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?

Reply via email to