Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Perl callback from c, multiple threads, cloned interpreter

Reply
Thread Tools

Perl callback from c, multiple threads, cloned interpreter

 
 
Jeff
Guest
Posts: n/a
 
      06-14-2005
Hello,

I'm having a problem passing a function parameter to a perl callback
function being call from C w/ a cloned interpreter. The reason for the
cloned interpreter is that the perl callback function is being called
from a different thread, and perl does not currently support multiple
threads concurrently calling into the same interpreter.

The below function works perfectly if I do not clone the interpreter.
But when I clone the interpreter, the function parameter passed on the
stack does not make its way to the function. When the perl function
attempts to use this varaible, it's always 0.

Is there a special step I need to take to setup the function parameter
on the stack w/ a cloned interpreter? I've tried passing a reference
to the variable, and this also does not work.

Any insight would be greatly appreciated.

Thanks,
Jeff

static void PerlCallBack(void *clientdata)
{

//clone perl interpreter and set it as context
perl_clone((PerlInterpreter*)Perl_get_context(),
CLONEf_CLONE_HOST|CLONEf_KEEP_PTR_TABLE);

PUSHMARK(SP) ;

//push integer, 2, onto stack as parameter for test purposes
XPUSHs(sv_2mortal(newSViv(2)));
PUTBACK ;

//call perl function passed via clientdata
perl_call_sv((SV*) clientdata, G_DISCARD) ;
LEAVE;

}

 
Reply With Quote
 
 
 
 
Tassilo v. Parseval
Guest
Posts: n/a
 
      06-14-2005
Also sprach Jeff:

> I'm having a problem passing a function parameter to a perl callback
> function being call from C w/ a cloned interpreter. The reason for the
> cloned interpreter is that the perl callback function is being called
> from a different thread, and perl does not currently support multiple
> threads concurrently calling into the same interpreter.
>
> The below function works perfectly if I do not clone the interpreter.
> But when I clone the interpreter, the function parameter passed on the
> stack does not make its way to the function. When the perl function
> attempts to use this varaible, it's always 0.
>
> Is there a special step I need to take to setup the function parameter
> on the stack w/ a cloned interpreter? I've tried passing a reference
> to the variable, and this also does not work.
>
> Any insight would be greatly appreciated.
>
> Thanks,
> Jeff
>
> static void PerlCallBack(void *clientdata)
> {
>
> //clone perl interpreter and set it as context
> perl_clone((PerlInterpreter*)Perl_get_context(),
> CLONEf_CLONE_HOST|CLONEf_KEEP_PTR_TABLE);


I am not actually an expert when it comes to working with several perl
interpreters. However, are you sure that the above comment correctly
describes what your code is doing? perl_clone() returns the new
interpreter. You are not doing anything with the return value.

I would assume, something like

PerlInterpreter *p = perl_clone(PERL_GET_CONTEXT,
CLONEf_CLONE_HOST|CLONEf_KEEP_PTR_TABLE);
PERL_SET_CONTEXT(p);

is needed.

> PUSHMARK(SP) ;
>
> //push integer, 2, onto stack as parameter for test purposes
> XPUSHs(sv_2mortal(newSViv(2)));
> PUTBACK ;
>
> //call perl function passed via clientdata
> perl_call_sv((SV*) clientdata, G_DISCARD) ;


The (P|p)erl_ form of the various functions should no longer be used.
It's simply call_sv().

Tassilo
--
use bigint;
$n=71423350343770280161397026330337371139054411854 220053437565440;
$m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($ m+=<=200);
 
Reply With Quote
 
 
 
 
Jeff
Guest
Posts: n/a
 
      06-14-2005
The perl_clone() functon creates a new interpreter and set's it as the
current context. There is no need to call PERL_SET_CONTEXT again.

Thanks for the input though.

 
Reply With Quote
 
Tassilo v. Parseval
Guest
Posts: n/a
 
      06-14-2005
Also sprach Jeff:

> The perl_clone() functon creates a new interpreter and set's it as the
> current context. There is no need to call PERL_SET_CONTEXT again.


I am still not entirely convinced that a mere perl_clone() is all you
have to do. It has to be made sure that in the current executing scope
there is a variable 'my_perl' that points to the actual interpreter.
Neither perl_context() nor my initial suggestion of PERL_SET_CONTEXT
ensure that. What happens if you do

dTHXa(perl_clone(aTHX, ...));

?

That will set pTHX which is #defined to be my_perl.

Tassilo
--
use bigint;
$n=71423350343770280161397026330337371139054411854 220053437565440;
$m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($ m+=<=200);
 
Reply With Quote
 
Jeff
Guest
Posts: n/a
 
      06-14-2005
The function call is executing in the new perl context. I can see this
in the debugger, and if it wasn't executing in the newly cloned
context, it would work.

I believe the problem is that the function reference I'm calling is
from the parent interpreter, and its CV value is pointing to the parent
interpreter, not the cloned interpreter.

Any ideas on how to fix this?

 
Reply With Quote
 
Tassilo v. Parseval
Guest
Posts: n/a
 
      06-15-2005
[ I am sure it would increase readability of this thread
if you quoted a bit of context. ]

Also sprach Jeff:

> The function call is executing in the new perl context. I can see this
> in the debugger, and if it wasn't executing in the newly cloned
> context, it would work.
>
> I believe the problem is that the function reference I'm calling is
> from the parent interpreter, and its CV value is pointing to the parent
> interpreter, not the cloned interpreter.


That sounds plausible.

> Any ideas on how to fix this?


As always in such cases, it's now probably necessary to try some of the
non-public stuff found in the source that has a promising name.

You might want to try it with applying sv_dup() to the callback SV. Its
prototype:

SV * Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param);

'CLONE_PARAMS' is:

struct clone_params {
AV* stashes;
UV flags;
PerlInterpreter *proto_perl;
};

'flags' seem to be those of perl_clone(). Looking at the source of
sv_dup(), 'stashes' is probably irrelevant in your case. 'proto_perl'
doesn't seem to be used for anything either but it can't hurt to store
perl_clone()'s return value there.

Other than that, skimming through ext/threads/threads.xs could be a good
idea (Perl_ithread_create() in particular).

Tassilo
--
use bigint;
$n=71423350343770280161397026330337371139054411854 220053437565440;
$m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($ m+=<=200);
 
Reply With Quote
 
Jeff
Guest
Posts: n/a
 
      06-15-2005
Good call on sv_dup, that fixed the problem. I'm still going to take a
look through Perl_ithread_create though to see how perl handles this
situation.

Thanks for your help,
Jeff

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Callback to Perl interpreter in C--something simpler than XS? Kevin Walzer Perl Misc 5 01-28-2013 10:45 AM
Session management when browser window is cloned mikharakiri_nospaum@yahoo.com Java 11 04-26-2006 07:11 PM
dvd menu on cloned disc Pavel Ferenc DVD Video 0 11-11-2005 05:53 PM
Cloned disk "thinks" it is much smaller than it is. Nomen Nescio Computer Security 5 08-12-2005 08:08 PM
Virtual Access Interface not cloned from Template Matthew Melbourne Cisco 0 11-11-2003 11:16 PM



Advertisments