Normally, wxPython event processing does **not** interupt other threads.
However, in my secondary thread, I'm issuing events using the
wxPostEvent() function. It appears that the wxPostEvent() function
cannot return while wxPython is in the middle of executing an Event
Handler function. wxPostEvent() returns once the mainloop continues
processing
Anyone got any ideas for getting round this? Maybe it's a wxWindows
issue.
Could be... wxPostEvent calls AddPendingEvent on the evtHandler object you
give it, and it does this (in pseudo code):
enter critical section(self.eventsLocker)
append event to pending event list
leave critical section
enter critical section(global eventsLocker)
append self to objects with pending events list
leave critical section
Later on in idle time ProcessPendingEvents will be called, and it does this:
enter critical section(self.eventsLocker)
while items in pending event list
node = first pending event list item
delete node
leave critical section
call ProcessEvent
enter critical section(self.eventsLocker)
leave critical section
So while there are certainly locks happening that will block the threads it
looks like it is released while the event handler code is actually being
called.
The other possibility is Python's Global Interpreter Lock which allows only
one thread to be in the interpreter at a time. This lock is released every
time there is a Python --> wxWindows method call and it is aquired for
wxWindows --> Python calls such as event handlers and virtual callbacks.
While Python code is running it is supposed to periodically release and
reaquire the GIL to allow other python threads to run. I've gone over how
wxPython deals with the GIL several times and feel real confident that it is
done right, but I suppose the possibility of a problem is there.
If you want to want to dive into this further let me know and I can let you
know where in the C++ code to look.
I can try to remove all wxPostEvent calls, but this means I've
got to implement my own method of communication between threads.
You could use the Queue in the standard Python lib. It is thread safe so
you can add objects to it from multiple threads and then read items from it
in an idle handler in the GUI thread. Just call wxWakeUpIdle() each time
you add an item to ensure that the idle processor will run soon.
···
--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!