Hello,
I am trying to write a XS module for a C library that creates its own
threads from which I have to pass callbacks back into perl.
Unfortunately, I am pretty much confused by the discussion of threads
in perlguts.
IIUC, I don't need to create multiple PerlInterpreter's. I just need
to set up the TLS properly in each thread. But it is not clear to me
how to do that.
>From the perl point of view, this library would be used like this:
use Mylib;
if (Mylib::init()) { # this will create the additional threads
# Main thread returns immediately after creating background threads
# For now we only sit and wait until we get killed. In a future
# improvement we might periodically check for configuration
# changes and restart.
#
sleep (0);
Mylib::shutdown(); # Cleanup
}
sub callback {
# this will be called when the other threads want to notify
# any events
}
The XS part of the interface seems to be easy:
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include </m/l/misc/mylib/mylib.h>
MODULE = Mylib PACKAGE = Mylib
void
deinit()
int
init()
And here is the C part of the interface into the library:
/* Protects against concurrent calls from different threads into perl
*/
static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
/* This function will be called by the threads created in lib_init()
*/
void test_callback (void)
{
dTHX;
dSP;
pthread_mutex_lock(&mutex);
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVpv("some", 4)));
XPUSHs(sv_2mortal(newSVpv("test", 4)));
XPUSHs(sv_2mortal(newSVpv("vals", 4)));
PUTBACK;
call_pv("callback", G_DISCARD);
pthread_mutex_unlock(&mutex);
}
int init (void)
{
/* For test purposes we call this from the main thread before any
other threads are created
*/
test_callback();
/* the lib_init() function will create the additional threads
which in turn will be calling test_callback()
*/
return lib_init ();
}
void deinit (void)
{
lib_deinit ();
}
Any hints? Or maybe a pointer to an example?