It seems that there are problems with using threads.pm inside threaded applications embedding perl. Let's take mod_perl 2.0 with worker mpm (which is a threaded app.

If I preload threads.pm at the server startup (thread A) and then try to use threads during request time (thread B), you will get a segfault. The problem is in the way threads.xs boots itself. It stores the current (the one that requires the module) thread's data in TLS. But when running in a different thread it can't access the original thread's TLS. Does it mean that we need a special handling for threads.pm inside mod_perl? Are there any docs covering that?

To reproduce the problem, require threads.pm somewhere at the server startup:

use threads;

now at request time, do:

  use threads;
  print threads->self->tid;

which ensures that we are in a different thread (not ithread) and it segfaults:

#0  0x402a6092 in pthread_mutex_lock () from /lib/i686/libpthread.so.0
#1  0x404f9f50 in ithread_to_SV (my_perl=0x8e34fe8, obj=0x0, thread=0x0,
    classname=0xa5fb970 "threads", inc=1 '\001') at threads.xs:331
#2  0x404fa545 in Perl_ithread_self (my_perl=0x8e34fe8, obj=0x0,
    Class=0xa5fb970 "threads") at threads.xs:510
#3  0x404fae26 in XS_threads_self (my_perl=0x8e34fe8, cv=0x9a003fc)
    at threads.xs:662
[...]

because nothing is really stored in the thread B's TLS, but threads.pm is already loaded so boot_threads is not called.

The only workaround I can think of is to force boot_threads (mess with DL handles) called in every new thread (not ithread!). May be threads.pm should provide a special method init() which will be called at boot and exposed to the users so they can call it in the threaded apps.

Notice that I didn't try to spawn ithreads from mod_perl. I just wanted to 'print threads->self->tid', though I can foresee people trying to run ithreads inside threaded modperl.

In any case the app, shouldn't segfault, but gracefully exit. So I think at least Perl_ithread_self should be safer. e.g.:

Perl_ithread_self (pTHX_ SV *obj, char* Class)
{
    ithread *thread;
    PERL_THREAD_GETSPECIFIC(self_key,thread);
-    return ithread_to_SV(aTHX_ obj, thread, Class, TRUE);
+   if (thread)
+      return ithread_to_SV(aTHX_ obj, thread, Class, TRUE);
+   else
+      Perl_croak(aTHX_ "can't find the threads data");
}

or something more helpful.

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to