Okay, wxWidgets 2.5.3 was tagged and bagged over the weekend. So if
there are any updates to contribs and such that you guys need to send to
me this week is the time to do it.
I have a request concerning multi-threads, and Global Interpreter Lock
handling.
Here is my case:
Our C application uses wxPython for its display.
For some long running functions, it starts a worker thread.
This thread will send messages to the main loop, to update
progress information. (nothing very new so far).
To call the PostMessage function, the thread needs to
own the GIL. We use the PyGILState_Ensure and
PyGILState_Release functions:
PyGILState_STATE state = PyGILState_Ensure();
.... call wxPython functions ...
PyGILState_Release(state);
These functions were added with python 2.3.
They have this advantage that you may call them from anywhere,
no matter if you already own the lock or not,
if it's a new thread or not.
Now, the problem:
in my application, the first call works well, but the second
call fails with something like "no current state"
Then, the analysis:
In helpers.cpp, in function wxPySaveThreadState, the thread state
is stored only once for a given thread.
The comments there say it all:
// info.tstate = tstate; //*** DO NOT update existing ones???
// Normally it will never change, but apparently COM callbacks
// (i.e. ActiveX controls) will (incorrectly IMHO) use a transient
// tstate which will then be garbage the next time we try to use
// it...
The PyGILState_* functions do just that, "use a transient tstate which is
garbage the next time".
wxPython should always store the present tstate. In "normal" cases,
it won't change, but threads created by applications are likely to
use different states.
And the solution:
I just uncommented the statement above, "info.tstate = tstate",
and it works.
I don't know if there are other hidden effects, but I think this change
should be made in wxPython.
···
--
Amaury Forgeot d'Arc