in reply to Re^3: Extending & Embedding Perl simultaneously: How to share a scalar between perl callback sub and main body?
in thread Extending & Embedding Perl simultaneously: How to share a scalar between perl callback sub and main body?

Hi All,

Hoping to get some pointers as I am really stuck here. I couldnt yet figure out the cause of the problem.

I also couldnt find any package in CPAN to "hack" around this issue : most sharing related packages seem really geared toward multi-process, distributed sharing or persistance. None that are simple/for my case. I guess I've to write my own workaround? :(

Thx

ps: I'm in Asian timezone, hence the "delays" in responding back to posts.

  • Comment on Re^4: Extending & Embedding Perl simultaneously: How to share a scalar between perl callback sub and main body?

Replies are listed 'Best First'.
Re^5: Extending & Embedding Perl simultaneously: How to share a scalar between perl callback sub and main body?
by BrowserUk (Patriarch) on Dec 03, 2009 at 09:18 UTC

    The problem is that unless someone has encountered your exact scenario--which is quite unlikely--the only way to find a solution would be to try a few things out.

    But in order to try things out, anyone considering doing so would have to try and reproduce your code from your description. And that's a hard thing to do and rather expecting to much of us. cdarke had a good attempt, but fell short.

    If you want further help, you're much more likely to get it if you would post a minimal, runnable example that can be downloaded and tried out. Perhaps you could start with cdarke's example and modify it to reflect your requirements to the point where it produces the error message your getting.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Thanks for the comments BrowserUk. I understand. I was hoping my situation wasnt so unique..that cant be good for my project long term (ie more surprises probably lay ahead). Anycase, I'll post a full sample shortly. I'm not comfortable with XS (used SWIG), so may take a bit.
        Note: Completely rewrote this post as I got some sleep and have the code to demo the issue. Hoping you can now really see the cause/problem and offer ideas.

        Thanks in advance!

        PS: I think there some leaks etc in that code, but didnt care about those at this point.

        myModule.xs

        #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include <pthread.h> static PerlInterpreter *orig_perl=NULL; static PerlInterpreter *cb_perl=NULL; SV* cb_ptr = NULL; void InvokeCB () { static int val = 0; val++; dTHX; dSP; ENTER; SAVETMPS; PUSHMARK(SP); SV * sv = cb_ptr; if (my_perl != orig_perl) { CLONE_PARAMS clone_param; clone_param.stashes = NULL; clone_param.flags = CLONEf_COPY_STACKS | CLONEf_KEEP_PTR_TABLE; clone_param.proto_perl = cb_perl; sv = sv_dup(sv, &clone_param); } XPUSHs(sv_2mortal(newSViv(val))); PUTBACK; call_sv(sv, G_DISCARD); FREETMPS; LEAVE; } void * BGThread(void * dontcare) { PERL_SET_CONTEXT(orig_perl); cb_perl = perl_clone(orig_perl, CLONEf_COPY_STACKS | CLONEf_KEEP_PT +R_TABLE); PERL_SET_CONTEXT(cb_perl); while (1) { sleep(5); InvokeCB(); } } MODULE = myModule PACKAGE = myModule int RegisterCB (SV *SubRef) CODE: pthread_t tid; pthread_create(&tid, NULL, BGThread, NULL); orig_perl = PERL_GET_CONTEXT; cb_ptr = newSVsv(SubRef); SvSHARE(cb_ptr); RETVAL = 1; OUTPUT: RETVAL

        test.pl

        #! /usr/local/bin/perl use myModule; use warnings; #shared scalar $cb_done = 0; @results = (); #This cb would be invoked by the cloned interpreter in the #C library. This works fine. sub cb_one { ($value) = @_; print "CB called. val received : ", $value, "\n"; $results[scalar(@results)] = $value; if ($value == 5) { print "cb_done changed to one.\n"; $cb_done = 1; } } print "Registered CB...\n"; $status = myModule::RegisterCB(\&main::cb_one); do { print "Waiting for CB to be done...\n"; sleep (5); } until ($cb_done == 1); #These line should be printed when $cb_done becomes 1 #in the main of the perl script print "CB was invoked : $cb_done\n"; print "results are : @results \n";

        script output

        Name "main::status" used only once: possible typo at ./test.pl line 27 +. Registered CB... Waiting for CB to be done... Waiting for CB to be done... CB called. val received : 1 Waiting for CB to be done... CB called. val received : 2 Waiting for CB to be done... CB called. val received : 3 Waiting for CB to be done... CB called. val received : 4 Waiting for CB to be done... CB called. val received : 5 cb_done changed to one. Waiting for CB to be done... CB called. val received : 6 Waiting for CB to be done... CB called. val received : 7