You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GILLock / GILRelease check if they have the GIL with API
In the case of 3 threads fighting over the GIL, it was possible for a deadlock
to occur, the thread 2 stole the GIL from thread 1, and thread 3 stole from
thread 2.
The API call to check if you have the GIL was added as a helper function
in Python 3.4.0 (issue #17522). The function is taken from there. A backport
would be trivial, but that would mean we could only use the packaged
python27.dll, and not the official one.
This whole schenanigans seems necessary, as you don't appear to be able to call PyGILState_Ensure() from a thread that already has the GIL.
11
-
It just locks up, and digging into the code, it's waiting on a lock that the thread already has.
10
+
This whole schenanigans is necessary, as you can't call PyGILState_Ensure() from a thread that already has the GIL.
12
11
13
-
For callbacks, it's impossible to know if the callback was generated from "within" python or not.
14
-
For instance: you have a callback on scintilla SCN_MODIFIED. If from a script you do editor.write('...'), you've got the GIL still when the callback comes.
15
-
When the user makes a change, it calls the callback, but this time you *don't* have the GIL, so you need to get it.
12
+
For the ScintillaWrapper (specifically, but not exclusively), it's tricky to impossible to tell if we need to release the GIL. If we're running on the
13
+
Python worker thread, and we make a call to Scintilla, that triggers a callback, we need to give it up (in order that the callback can run). The callback
14
+
identification must be performed with the GIL, so it would block if we didn't give it up. (There's an optimisation that if no callbacks are registered, then it
15
+
doesn't check, and doesn't acquire the GIL)
16
+
17
+
However, if we're being called from the replace function, and therefore the main thread, we probably don't even have the GIL to give up.
16
18
17
19
With the different threads running the different callbacks, and python code running on a thread (*generally* - see the editor.replace() suite)
18
20
it has become impossible to manage manually (read: the Wrong Way To Do It(tm)). These objects manage the GIL, and provide a easy, safe way to ensure
19
21
you have the GIL when you need it, and give it up correctly whatever happens in the mean time.
20
-
*/
21
22
22
-
classGILManager;
23
+
The doIHaveTheGIL() function is taken from Python 3.4.0, Issue #17522. An extra workaround is included to make it work when Py_DEBUG is defined.
24
+
- see note below where PyThreadState_GET is redefined.
25
+
*/
23
26
24
27
25
-
/* GILLock is the generic class given back when asking for the lock
26
-
* If the current thread already has the lock, then you'll get an instance of
27
-
* this class, that does nothing.
28
-
* If however, you didn't already have the lock, you'll an instance of OwnedGILLock, which
29
-
* gives the lock back upon destruction.
28
+
#ifdef Py_DEBUG
29
+
/* For Py_DEBUG, PyThreadState_GET() is redefined to PyThreadState_Get(), which checks that the current ThreadState is not null
30
+
* We "undo" that define here, as we need to get the current threadstate without checking if it's not set
0 commit comments