[CDRIVER-3635] Thread creation on Windows should use _beginthreadex Created: 25/Apr/20  Updated: 28/Oct/23  Resolved: 07/May/20

Status: Closed
Project: C Driver
Component/s: None
Affects Version/s: None
Fix Version/s: 1.17.0-beta2, 1.17.0

Type: Improvement Priority: Major - P3
Reporter: Kevin Albertson Assignee: Kevin Albertson
Resolution: Fixed Votes: 0
Labels: platform-problems
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

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:

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
);

The docs for ThreadProc say:

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.



 Comments   
Comment by Githook User [ 25/May/20 ]

Author:

{'name': 'Kevin Albertson', 'email': 'kevin.albertson@mongodb.com', 'username': 'kevinAlbs'}

Message: CDRIVER-3635 fix more thread func decls
Branch: r1.17
https://github.com/mongodb/mongo-c-driver/commit/0f5b1632e8f771900415cd76f63a397c16d927b5

Comment by Githook User [ 25/May/20 ]

Author:

{'name': 'Kevin Albertson', 'email': 'kevin.albertson@10gen.com', 'username': 'kevinAlbs'}

Message: CDRIVER-3635 use _beginthreadex, not CreateThread

Use correct calling convention in thread functions.
CDRIVER-3634 close thread handles after joining.
Branch: r1.17
https://github.com/mongodb/mongo-c-driver/commit/d47399cb8a885c538f5446b71ace9655e215454f

Comment by Githook User [ 07/May/20 ]

Author:

{'name': 'Kevin Albertson', 'email': 'kevin.albertson@mongodb.com', 'username': 'kevinAlbs'}

Message: CDRIVER-3635 fix more thread func decls
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/775e50961893da4185f7bd69d9159599c5f5f091

Comment by Githook User [ 07/May/20 ]

Author:

{'name': 'Kevin Albertson', 'email': 'kevin.albertson@10gen.com', 'username': 'kevinAlbs'}

Message: CDRIVER-3635 use _beginthreadex, not CreateThread

Use correct calling convention in thread functions.
CDRIVER-3634 close thread handles after joining.
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/bedfc0157f2d0a88c463086915426546b0f633b3

Generated at Wed Feb 07 21:18:37 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.