[Zope-dev] Zope and Com : CoInitialize done on each thread by Zserver?

Toby Dickenson htrd90@zepler.org
Tue, 31 Aug 1999 13:48:52 GMT


On Mon, 30 Aug 1999 14:26:52 -0400, Brian wrote:

>The win32 binary Zope dist. includes a subset of the win32
>extensions, but _not_ win32com - that would open up many
>new cans of worms having to due with COM versions etc. that
>we don't want to get into (and that Mark is already doing a
>good job dealing with in his distribution). So, z2 does not
>try to call CoInitialize currently (and won't anytime soon).

I posted a patch to initialize COM to zopedev on 1999/7/27, also
included below. I think it's in the Collector too.

This patch tries to import the pythoncom module, and only tries to
call CoInitializeEx if it is available.

>Your need to do these things early in the startup code is 
>similar to some things others have needed, and we've been
>thinking about adding a more general-purpose hook, where
>Zope will probably be willing try to import a site-specific 
>module very early in the startup process. Then site maintainers
>will be able to do whatever they need to do (add things to
>the path, init COM, etc.) without hacking the Zope sources.
>
>Your COM problem exposes a new twist, though. If CoInitialize
>needs to be called for each thread, then the general-purpose
>early import hook wouldn't quite be enough for you. The site-
>specific module hook won't make it into 2.0 final anyway, so
>we'll try to think about this for a future version. It sounds
>like what we may need is a sort of way to register functions
>that should be called on thread creation (and probably also
>destruction).

You are correct that it needs to hook into both the startup of the
main thread, and the start of every publisher thread.

Also, it needs to be called before the pythoncom module is first
imported (it needs to set a variable in the sys module that is used by
the pythoncom module startup code). Doing it in a product, for
example, is too late.


I last used this with alpha 4, but it should work with the current
beta too. You need to add:

* "import zcom; zcom.init()" in the midde of z2 py

* "import zcom; zcom.start_of_another_zope_thread()"
   as the first line of __init__ in ZServerPublisher.py

* The module zcom.py as below.

I hope this helps,




""" COM support for Zope.

This module initializes COM. Nothing more.

Author: Toby Dickenson

"""

# We have to use MTA threads since it is possible that a variable
# referring to a COM object might be used by multiple threads. After
# this, COM will take care of all concurrency issues automatically.

import sys

COINIT_MULTITHREADED = 0

def init():
"""Call this in the main application thread. It determines whether
COM support is available, and imports the pythoncom module for the
first time. The first import of pythoncom triggers some 'convenient'
magic, so we get that over with too."""

# Set the value in sys module that is used by pythoncom
# when first imported
sys.coinit_flags=COINIT_MULTITHREADED
try:
import pythoncom
except ImportError:
pass
else:
assert COINIT_MULTITHREADED==pythoncom.COINIT_MULTITHREADED
# This thread is now registered with COM as an MTA


def start_of_another_zope_thread():
"""Call this at the start of every thread that enters Zope."""
pythoncom=sys.modules.get('pythoncom',None)
if pythoncom:
pythoncom.CoInitializeEx(COINIT_MULTITHREADED)
# This thread is now part of the MTA


Toby Dickenson