Thanks for your efforts, Shmuel! On Mon, Aug 04, 2008 at 08:10:31PM +0300, Shmuel Fomberg wrote: > >>IANAE, (I am not an expert) but if you say that the main thread returns > >>immediately and waiting in a loop for the lib, then you already have one > >>thread inside Perl. So the background threads shouldn't call into your > >>perl interpreter. > > > >If I understand correctly, I have two options then: > > > >1. _not_ let the main thread return back from the XS. That is, I > > move the sleep(0) from the perl script into the init() function. > > Would that break anything withhin perl? > > For this one you need a real expert. It is possible to call into Perl > from an XS sub. but to call into Perl from other threads while it is > inside a XS call? I have no idea.
As far as I understand the corresponding section in perlguts, it should be possible _if_ PERL_SET_CONTEXT() is called before. But for some reason it keeps crashing :-( > >2. I need to create a second perl interpreter (or clone the first one). > > Can somebody point me to example code how to do that? > > That's actually no big deal. look at perldoc page perlembed, there are > examples. What I am missing from those examples is the explanation how the different interpreters would communicate. And there's one more complication: the low-level library don't even state how many threads will call my callback. Therefore I would prefer to have only _one_ interpreter and use a mutex to keep the threads from entering the interpreter simultaneously. This is how my code (still crashing) looks right now: # define PERL_NO_GET_CONTEXT # include "defs.h" static SV *callback_ref = (SV*)NULL; static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; /* This function works OK when called from module_config() in main thread, but it crashes on PUSHMARK(SP) when called from other threads */ int call_perl (int cnt, ...) { dTHX; dSP; int i; I32 numargs; va_list args; pthread_mutex_lock(&mutex); PERL_SET_CONTEXT(my_perl); ENTER; SAVETMPS; PUSHMARK(SP); /* Here it crashes when called from different thread */ va_start (args, cnt); while (cnt-- > 0) { char *str = va_arg(args, char*); XPUSHs(sv_2mortal (newSVpv (str, strlen (str)))); } va_end (args); PUTBACK; numargs = call_sv (callback_ref, G_SCALAR); if (numargs != 1) croak("Big trouble\n"); SPAGAIN; for (i=0; i<numargs; i++) { printf ("ret %i\n", POPi); } PUTBACK; FREETMPS; LEAVE; pthread_mutex_unlock(&mutex); return numargs; } void module_config (SV *callback) { dTHX; if (callback_ref == (SV*)NULL) { callback_ref = newSVsv (callback); /* first time, create new SV */ } else { SvSetSV (callback_ref, callback); /* been here, overwrite */ } start_threads (); do { sleep (180); } while (call_perl (1, "check")); /* works OK when called from here */ }