(Non-Win32 users:  The real issue here is not Win32-specific.)

I'm trying to write an mp1/Apache::Registry script on Win32 that uses 
the Win32::Shortcut module, and I find that it works fine under CGI but 
not mod_perl.

I think the problem is this:

Win32::Shortcut in an XS module.  The XS file has a BOOT: section which 
calls a Win32 API function called CoInitialize().  This is called by 
"bootstrap Win32::Shortcut;" when the module is require()'d/use()'d.  
The PM file has an END block which calls an XS routine which calls 
another Win32 API function called CoUninitialize().

Nothing else in this module works unless it is called *between* those 
calls to CoInit and CoUninit.

Under CGI, when my script starts running it runs "use Win32::Shortcut;" 
which calls CoInit, then it does whatever it has to do, then exits, 
causing the END block to be run, which calls CoUninit.  The next time 
the script is run we just do it all again:

----------
CoInit
# do stuff for request 1
CoUninit
----------
CoInit
# do stuff for request 2
CoUninit
----------
...

However, under Apache::Registry the CoInit call only gets done once 
because the module is only loaded once and thereafter gets cached, but 
the END block is still run at the end of every script run, so now we have:

----------
CoInit
# do stuff for request 1
CoUninit
----------
# do stuff for request 2
CoUninit
----------
...

You can see why request 2 doesn't work: CoUninit was called at the end 
of request 1 and CoInit hasn't been called since.

I tried placing a "use Win32::Shortcut;" line in my mp1 startup.pl 
script (and I also tried "PerlModule Win32::Shortcut" in the httpd.conf 
file instead, which I believe amounts to the same thing) to see if this 
would help, but it doesn't:

As explained in the mod_perl manpage, the END block will now only get 
run once (at server shutdown) because it was encountered during server 
startup.  I thought that this would solve the problem since now we have 
one call to CoInit at startup and one call to CoUninit at shutdown and 
neither gets called any other time, but I now find that *no* requests to 
the script work, not even the first request!

I think the reason is that the parent Apache.exe loaded the module, 
doing the CoInit call (and will later run the END block, doing the 
CoUninit too), but the child Apache.exe actually serves the request, and 
the CoInit/CoUninit calls have to be made from the same process that 
wants to be doing stuff in-between, so now the child doesn't work at all 
since it never called CoInit to start with.

The only way that I've got this working so far is to simulate what 
Apache::StatINC would do if the module was changed between every 
request:  I've deleted the loading of the module from server startup, 
and now have this in my script:

    use Win32::Shortcut;
    delete $INC{'Win32/Shortcut.pm'};
    require 'Win32/Shortcut.pm';
    ...

The use() line there gets an END block installed to be run at the end of 
every script run, while the delete()/require() calls force the bootstrap 
code to be re-run at the start of every script run.

This seems to work (so far!), but is there a more elegant way of doing this?

- Steve



------------------------------------------------
Radan Computational Ltd.

The information contained in this message and any files transmitted with it are 
confidential and intended for the addressee(s) only.  If you have received this 
message in error or there are any problems, please notify the sender immediately.  The 
unauthorized use, disclosure, copying or alteration of this message is strictly 
forbidden.  Note that any views or opinions presented in this email are solely those 
of the author and do not necessarily represent those of Radan Computational Ltd.  The 
recipient(s) of this message should check it and any attached files for viruses: Radan 
Computational will accept no liability for any damage caused by any virus transmitted 
by this email.


-- 
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html

Reply via email to