-
Type: Improvement
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: None
Currently, CreateThread is used as the primitive to create threads on Windows, defined here:
https://github.com/mongodb/mongo-c-driver/blob/r1.17/src/common/common-thread-private.h#L58
My understanding is that _beginthreadex is a wrapper around CreateThread to ensure it is safe to use the C runtime. The documentation for CreateThread states:
A thread in an executable that calls the C run-time library (CRT) should use the _beginthreadex and _endthreadex functions for thread management rather than CreateThread and ExitThread; this requires the use of the multithreaded version of the CRT. If a thread created using CreateThread calls the CRT, the CRT may terminate the process in low-memory conditions.
This is additionally stated in https://docs.microsoft.com/en-us/windows/win32/procthread/creating-threads
The MyThreadFunction function avoids the use of the C run-time library (CRT), as many of its functions are not thread-safe, particularly if you are not using the multithreaded CRT. If you would like to use the CRT in a ThreadProc function, use the _beginthreadex function instead.
Though docs for the CRT library state: "All versions of the CRT support multi-threaded development", so I believe on Windows 10, where we are linking against the Universal CRT shipped with Windows, this may not be an observable issue.
Other evidence:
- libuv and cpython both use _beginthreadex to create threads on Windows
- this stack overflow discussion: https://stackoverflow.com/questions/331536/windows-threading-beginthread-vs-beginthreadex-vs-createthread-c
As an aside, we're using the wrong function signature for CreateThread anyway. Our thread functions have the pthread signature:
static void *
_mongoc_topology_run_background (void *data)
CreateThread expects the thread function to match the signature:
DWORD WINAPI ThreadProc( _In_ LPVOID lpParameter );
Do not declare this callback function with a void return type and cast the function pointer to LPTHREAD_START_ROUTINE when creating the thread. Code that does this is common, but it can crash on 64-bit Windows.
So that slightly worries me. If we need to fix this anyway, we'd might as well use the recommended thread creation function.