Thank you Rober & Alex for the answers :-)
But I must admit that I'm still bit uncertain about that whole issue. As I 
understood apache it is creating a thread for every request anyway, or not? 
(and yes, on windows the MPM winnt is used)
so wouldn't it be enough to just call CoInitialized() at the start of my 
(mod_python) python-handler and CoUnitialize() and the end of my handler? the 
try... finally you have added only for the case my script would "crash", right? 
so that the CoUnitialize() is called in that case as well?
The idea about the single thread and queue I don't really get to be honest... 
what sort of object would be passed in the queue? And how would I create that 
queue and the thread? I guess you thinking of some standard python modules (as 
there's probably a python module for everything =))?

Greetings
Dominique

________________________________________
Von: Robert Brewer [EMAIL PROTECTED]
Gesendet: Donnerstag, 24. April 2008 17:57
An: Holzwarth, Dominique (Berne Bauhaus); python-win32@python.org
Betreff: RE: [python-win32] Apache & mod_python & win32com

[EMAIL PROTECTED] wrote:
> I'm developing a web application using mod_python and the apache web
> server. That application has to handle xml files and for that I'm
using
> win32com with with MSXML.
>
> My problem is, that apache spawns a new process / thread (not sure
> wether ist a process or thread. I think it's a thread)

On Windows, almost certainly a thread. Apache on Windows uses the
"winnt" MPM, which is multithreaded, not multiprocess.

> per http
> request. So when multiple users generated requests "at the same time"
> (new request before the first one is returned) I have multiple threads
> running. And that's where my win32com code is crashing...
>
> Currently, for every request my code does the following (as an
> example):
>
> return win32com.client.Dispatch("Msxml2.DOMDocument.6.0")
>
> To get an empty MSXSML DOM object.
>
> For multiple requests at the same time I get the following error:
>
>  File "C:\Program Files\Apache Software
>
Foundation\Apache2.2\TCRExceptionManagerData\database_library\database.
> py", line 24, in __init__
>     self.__configFileSchema = self.__XSDSchemaCache()
>
>   File "C:\Program Files\Apache Software
>
Foundation\Apache2.2\TCRExceptionManagerData\database_library\database.
> py", line 1774, in __XSDSchemaCache
>     return win32com.client.Dispatch("MSXML2.XMLSchemaCache.6.0")
>
>   File "C:\Program Files\Python25\lib\site-
> packages\win32com\client\__init__.py", line 95, in Dispatch
>     dispatch, userName =
> dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
>
>   File "C:\Program Files\Python25\lib\site-
> packages\win32com\client\dynamic.py", line 98, in
> _GetGoodDispatchAndUserName
>     return (_GetGoodDispatch(IDispatch, clsctx), userName)
>
>   File "C:\Program Files\Python25\lib\site-
> packages\win32com\client\dynamic.py", line 78, in _GetGoodDispatch
>     IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx,
> pythoncom.IID_IDispatch)
>
> com_error: (-2147221008, 'CoInitialize has not been called.', None,
> None)
>
> I've read already a bit in this mailing list and someone mentioned
that
> one need to call pythoncom.CoInitialize() and
> pythoncom.CoUninitialize(). But I don't know where exactly i should
> call those functions and wether that'll solve my problem... Also, when
> I do a 'import win32com.pythoncom' I get an error that the module
> 'pythoncom' does not exist!
>
> I would be really happy if someone could help me and tell me how to
> make my win32com work for multiple threads!

As Alex mentioned, you need to call CoInitialize for each thread.
Unfortunately, since Apache is creating the threads for you, you don't
have a hook for events to run on thread startup. Instead, you have to
watch threads as they go by and call CoInitialize ASAP. Best to do so
with a try/finally in case something goes wrong:

def handler(req):
    CoInitialize()
    try:
        process(req)
        return apache.OK
    finally:
        CoUninitialize()

If for various reasons that can't be made to work (some components just
aren't thread safe), another option would be to run all the COM calls in
a single thread and use a Queue; request threads would call q.put(xml,
reqid) and block, the COM thread would call q.get(), do the work, and
shove the result into results[reqid].


Robert Brewer
[EMAIL PROTECTED]

_______________________________________________
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to