develooper Front page | perl.ithreads | Postings from August 2008

XS callbacks from different threads.

Thread Next
From:
Josef Wolf
Date:
August 1, 2008 18:00
Subject:
XS callbacks from different threads.
Message ID:
20080802005912.GB27925@raven.wolf.lan
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?

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About