Пример #1
0
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;
}
Пример #2
0
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;

}
Пример #3
0
// 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;
}
Пример #4
0
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;
}