So far most questions on this list were about module names. This question is about a method name. Liz suggested that I ask here, as it's pretty important to choose a good name for this particular method, and you will understand why in the moment. If you ever write an XS module you will want to read on, even if you can't contribute to this thread.

The discussed issue affects perl programs spawning perl threads and embed perl programs like mod_perl running in the threaded environment (e.g. worker and winnt mpms of Apache 2.x). In the case of mod_perl 2.0, Unix users can always avoid running threaded perl by running the prefork mpm, but win32 users can't - they are stuck with the threaded Apache server and that means with threaded perl environment. So if you maintain an XS CPAN module, chances are that you will need to make it working with Perl ithreads, as these users will come bugging you, so you should at least be aware of the gotchas...

Perl 5.8.0 has introduced a working ithreads implementation (there were Threads before 5.8.0, but they are R.I.P.). Under which any pure perl module, not relying on XSUBs (XS glue code interfacing C) and core perl functions that internally call C function, will work just fine. Well there is an issue with thread-local functions, which affect all threads (e.g. chdir), but we will leave that issue and the issue with core perl functions that call C function to the threads manpage. We will concentrate on XSUBs.

Among other things XSUBs allow developers to manipulate C structs via Perl (see perlxs and perlxstut manpages for more info). In order to pass the C struct around in the perl code, one would create a perl SV variable, stash a pointer to that C struct into an IV slot of that variable and return to the perl user a reference to that variable blessed into some class. Now users can call methods on this variable, every time a method is called, XSUB will retrieve the pointer to the C struct from SV's IV slot and do something about it. So far so good.

Now enter Perl ithreads, which are very different from any other threads implementation that you may ever encountered. Perl ithreads don't share any variables between threads, unless you explicitly tell it to (see the threads::shared manpage for more info). Due to this property pure Perl modules require not changes to work with ithreads. When a new thread is started a new perl interpreter is created from the parent interpreter, and all variables that existed in the parent interepreter are cloned. So for example if you had a variable $x whose IV value was 5, it'll be cloned in the new thread, with the same value. And that's where comes the catch - Perl doesn't know how to handle the special variables that contain a pointer to the C struct, because they aren't special to Perl. All Perl sees is something like 0x832cf08 in a variable's $y IV slot, which is exactly the same as 5 in the previous example. So what it does, is cloning that $y, including its IV slot. In the case of $x containing 5, two threads manipulating that variable don't affect each other. However in the case of $y, two threads are now operating on the same C struct pointer. Several problems emerge:

1) you now to need to serialize the access to this variable or make the XS code thread-safe

2) When $y goes out of scope, perl will call DESTROY which will try to free the memory allocated by the C struct. So the first threads successfully free()s the memory. Now the second thread is in trouble as it'll try to work with memory that was deallocated. All kind of segfaults and hangs kick in.

Obviously there is a solution to this problem. Enter the magic CLONE function called when a new thread is spawned (perl_clone is called). If a package defines this function, perl will call it. When CLONE is called Perl has already cloned $y. So what you need to do is to go and change $y's guts to point to a new C struct, initialized from the original C struct. But without changing $y, i.e. it's external appearance must not change. Only the IV slot needs to be changed. So here is where my question comes into the picture. How to call that method that will substitute the IV slot without changing the object. It's going to be used by many XS modules so we'd better choose a good name for it so we can all talk about the same method.

I chose the name 'possess' as if the object 'being possessed by some evil spirit'. Remember that the external object must stay the same (since it lives in the user's space, e.g. script and we can't touch it).

Liz wrote a module Thread::Bless which provides a framework for this issue, and she called this method 'fixup'.

Now that hopefully you understand the problem and what the method is trying to achieve, Liz and I are trying to get more ideas from you.

BTW, if you want to understand the issue in more details, I've written Example::CLONE which is a simple interface to C struct with a few accessors:
http://apache.org/~stas/Example-CLONE-0.01.tar.gz
Once it's polished you will find it in the perlthreads manpage, and I may post an article on the topic...


__________________________________________________________________
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



Reply via email to