CORBA-omniORB
view release on metacpan or search on metacpan
omnithreads/omnithreads.xs view on Meta::CPAN
context = G_ARRAY;
}
} else if (hv_exists(specs, "scalar", 6)) {
if (SvTRUE(*hv_fetch(specs, "scalar", 6, 0))) {
context = G_SCALAR;
}
} else if (hv_exists(specs, "void", 4)) {
if (SvTRUE(*hv_fetch(specs, "void", 4, 0))) {
context = G_VOID;
}
}
/* exit => thread_only */
if (hv_exists(specs, "exit", 4)) {
str = (char *)SvPV_nolen(*hv_fetch(specs, "exit", 4, 0));
exit_opt = (*str == 't' || *str == 'T')
? PERL_ITHR_THREAD_EXIT_ONLY : 0;
}
}
if (context == -1) {
context = GIMME_V; /* Implicit context */
} else {
context |= (GIMME_V & (~(G_ARRAY|G_SCALAR|G_VOID)));
}
/* Function args */
params = newAV();
if (items > 2) {
for (ii=2; ii < items ; ii++) {
av_push(params, SvREFCNT_inc(ST(idx+ii)));
}
}
/* Create thread */
create_destruct_mutex.lock();
thread = S_ithread_create(aTHX_ function_to_call,
stack_size,
context,
exit_opt,
newRV_noinc((SV*)params));
if (! thread) {
XSRETURN_UNDEF;
}
ST(0) = sv_2mortal(ithread_to_SV(aTHX_ Nullsv, thread, classname, FALSE));
/* Let thread run */
thread->mutex.unlock();
create_destruct_mutex.unlock();
/* XSRETURN(1); - implied */
void
ithread_list(...)
PREINIT:
char *classname;
ithread *thread;
int list_context;
IV count = 0;
int want_running;
PPCODE:
/* Class method only */
if (SvROK(ST(0))) {
Perl_croak(aTHX_ "Usage: threads->list(...)");
}
classname = (char *)SvPV_nolen(ST(0));
/* Calling context */
list_context = (GIMME_V == G_ARRAY);
/* Running or joinable parameter */
if (items > 1) {
want_running = SvTRUE(ST(1));
}
/* Walk through threads list */
create_destruct_mutex.lock();
for (thread = main_thread.next;
thread != &main_thread;
thread = thread->next)
{
/* Ignore detached or joined threads */
if (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED)) {
continue;
}
/* Filter per parameter */
if (items > 1) {
if (want_running) {
if (thread->state & PERL_ITHR_FINISHED) {
continue; /* Not running */
}
} else {
if (! (thread->state & PERL_ITHR_FINISHED)) {
continue; /* Still running - not joinable yet */
}
}
}
/* Push object on stack if list context */
if (list_context) {
XPUSHs(sv_2mortal(ithread_to_SV(aTHX_ Nullsv, thread, classname, TRUE)));
}
count++;
}
create_destruct_mutex.unlock();
/* If scalar context, send back count */
if (! list_context) {
XSRETURN_IV(count);
}
void
ithread_self(...)
PREINIT:
char *classname;
ithread *thread;
CODE:
/* Class method only */
if (SvROK(ST(0))) {
Perl_croak(aTHX_ "Usage: threads->self()");
}
classname = (char *)SvPV_nolen(ST(0));
thread = S_ithread_get(aTHX);
ST(0) = sv_2mortal(ithread_to_SV(aTHX_ Nullsv, thread, classname, TRUE));
/* XSRETURN(1); - implied */
void
ithread_tid(...)
PREINIT:
ithread *thread;
CODE:
thread = SV_to_ithread(aTHX_ ST(0));
XST_mUV(0, thread->tid);
/* XSRETURN(1); - implied */
void
ithread_join(...)
PREINIT:
ithread *thread;
int join_err;
AV *params;
int len;
int ii;
void *retval;
PPCODE:
/* Object method only */
if (! sv_isobject(ST(0))) {
Perl_croak(aTHX_ "Usage: $thr->join()");
}
/* Check if the thread is joinable */
thread = SV_to_ithread(aTHX_ ST(0));
join_err = (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED));
if (join_err) {
if (join_err & PERL_ITHR_DETACHED) {
Perl_croak(aTHX_ "Cannot join a detached thread");
} else {
Perl_croak(aTHX_ "Thread already joined");
}
}
/* Join the thread */
PUTBACK;
{
UV token = unlock_interpreter(aTHX);
thread->thr->join(0);
relock_interpreter(aTHX_ token);
}
SPAGAIN;
thread->mutex.lock();
/* Mark as joined */
thread->state |= PERL_ITHR_JOINED;
/* Get the return value from the call_sv */
{
AV *params_copy;
PerlInterpreter *other_perl;
CLONE_PARAMS clone_params;
ithread *current_thread;
params_copy = (AV *)SvRV(thread->params);
other_perl = thread->interp;
clone_params.stashes = newAV();
clone_params.flags = CLONEf_JOIN_IN;
PL_ptr_table = ptr_table_new();
current_thread = S_ithread_get(aTHX);
S_ithread_set(aTHX_ thread);
/* Ensure 'meaningful' addresses retain their meaning */
ptr_table_store(PL_ptr_table, &other_perl->Isv_undef, &PL_sv_undef);
ptr_table_store(PL_ptr_table, &other_perl->Isv_no, &PL_sv_no);
ptr_table_store(PL_ptr_table, &other_perl->Isv_yes, &PL_sv_yes);
params = (AV *)sv_dup((SV*)params_copy, &clone_params);
S_ithread_set(aTHX_ current_thread);
SvREFCNT_dec(clone_params.stashes);
SvREFCNT_inc_void(params);
ptr_table_free(PL_ptr_table);
PL_ptr_table = NULL;
}
/* We are finished with the thread */
S_ithread_clear(aTHX_ thread);
thread->mutex.unlock();
{
( run in 0.389 second using v1.01-cache-2.11-cpan-71847e10f99 )