Multithreaded COM server problem...

John Lull jl at windsmith.net
Tue Jan 13 09:28:09 EST 2004


Mark Hammond <mhammond at skippinet.com.au> wrote (with possible
deletions):

> 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:
>      time.sleep(0.1)
>      pythoncom.PumpWaitingMessages()
> 
> It works as you expect.  A better choice would probably be 
> win32event.MsgWaitForMultipleObjects, but that depends on what your app 
> really does.
> 
> Mark.

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
instead of:
  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:
  Runtime Error!
  Program: c:\Apps\Python2.2\pythonw.exe
  abnormal program termination

When I click OK, my client application reports (reformatted for
posting):
  Traceback (most recent call last):
    File "D:\Cust\Kinetics\comThreads\test20.py", line 7, in ?
      app=Dispatch('PyComThreads.Application')
    File "C:\Apps\Python2.2\lib\site-packages\win32com
          \client\__init__.py", line 95, in Dispatch
      dispatch, userName = dynamic._GetGoodDispatchAndUserName(
                                      dispatch,userName,clsctx)
    File "C:\Apps\Python2.2\lib\site-packages\win32com
          \client\dynamic.py", line 84, in _GetGoodDispatchAndUserName
      return (_GetGoodDispatch(IDispatch, clsctx), userName)
    File "C:\Apps\Python2.2\lib\site-packages\win32com
          \client\dynamic.py", line 72, in _GetGoodDispatch
      IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx,
                                             pythoncom.IID_IDispatch)
  pywintypes.com_error: (-2146959355, 'Server execution failed',
                         None, None)

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.

Regards,
John






More information about the Python-list mailing list