static int coroae_wait_fd_read(int fd, int timeout) { int ret = 0; dSP; ENTER; SAVETMPS; PUSHMARK(SP); mXPUSHs(newSViv(fd)); mXPUSHs(newSViv(timeout)); PUTBACK; call_pv("Coro::AnyEvent::readable", G_SCALAR|G_EVAL); SPAGAIN; if(SvTRUE(ERRSV)) { uwsgi_log("[uwsgi-perl error] %s", SvPV_nolen(ERRSV)); (void)POPs; // we must pop undef from the stack in G_SCALAR context } else { SV *p_ret = POPs; if (SvTRUE(p_ret)) { ret = 1; } } PUTBACK; FREETMPS; LEAVE; return ret; }
static SV *coroae_add_signal_watcher(const char *signame, CV *cb) { SV *newobj; dSP; ENTER; SAVETMPS; PUSHMARK(SP); mXPUSHs(newSVpvs("AnyEvent")); mXPUSHs(newSVpvs("signal")); mXPUSHs(newSVpv(signame, 0)); mXPUSHs(newSVpvs("cb")); mXPUSHs(newRV_noinc((SV *)cb)); PUTBACK; call_method("signal", G_SCALAR|G_EVAL); SPAGAIN; if(SvTRUE(ERRSV)) { // no need to continue... uwsgi_log("[uwsgi-perl error] %s", SvPV_nolen(ERRSV)); exit(1); } else { newobj = SvREFCNT_inc(POPs); } PUTBACK; FREETMPS; LEAVE; return newobj; }
// create a new coro SV * coroae_coro_new(CV *block) { SV *newobj = NULL; dSP; ENTER; SAVETMPS; PUSHMARK(SP); mXPUSHs(newSVpvs("Coro")); mXPUSHs(newRV_noinc((SV *)block)); PUTBACK; call_method("new", G_SCALAR|G_EVAL); SPAGAIN; if(SvTRUE(ERRSV)) { uwsgi_log("[uwsgi-perl error] %s", SvPV_nolen(ERRSV)); (void)POPs; // we must pop undef from the stack in G_SCALAR context } else { newobj = SvREFCNT_inc(POPs); } PUTBACK; FREETMPS; LEAVE; return newobj; }
static void* run_thread(void* arg) { mthread* thread = (mthread*) arg; PerlInterpreter* my_perl = construct_perl(); const message *to_run, *modules, *message; SV *call, *status; perl_mutex* shutdown_mutex; thread->interp = my_perl; #ifndef WIN32 S_set_sigmask(&thread->initial_sigmask); #endif PERL_SET_CONTEXT(my_perl); store_self(my_perl, thread); { dSP; modules = queue_dequeue(thread->queue, NULL); load_modules(my_perl, modules); to_run = queue_dequeue(thread->queue, NULL); ENTER; SAVETMPS; call = SvRV(message_load_value(to_run)); PUSHMARK(SP); mXPUSHs(newSVpvn("exit", 4)); status = newSVpvn("normal", 6); mXPUSHs(status); mXPUSHs(newSViv(thread->id)); ENTER; PUSHMARK(SP); PUTBACK; call_sv(call, G_SCALAR|G_EVAL); SPAGAIN; if (SvTRUE(ERRSV)) { sv_setpvn(status, "error", 5); warn("Thread %"UVuf" got error %s\n", thread->id, SvPV_nolen(ERRSV)); PUSHs(ERRSV); } message_from_stack_pushed(message); LEAVE; send_listeners(thread, message); destroy_message(message); FREETMPS; LEAVE; } shutdown_mutex = get_shutdown_mutex(); MUTEX_LOCK(shutdown_mutex); perl_destruct(my_perl); MUTEX_UNLOCK(shutdown_mutex); mthread_destroy(thread); PerlMemShared_free(thread); perl_free(my_perl); return NULL; }