|
31 | 31 | #include "capi.h" |
32 | 32 | #include <trufflenfi.h> |
33 | 33 |
|
34 | | -extern TruffleContext* TRUFFLE_CONTEXT; |
35 | 34 | static THREAD_LOCAL int graalpy_attached_thread = 0; |
36 | 35 | static THREAD_LOCAL int graalpy_gilstate_counter = 0; |
37 | 36 |
|
@@ -2290,22 +2289,22 @@ PyGILState_Check(void) |
2290 | 2289 |
|
2291 | 2290 | return (tstate == gilstate_tss_get(runtime)); |
2292 | 2291 | #else // GraalPy change |
2293 | | - int attached = 0; |
2294 | 2292 | /* |
2295 | 2293 | * PyGILState_Check is allowed to be called from a new thread that didn't yet setup the GIL. |
2296 | | - * If we don't attach the thread ourselves, the upcall will work because NFI will attach |
2297 | | - * the thread automatically, but it won't create the context which would then break |
2298 | | - * subsequent PyGILState_Ensure. |
| 2294 | + * We must attach it before calling into Java so the upcall has an entered polyglot context. |
2299 | 2295 | */ |
2300 | | - if (TRUFFLE_CONTEXT) { |
2301 | | - if ((*TRUFFLE_CONTEXT)->getTruffleEnv(TRUFFLE_CONTEXT) == NULL) { |
2302 | | - (*TRUFFLE_CONTEXT)->attachCurrentThread(TRUFFLE_CONTEXT); |
2303 | | - attached = 1; |
| 2296 | + int attached = 0; |
| 2297 | + if (graalpy_attach_native_thread) { |
| 2298 | + attached = graalpy_attach_native_thread(); |
| 2299 | + if (attached == GRAALPY_ATTACH_NATIVE_FAILED) { |
| 2300 | + return 0; |
2304 | 2301 | } |
| 2302 | + } else { |
| 2303 | + return 0; |
2305 | 2304 | } |
2306 | 2305 | int ret = GraalPyPrivate_GILState_Check(); |
2307 | | - if (attached) { |
2308 | | - (*TRUFFLE_CONTEXT)->detachCurrentThread(TRUFFLE_CONTEXT); |
| 2306 | + if (attached == GRAALPY_ATTACH_NATIVE_OWNED && graalpy_detach_native_thread) { |
| 2307 | + graalpy_detach_native_thread(); |
2309 | 2308 | } |
2310 | 2309 | return ret; |
2311 | 2310 | #endif // GraalPy change |
@@ -2362,13 +2361,18 @@ PyGILState_Ensure(void) |
2362 | 2361 |
|
2363 | 2362 | return has_gil ? PyGILState_LOCKED : PyGILState_UNLOCKED; |
2364 | 2363 | #else // GraalPy change |
2365 | | - if (TRUFFLE_CONTEXT) { |
2366 | | - if ((*TRUFFLE_CONTEXT)->getTruffleEnv(TRUFFLE_CONTEXT) == NULL) { |
2367 | | - (*TRUFFLE_CONTEXT)->attachCurrentThread(TRUFFLE_CONTEXT); |
| 2364 | + if (!graalpy_attach_native_thread) { |
| 2365 | + Py_FatalError("PyGILState_Ensure called before GraalPy C API initialization"); |
| 2366 | + } |
| 2367 | + if (!graalpy_attached_thread) { |
| 2368 | + int attached = graalpy_attach_native_thread(); |
| 2369 | + if (attached == GRAALPY_ATTACH_NATIVE_FAILED) { |
| 2370 | + Py_FatalError("Could not attach native thread to the polyglot context"); |
| 2371 | + } else if (attached == GRAALPY_ATTACH_NATIVE_OWNED) { |
2368 | 2372 | graalpy_attached_thread = 1; |
2369 | 2373 | } |
2370 | | - graalpy_gilstate_counter++; |
2371 | 2374 | } |
| 2375 | + graalpy_gilstate_counter++; |
2372 | 2376 | return GraalPyPrivate_GILState_Ensure() ? PyGILState_UNLOCKED : PyGILState_LOCKED; |
2373 | 2377 | #endif // GraalPy change |
2374 | 2378 | } |
@@ -2428,20 +2432,20 @@ PyGILState_Release(PyGILState_STATE oldstate) |
2428 | 2432 | if (oldstate == PyGILState_UNLOCKED) { |
2429 | 2433 | GraalPyPrivate_GILState_Release(); |
2430 | 2434 | } |
2431 | | - if (TRUFFLE_CONTEXT) { |
2432 | | - graalpy_gilstate_counter--; |
2433 | | - if (graalpy_gilstate_counter == 0 && graalpy_attached_thread) { |
2434 | | - GraalPyPrivate_BeforeThreadDetach(); |
2435 | | - (*TRUFFLE_CONTEXT)->detachCurrentThread(TRUFFLE_CONTEXT); |
2436 | | - graalpy_attached_thread = 0; |
2437 | | - /* |
2438 | | - * The thread state on the Java-side is cleared in GraalPyPrivate_BeforeThreadDetach. |
2439 | | - * As part of that the tstate_current pointer should have been set to NULL to make |
2440 | | - * sure to fetch a fresh pointer the next time we attach. Just to be sure, we clear |
2441 | | - * it here too: |
2442 | | - */ |
2443 | | - tstate_current = NULL; |
| 2435 | + graalpy_gilstate_counter--; |
| 2436 | + if (graalpy_gilstate_counter == 0 && graalpy_attached_thread) { |
| 2437 | + GraalPyPrivate_BeforeThreadDetach(); |
| 2438 | + if (graalpy_detach_native_thread) { |
| 2439 | + graalpy_detach_native_thread(); |
2444 | 2440 | } |
| 2441 | + graalpy_attached_thread = 0; |
| 2442 | + /* |
| 2443 | + * The thread state on the Java-side is cleared in GraalPyPrivate_BeforeThreadDetach. |
| 2444 | + * As part of that the tstate_current pointer should have been set to NULL to make |
| 2445 | + * sure to fetch a fresh pointer the next time we attach. Just to be sure, we clear |
| 2446 | + * it here too: |
| 2447 | + */ |
| 2448 | + tstate_current = NULL; |
2445 | 2449 | } |
2446 | 2450 | #endif // GraalPy change |
2447 | 2451 | } |
|
0 commit comments