41
41
42
42
// Access to std::cout and std::endl
43
43
#include < iostream>
44
- #include < mutex>
45
44
// DECLDIR will perform an export for us
46
45
#define DLL_EXPORT
47
46
@@ -108,9 +107,9 @@ struct InitializeThreadingInfo {
108
107
PyImport_ImportModule* pyImportMod;
109
108
PyEval_Lock* initThreads;
110
109
111
- std::mutex mutex ;
112
- HANDLE initedEvent; // Note: only access with mutex locked (and check if not already nullptr).
113
- bool completed; // Note: only access with mutex locked
110
+ CRITICAL_SECTION cs ;
111
+ HANDLE initedEvent; // Note: only access with cs locked (and check if not already nullptr).
112
+ bool completed; // Note: only access with cs locked
114
113
};
115
114
116
115
@@ -122,12 +121,12 @@ int AttachCallback(void *voidInitializeThreadingInfo) {
122
121
initializeThreadingInfo->initThreads (); // Note: calling multiple times is ok.
123
122
initializeThreadingInfo->pyImportMod (" threading" );
124
123
125
- initializeThreadingInfo->mutex .lock ();
124
+ EnterCriticalSection (&initializeThreadingInfo->cs );
125
+ initializeThreadingInfo->completed = true ;
126
126
if (initializeThreadingInfo->initedEvent != nullptr ) {
127
127
SetEvent (initializeThreadingInfo->initedEvent );
128
128
}
129
- initializeThreadingInfo->completed = true ;
130
- initializeThreadingInfo->mutex .unlock ();
129
+ LeaveCriticalSection (&initializeThreadingInfo->cs );
131
130
return 0 ;
132
131
}
133
132
@@ -311,13 +310,19 @@ extern "C"
311
310
// Either _PyThreadState_Current or _PyThreadState_UncheckedGet are required
312
311
DEFINE_PROC_NO_CHECK (curPythonThread, PyThreadState**, " _PyThreadState_Current" , -220 ); // optional
313
312
DEFINE_PROC_NO_CHECK (getPythonThread, _PyThreadState_UncheckedGet*, " _PyThreadState_UncheckedGet" , -230 ); // optional
313
+ DEFINE_PROC_NO_CHECK (getPythonThread13, _PyThreadState_GetCurrent*, " _PyThreadState_GetCurrent" , -231 ); // optional
314
+ if (getPythonThread == nullptr && getPythonThread13 != nullptr ) {
315
+ std::cout << " Using Python 3.13 or later, using _PyThreadState_GetCurrent" << std::endl << std::flush;
316
+ getPythonThread = getPythonThread13;
317
+ }
314
318
315
319
if (curPythonThread == nullptr && getPythonThread == nullptr ) {
316
320
// we're missing some APIs, we cannot attach.
317
321
std::cerr << " Error, missing Python threading API!!" << std::endl << std::flush;
318
322
return -240 ;
319
323
}
320
324
325
+
321
326
// Either _Py_CheckInterval or _PyEval_[GS]etSwitchInterval are useful, but not required
322
327
DEFINE_PROC_NO_CHECK (intervalCheck, int *, " _Py_CheckInterval" , -250 ); // optional
323
328
DEFINE_PROC_NO_CHECK (getSwitchInterval, _PyEval_GetSwitchInterval*, " _PyEval_GetSwitchInterval" , -260 ); // optional
@@ -368,22 +373,25 @@ extern "C"
368
373
initializeThreadingInfo->pyImportMod = pyImportMod;
369
374
initializeThreadingInfo->initThreads = initThreads;
370
375
initializeThreadingInfo->initedEvent = CreateEvent (nullptr , TRUE , FALSE , nullptr );
376
+ InitializeCriticalSection (&initializeThreadingInfo->cs );
377
+
371
378
372
379
// Add the call to initialize threading.
373
380
addPendingCall (&AttachCallback, initializeThreadingInfo);
374
381
375
382
::WaitForSingleObject (initializeThreadingInfo->initedEvent, 5000 );
376
383
377
384
// Whether this completed or not, release the event handle as we won't use it anymore.
378
- initializeThreadingInfo->mutex . lock ( );
385
+ EnterCriticalSection (& initializeThreadingInfo->cs );
379
386
CloseHandle (initializeThreadingInfo->initedEvent );
380
387
bool completed = initializeThreadingInfo->completed ;
381
388
initializeThreadingInfo->initedEvent = nullptr ;
382
- initializeThreadingInfo->mutex . unlock ( );
389
+ LeaveCriticalSection (& initializeThreadingInfo->cs );
383
390
384
391
if (completed) {
385
392
// Note that this structure will leak if addPendingCall did not complete in the timeout
386
393
// (we can't release now because it's possible that it'll still be called).
394
+ DeleteCriticalSection (&initializeThreadingInfo->cs );
387
395
delete initializeThreadingInfo;
388
396
if (showDebugInfo) {
389
397
std::cout << " addPendingCall to initialize threads/import threading completed. " << std::endl << std::flush;
0 commit comments