Multithreaded COM server problem...
jl at windsmith.net
Tue Jan 13 15:28:09 CET 2004
Mark Hammond <mhammond at skippinet.com.au> wrote (with possible
> John Lull wrote:
> > Unfortunately, this one has to be a local server since it's providing shared
> > access to a pool of hardware devices from multiple distributed clients. I've
> > carefully reviewed chapters 5 & 12, and appendix D, and wasn't able to find
> > anything addressing threading models in the local server in detail. If I've
> > missed something, I'd be grateful for any additional hints.
> The problem is that your client code is not running a message loop. If
> you change the loop of your client test code to something like:
> for i in range(delay)*10:
> It works as you expect. A better choice would probably be
> win32event.MsgWaitForMultipleObjects, but that depends on what your app
> really does.
I presume you meant my server code. This still leaves all calls to the
server running in a single thread, however. If I insert a call to
PumpWaitingMessages() in a short operation, and it happens to start a
long operation, the result of that short operation will be delayed
until the long operation completes. This will make my server unusable.
I think I really need a server with at least requests from different
clients running in separate threads.
I tried changing win32com.server.localserver to do:
sys.coinit_flags = 0
sys.coinit_flags = 2
At first glance this seems to do what I want -- requests to the server
seem to run from a thread pool. However, I also get intermittent (but
frequest) startup errors, with a Microsoft Visual C++ Runtime Library
error dialog (during pythoncom.PumpMessages but before my server
module gets imported) reporting:
abnormal program termination
When I click OK, my client application reports (reformatted for
Traceback (most recent call last):
File "D:\Cust\Kinetics\comThreads\test20.py", line 7, in ?
\client\__init__.py", line 95, in Dispatch
dispatch, userName = dynamic._GetGoodDispatchAndUserName(
\client\dynamic.py", line 84, in _GetGoodDispatchAndUserName
return (_GetGoodDispatch(IDispatch, clsctx), userName)
\client\dynamic.py", line 72, in _GetGoodDispatch
IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx,
pywintypes.com_error: (-2146959355, 'Server execution failed',
I do *not* seem to get this error if the server is already running
because of a request from another process.
If I'm not able to track down the cause of this error, is there some
way I can (during object creation) create a new thread to handle all
requests on the new object? I know how to create the thread, what I
don't know is how I would tell the COM mechanism to route all requests
on the new object to the message pump in the new thread.
Thanks for your assistance.
More information about the Python-list