[python-win32] Strange problem with CoUninitialize using threads and COM objects

Don Dwiggins dond@advancedmp.com
14 Oct 2002 15:12:12 -0700


I have a COM component that contains a bunch of "agents", and a driver
application that takes a list of agent names, fires off threads to call the
requested agents, and collects the results as they finish.

The problem I'm having is that about 90% of the time, when the first thread
to finish calls CoUninitialize(), the application just dies quietly, I've
wrapped everything in try...except blocks, and put print statements before
almost every statement (with calls to flush the output) -- nothing gets
printed after the offending call.  If, however, I comment out the call to
CoUninitialize(), everything works fine; I can run several agents, and
they'll all complete properly, and the application will exit as it should.

To go a little deeper, the thread logic is something like this (resultq is a
Queue object passed in):
class MyAgent(Thread):
    "The agent thread class"
    def __init__(self, name, info, resultq):
        Thread.__init__(self)
        self.name = name
        self.objname = name
        self.info = info
        self.resultq = resultq

    def run(self):
        "Get an agent object and run it"
        CoInitialize()   # Let COM know we're here
        obj = GetAgent(self.objname)
        results = obj.GetResults(self.info['param'])
        self.resultq.put((self.info['URLDesc'], results))
        CoUninitialize()   # Tell COM we're done

... and the main thread does essentially:
    activeAgents = 0
    resultQ = Queue()
    for name in namelist:
        info = {....}
        SearchAgent(name, info, resultQ).start()
        activeAgents += 1
    while activeAgents > 0:
        agentname, results = resultQ.get()
        db.recordResults(agentname, results)
        activeAgents -= 1
    sys.exit()

(I've omitted the print statements and the try blocks, along with some other
local processing code.)

Any suggestions as to what I should try here, or why CoUninitialize should
cause python to drop out the back door?  I suppose I could just leave
out the troublesome CoUninitialize, but I'm wondering what might bite me if
I do.

One more data point: when I run the app with "python -i", it still exits
without taking me to the post-mortem prompt.

Regards,
-- 

Don Dwiggins                     "The truth will make you free,
d.l.dwiggins@computer.org         but first it will make you miserable"
                                  -- Tom DeMarco