/* * Arguments: ..., function, [arguments (any) ...] * Returns: [results (any) ...] */ static int levq_sync_call (lua_State *L, struct event_queue *evq, struct evq_sync_op *op, const int is_sched_add, const int fn_idx) { op->L = L; op->fn_idx = fn_idx; op->status = 0; op->is_sched_add = is_sched_add; op->next = evq->sync_op; evq->sync_op = op; evq_signal(evq, EVQ_SIGEVQ); if (is_sched_add) { lua_pushlightuserdata(L, op); /* sync_op_ludata */ return 1; } else { struct sys_thread *td = sys_thread_get(); const int old_top = fn_idx - 1; if (!td) luaL_argerror(L, 0, "Threading not initialized"); op->td = td; sys_thread_suspend(td, TIMEOUT_INFINITE); /* wait result */ if (op->status) lua_error(L); return lua_gettop(L) - old_top; } }
/* * Arguments: evq_udata, [signal (string)] * Returns: [evq_udata] */ static int levq_signal (lua_State *L) { struct event_queue *evq = checkudata(L, 1, EVQ_TYPENAME); const int signo = lua_isnoneornil(L, 2) ? EVQ_SIGEVQ : sig_flags[luaL_checkoption(L, 2, NULL, sig_names)]; if (!evq_signal(evq, signo)) { lua_settop(L, 1); return 1; } return sys_seterror(L, 0); }
static void signal_handler (const int signo) { #ifdef USE_KQUEUE (void) signo; #else struct event **sig_evp; if (signo == SYS_SIGINTR) return; sig_evp = signal_gethead(signo); if (!sig_evp) return; pthread_mutex_lock(&g_Signal.cs); { struct event *ev = *sig_evp; for (; ev; ev = ev->next_object) { if (!event_deleted(ev)) evq_signal(ev->evq, signo); } } pthread_mutex_unlock(&g_Signal.cs); #endif }