[python-win32] Python service hangs in Dispatch when frozen with py2exe
Mark Hammond
mhammond at skippinet.com.au
Tue Jun 1 20:06:28 CEST 2010
On 2/06/2010 3:42 AM, Don Dwiggins wrote:
> The object is part of a DLL written in VB6. It's currently single
> threaded -- apartment threading is the only other option in the IDE.
Right - Apartment threading might give better results.
>>
>> What is your main thread doing? Can you make it run a message loop to
>> test (ie, call pythoncom.PumpMessages() in that main thread?)
>
> Hmm, I'll have to look at that. I'm running under a Twisted reactor, and
> I'm not sure without looking how the reactor sets up the thread. I'm not
> sure how (or why) PumpMessages would work here -- there's nothing going
> on in the object that would require a Windows message loop.
The Windows message loop is used by the COM marshalling process. IIRC,
the first thread to initialize COM in a process is the thread in which
single-threaded objects will always end up being called in. If a
different thread creates the object, COM uses Windows messages to
marshall all calls back to that main thread. IOW, your second thread
makes a call - even to create the object - which results in that thread
sending a windows message to the main thread to act on the request.
What this probably means in practice is that twisted needs to use a
reactor which calls MsgWaitForMultipleObjects() and runs a message loop
when the function detects a new message is in the queue. I'm not sure
if there is an existing reactor which does this.
IIRC, apartment threading may fix this - the second thread can call
CoInit indicating it is a new apartment, which should mean that no
marshalling will happen between that thread and the new
apartment-threaded object. As mentioned above though, if the object
reports it is "single threaded", calls will *always* be marshalled to
the main thread and will always require a message loop to work correctly.
HTH,
Mark
More information about the python-win32
mailing list