in reply to Re^2: xs, threads and panic
in thread xs, threads and panic

The way perl's threading model works is that each thread has its own interpreter, and own set of SVs. When a new thread is created, perl makes a copy of every SV it knows about, and 'gives' them to the new interpreter. The new interpreter should not be able to mess with any of the SVs belonging to another interpreter; this is not thread-safe, and crashes and panics will occur.

What you need to do is replace the callback_ref variable - which perl doesn't know about - with a perl scalar (or array if you need more than one value) that is embedded in a namespace: $Callback::callback_ref, say. Then when you create a thread, a copy of $Callback::callback_ref is made in the new thread, and everyone's happy.

Dave.

Replies are listed 'Best First'.
Re^4: xs, threads and panic
by Anonymous Monk on May 20, 2009 at 14:38 UTC
    Yes, it works!
    Working code:

    Callback.pm
    package Callback; use 5.010000; use threads; use threads::shared; use strict; use warnings; require Exporter; use AutoLoader qw(AUTOLOAD); our @ISA = qw(Exporter); our $VERSION = '0.01'; require XSLoader; XSLoader::load('Callback', $VERSION); my $callback_ref; sub new($$) { my $invocant = shift; $callback_ref = shift; $invocant = ref $invocant if ref $invocant; my $self = &share({}); return bless $self, $invocant; } sub run($) { my $self = shift; my $param = shift; runCallback($callback_ref, $param); } 1;
    Callback.xs
    #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" # define PERL_NO_GET_CONTEXT int runCallback(CV* callback_ref, const char* param) { int count; int answer; dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(param, 0))); PUTBACK; count = call_sv((SV*)callback_ref, G_SCALAR); SPAGAIN; if (count != 1) croak("Uncknown return value format. Returned %d params instid 1", + count); answer = POPi; FREETMPS; LEAVE; return answer; } MODULE = Callback PACKAGE = Callback void runCallback(callback_ref, param) CV* callback_ref; const char* param; PROTOTYPE: $$ PPCODE: XPUSHs(sv_2mortal( newSViv(runCallback(callback_ref, param)) +));
    Thanks, Dave!