Jeremy White wrote:
[ I've added a note to myself to look for all the places that we use
dTHX and to ensure that they are necessary - I think they are used
when we get a win32 api callback such that we can't use the NOTXSPROC
calling convention ]
I'm still not 100% sure how the context works within Win32-GUI but there
might be a problem when Win32-GUI is used in a threaded app, where you
want different threads to deal with different windows (see
AttachThreadInput method in the docs).
As I understand things, we're storing the context in
PERLWIN32GUI_USERDATA via the macro PERLUD_DECLARE and we're fetching
the context via the macro PERLUD_FETCH. As we're fetching the context
everytime we're doing an event, we are *always* using the perl
interpreter that created the window, rather than the context that is
associated with the current running thread.
I'm not to sure what the solution could be, as I understand things you
can't pass sub refs around perl threads, which means that NEM would be
broken (i.e., thread A creates the window and the sub refs for the
events, but you need thread B to respond to events for the window
created by A). From very bitter experience, Perl 5.6 and most 5.8.x
(5.8.7 seems ok) threading at the deep perl level is broken.
So long as you don't use AttachThreadInput, then I think we're OK, as
messages get posted to the thread that creates the window, and the
message loops only pull messages from that thread's message loop.
You're correct that as soon as you call AttachThreadInput the whole
thing is broken.
That said, Win32::GUI needs some significant work to be thread-safe (and
even more work to be thread-friendly).
I've got some ideas of the direction to take this, and think that as a
first step simply adding a CLONE_SKIP method to each class, that
prevents the objects getting cloned when a new thread is started is the
easiest direction. This would certainly cater for (what I can see is a
very common case of) wanting to start a thread to do some work, whilst
keeping all the GUI code in a separate thread. At least we'd be able
to use threads (even if in a somewhat limited way) without crashing
every time we do a thread->join().
I'll tuck your comments away for further though when I get around to
considering threads in more detail.
Regards,
Rob.