Re: BEGIN/END block problems with Win32::Shortcut under mp1
Steve Hay wrote: >Jan Dubois wrote: > > >>The other issue you are seeing is that CoInitialize() needs to be called >>in each *thread* that wants to make COM calls. To do this properly, the >>module needs to provide a CLONE method if you are using Perl threads in >>5.8.x. >> >> >> >That's not an issue for me with mp1 because it's single-threaded on >Win32. I'll have to bear it in mind when moving to mp2, though, 'cos >that's multi-threaded on Win32. > Actually, it *is* an issue for me :( mp1 only uses Perl in a single-threaded way on Win32, but the Apache.exe process itself has (by default) 50 threads which take turns to serve requests. So I find (with your fixed version of Win32::Shortcut) that several consecutive requests all work OK, but then sometime later a subsequent request gets served by a different thread and it breaks because the CoInit wasn't done there. Adding a CLONE method to Win32::Shortcut won't help this either because it's Apache threads causing the problem, not Perl threads. So it's back to my nasty %INC hacking now. Using mod_perl handlers is the only other suggestion so far, but it's not so easy in the software concerned for which I have to maintain CGI compatibility. - 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
Re: BEGIN/END block problems with Win32::Shortcut under mp1
IMHO, your startup.pl approach is best, although I'm not sure why it would be calling END. In any case, you only need to use() the module once at startup. Most likely, in the "scripts" which are calling the functions, you could just import() the module. Or maybe I misunderstood. Issac BTW: From a developer's standpoint, that doesn't sound like a healthy way for the module you're using to work. It sounds like it would be better designed as an OO module. To illustrate this, I recently wrote a Perl application which needed to JavaScript parsing. As such, I rewrote some parts of the JAvaScript::SpiderMonkey module (I didn't like the way most of it was written - I started helping to rewrite it, but it took to long and eventually I had to get back to work work so I just wrote the parts I needed in my own module, but I'm getting off track). Getting to the point, before I could work with any JavaScript, I also had initialization, and had to do de-initialization. To solve this, I made the object OO-oriented, and had it do XS init stuff in the new() call (before being bless()ed) and de-init stuff in DESTROY, rather than END. - Original Message - From: "Steve Hay" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Tuesday, September 21, 2004 7:24 PM Subject: BEGIN/END block problems with Win32::Shortcut under mp1 > (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
RE: BEGIN/END block problems with Win32::Shortcut under mp1
On Tue, 21 Sep 2004, Steve Hay wrote: > I'm a little wary of this fix because MSDN docs say "An apartment must > call CoUninitialize once for each successful call it has made to > CoInitialize" and "CoUninitialize should be called on application > shutdown", but it certainly seems to work and is less messy than what > I was doing. I believe the reason you should call CoUninitialize() explicitly is to get proper cleanup of "hanging" COM objects whose reference counts haven't been properly maintained. Once the thread or process shuts down, it is no longer possible to properly finalize those objects. If all your COM objects have been properly disposed, then you should be fine. Win32::Shortcut doesn't maintain reference counts itself, so I wouldn't worry about this too much. There is also a race condition when 2 modules try to call CoUninitialize(), e.g. Win32::Shortcut and Win32::OLE. If Win32::Shortcut has been loaded last, then its END block will be executed first, and the DESTROY methods of all still existing Win32::OLE methods will fail. Cheers, -Jan -- 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
RE: BEGIN/END block problems with Win32::Shortcut under mp1
On Tue, 21 Sep 2004, Jan Dubois wrote: > There is also a race condition when 2 modules try to call CoUninitialize(), > e.g. Win32::Shortcut and Win32::OLE. If Win32::Shortcut has been loaded last, > then its END block will be executed first, and the DESTROY methods of all > still existing Win32::OLE methods will fail. Oops, please ignore that paragraph; it is bogus. The CoInitialize / CoUninitialize() are maintaining a counter, so COM isn't actually uninitialized until *all* users have called CoUninitialize(). Cheers, -Jan -- 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
Re: BEGIN/END block problems with Win32::Shortcut under mp1
Jan Dubois wrote: >On Tue, 21 Sep 2004, Steve Hay wrote: > > >>(Non-Win32 users: The real issue here is not Win32-specific.) >> >> > >As to Win32::Shortcut: you should just delete the END block from the module. >I see that Sarathy already did this over a year for the version that ships >with ActivePerl. He also gave me his mailbox with accumulated libwin32 >patches and asked me to put out another libwin32 release to CPAN. >Unfortunately I haven't found time to get around to it yet. > Oh - I looked on CPAN for a newer libwin32 or Win32::Shortcut (and even tried dada.perl.it), but didn't think of looking in the latest ActivePerl! I'm a little wary of this fix because MSDN docs say "An apartment must call CoUninitialize once for each successful call it has made to CoInitialize" and "CoUninitialize should be called on application shutdown", but it certainly seems to work and is less messy than what I was doing. > >The other issue you are seeing is that CoInitialize() needs to be called >in each *thread* that wants to make COM calls. To do this properly, the >module needs to provide a CLONE method if you are using Perl threads in >5.8.x. > That's not an issue for me with mp1 because it's single-threaded on Win32. I'll have to bear it in mind when moving to mp2, though, 'cos that's multi-threaded on Win32. > >I have no clue how all this relates to MP1; it is just the subject line that >made me take a brief peek at this message. > Thanks for the tip. It's interesting to note that the purveyors of PerlEx watch this list :) ... - 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
Re: BEGIN/END block problems with Win32::Shortcut under mp1
On Tue, 2004-09-21 at 12:24, Steve Hay wrote: > 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? One thing you could do is change your script to a mod_perl handler. Then the END blocks will not get run until the server shuts down. - Perrin -- 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
RE: BEGIN/END block problems with Win32::Shortcut under mp1
On Tue, 21 Sep 2004, Steve Hay wrote: > (Non-Win32 users: The real issue here is not Win32-specific.) As to Win32::Shortcut: you should just delete the END block from the module. I see that Sarathy already did this over a year for the version that ships with ActivePerl. He also gave me his mailbox with accumulated libwin32 patches and asked me to put out another libwin32 release to CPAN. Unfortunately I haven't found time to get around to it yet. The other issue you are seeing is that CoInitialize() needs to be called in each *thread* that wants to make COM calls. To do this properly, the module needs to provide a CLONE method if you are using Perl threads in 5.8.x. I have no clue how all this relates to MP1; it is just the subject line that made me take a brief peek at this message. Cheers, -Jan -- 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