static void eio_on_want_poll (EV_P_ ev_async *watcher, int revents) { manos_data_t *data = (manos_data_t *) watcher->data; if (eio_poll () == -1) ev_idle_start (EV_A_ &eio_idle_watcher); }
/*-----------------------------EventLoop------------------------------*/ static int EventLoop () { struct ev_loop *loop; struct ev_idle *eidle; ev_io *standard_input; ev_io *socket_input; LogDebug("%s EventLoop Started", global_argv[0]); loop = ev_default_loop(EVBACKEND_SELECT); /* Create an idle event to stop the program */ eidle = malloc(sizeof(ev_idle)); ev_idle_init(eidle, Idle); ev_idle_start(loop, eidle); /* Create the standard_input event */ standard_input = malloc(sizeof(ev_io)); ev_io_init(standard_input, ReadStdin, STDIN_FILENO, EV_READ); ev_io_start(loop, standard_input); /* Create the socket_input event */ socket_input = malloc(sizeof(ev_io)); ev_io_init(socket_input, ReadSocket, sockfd, EV_READ); ev_io_start(loop, socket_input); ev_loop(loop, 0); LogDebug("%s EventLoop finished", global_argv[0]); return 0; }
static guint add_idle_full (MilterEventLoop *loop, gint priority, GSourceFunc function, gpointer data, GDestroyNotify notify) { guint id; ev_idle *watcher; IdleWatcherPrivate *watcher_priv; MilterLibevEventLoopPrivate *priv; priv = MILTER_LIBEV_EVENT_LOOP_GET_PRIVATE(loop); watcher_priv = g_new0(IdleWatcherPrivate, 1); watcher_priv->function = function; watcher = g_new0(ev_idle, 1); watcher->data = watcher_priv; id = add_watcher(MILTER_LIBEV_EVENT_LOOP(loop), (ev_watcher *)watcher, WATCHER_STOP_FUNC(ev_idle_stop), NULL, notify, data); ev_idle_init(watcher, idle_func); ev_idle_start(priv->ev_loop, watcher); return id; }
/** * Starts the idle so it won't be called by the specified event loop. * * Usage: * idle:start(loop [, is_daemon]) * * [+0, -0, e] */ static int idle_start(lua_State *L) { ev_idle* idle = check_idle(L, 1); struct ev_loop* loop = *check_loop_and_init(L, 2); int is_daemon = lua_toboolean(L, 3); ev_idle_start(loop, idle); loop_start_watcher(L, 2, 1, is_daemon); return 0; }
eNextState NextDBOperation(AsyncIO *IO, IO_CallBack CB) { SetEVState(IO, eQDBNext); IO->NextDBOperation = CB; ev_idle_init(&IO->db_unwind_stack, DB_PerformNext); IO->db_unwind_stack.data = IO; ev_idle_start(event_db, &IO->db_unwind_stack); return eDBQuery; }
int uv_close(uv_handle_t* handle, uv_close_cb close_cb) { uv_tcp_t* tcp; uv_async_t* async; uv_timer_t* timer; handle->close_cb = close_cb; switch (handle->type) { case UV_TCP: tcp = (uv_tcp_t*) handle; uv_read_stop((uv_stream_t*)tcp); ev_io_stop(EV_DEFAULT_ &tcp->write_watcher); break; case UV_PREPARE: uv_prepare_stop((uv_prepare_t*) handle); break; case UV_CHECK: uv_check_stop((uv_check_t*) handle); break; case UV_IDLE: uv_idle_stop((uv_idle_t*) handle); break; case UV_ASYNC: async = (uv_async_t*)handle; ev_async_stop(EV_DEFAULT_ &async->async_watcher); ev_ref(EV_DEFAULT_UC); break; case UV_TIMER: timer = (uv_timer_t*)handle; if (ev_is_active(&timer->timer_watcher)) { ev_ref(EV_DEFAULT_UC); } ev_timer_stop(EV_DEFAULT_ &timer->timer_watcher); break; default: assert(0); return -1; } uv_flag_set(handle, UV_CLOSING); /* This is used to call the on_close callback in the next loop. */ ev_idle_start(EV_DEFAULT_ &handle->next_watcher); ev_feed_event(EV_DEFAULT_ &handle->next_watcher, EV_IDLE); assert(ev_is_pending(&handle->next_watcher)); return 0; }
void * work(void *p) { signal(SIGPIPE, SIG_IGN); ev_idle idle_watcher; ev_idle_init (&idle_watcher, idle_cb); ev_idle_start(work_loop, &idle_watcher); ev_async_init(&async_watcher, async_cb); ev_async_start(work_loop, &async_watcher); ev_loop(work_loop, 0); return (void *)0; }
static void defer_enable(struct pa_defer_event *ev, int b) { if (b) { lem_debug("starting"); ev_idle_start(LEM_ &ev->w); } else { lem_debug("stopping"); ev_idle_stop(LEM_ &ev->w); } }
static void prepare_cb (struct ev_loop *loop, ev_prepare *w, int revents) { struct ev_flux *fw = (struct ev_flux *)((char *)w - offsetof (struct ev_flux, prepare_w)); int events = get_pollevents (fw->h); if ((events & fw->events) || (events & EV_ERROR)) ev_idle_start (loop, &fw->idle_w); else ev_io_start (loop, &fw->io_w); }
int uv_idle_start(uv_handle_t* handle, uv_loop_cb cb) { int was_active = ev_is_active(&handle->idle_watcher); handle->idle_cb = cb; ev_idle_start(EV_DEFAULT_UC_ &handle->idle_watcher); if (!was_active) { ev_unref(EV_DEFAULT_UC); } return 0; }
int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) { int was_active = ev_is_active(&idle->idle_watcher); idle->idle_cb = cb; ev_idle_start(idle->loop->ev, &idle->idle_watcher); if (!was_active) { ev_unref(idle->loop->ev); } return 0; }
/* Register a python function to execute when idle */ PyObject *py_defer(PyObject *self, PyObject *args) { PyObject *pyfct, *pycombined, *pyfctargs; int startidle=0; int toadd=1; int listsize=0; if (!PyArg_ParseTuple(args, "OOO", &pyfct, &pyfctargs, &pycombined)) return NULL; //if queue is empty, trigger a start of idle if (!pydeferqueue) { pydeferqueue=PyList_New(0); } listsize=PyList_Size(pydeferqueue); if (listsize==0) { //it has been stopped by the idle_cb startidle=1; } //add fct cb into the defer queue PyObject *pyelem=PyList_New(0); PyList_Append(pyelem, pyfct); PyList_Append(pyelem, pyfctargs); if (pycombined==Py_True) { //check if the fucntion is already in the queue if (PySequence_Contains(pydeferqueue, pyelem)) { toadd=0; } } if (toadd==1) { PyList_Append(pydeferqueue, pyelem); //start the idle if (startidle==1) { //we create a new idle watcher and we start it if (debug) printf("trigger idle_start \n"); ev_idle_start(loop, idle_watcher); } } Py_DECREF(pyelem); return Py_None; }
static struct pa_defer_event * defer_new(pa_mainloop_api *a, pa_defer_event_cb_t cb, void *userdata) { struct pa_defer_event *ev = lem_xmalloc(sizeof(struct pa_defer_event)); (void)a; lem_debug("new defer %p", ev); ev_idle_init(&ev->w, defer_handler); ev->w.data = userdata; ev->cb = cb; ev->destroy = NULL; ev_idle_start(LEM_ &ev->w); return ev; }
int uv_close(uv_handle_t* handle) { switch (handle->type) { case UV_TCP: ev_io_stop(EV_DEFAULT_ &handle->write_watcher); ev_io_stop(EV_DEFAULT_ &handle->read_watcher); break; case UV_PREPARE: uv_prepare_stop(handle); break; case UV_CHECK: uv_check_stop(handle); break; case UV_IDLE: uv_idle_stop(handle); break; case UV_ASYNC: ev_async_stop(EV_DEFAULT_ &handle->async_watcher); ev_ref(EV_DEFAULT_UC); break; case UV_TIMER: if (ev_is_active(&handle->timer_watcher)) { ev_ref(EV_DEFAULT_UC); } ev_timer_stop(EV_DEFAULT_ &handle->timer_watcher); break; default: assert(0); return -1; } uv_flag_set(handle, UV_CLOSING); /* This is used to call the on_close callback in the next loop. */ ev_idle_start(EV_DEFAULT_ &handle->next_watcher); ev_feed_event(EV_DEFAULT_ &handle->next_watcher, EV_IDLE); assert(ev_is_pending(&handle->next_watcher)); return 0; }
void lem_queue(lua_State *T, int nargs) { struct lem_runqueue_slot *slot; assert(T != NULL); lem_debug("enqueueing thread with %d argument%s", nargs, nargs == 1 ? "" : "s"); if (rq.first == rq.last) ev_idle_start(LEM_ &rq.w); slot = &rq.queue[rq.last]; slot->T = T; slot->nargs = nargs; rq.last++; rq.last &= rq.mask; if (rq.first == rq.last) { unsigned int i; unsigned int j; struct lem_runqueue_slot *new_queue; lem_debug("expanding queue to %u slots", 2*(rq.mask + 1)); new_queue = lem_xmalloc(2*(rq.mask + 1) * sizeof(struct lem_runqueue_slot)); i = 0; j = rq.first; do { new_queue[i] = rq.queue[j]; i++; j++; j &= rq.mask; } while (j != rq.first); free(rq.queue); rq.queue = new_queue; rq.first = 0; rq.last = i; rq.mask = 2*rq.mask + 1; } }
int main (void) { // use the default event loop unless you have special needs struct ev_loop *loop = EV_DEFAULT; // initialise an io watcher, then start it // this one will watch for stdin to become readable ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); ev_io_start (loop, &stdin_watcher); // initialise a timer watcher, then start it // simple non-repeating 5.5 second timeout ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); ev_timer_start (loop, &timeout_watcher); ev_idle_init(&idle_watcher, idle_cb); ev_idle_start(loop, &idle_watcher); // now wait for events to arrive ev_run (loop, 0); // break was called, so exit return 0; }
void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { uv_async_t* async; uv_stream_t* stream; uv_process_t* process; handle->close_cb = close_cb; switch (handle->type) { case UV_NAMED_PIPE: uv_pipe_cleanup((uv_pipe_t*)handle); /* Fall through. */ case UV_TTY: case UV_TCP: stream = (uv_stream_t*)handle; uv_read_stop(stream); ev_io_stop(stream->loop->ev, &stream->write_watcher); uv__close(stream->fd); stream->fd = -1; if (stream->accepted_fd >= 0) { uv__close(stream->accepted_fd); stream->accepted_fd = -1; } assert(!ev_is_active(&stream->read_watcher)); assert(!ev_is_active(&stream->write_watcher)); break; case UV_UDP: uv__udp_start_close((uv_udp_t*)handle); break; case UV_PREPARE: uv_prepare_stop((uv_prepare_t*) handle); break; case UV_CHECK: uv_check_stop((uv_check_t*) handle); break; case UV_IDLE: uv_idle_stop((uv_idle_t*) handle); break; case UV_ASYNC: async = (uv_async_t*)handle; ev_async_stop(async->loop->ev, &async->async_watcher); ev_ref(async->loop->ev); break; case UV_TIMER: uv_timer_stop((uv_timer_t*)handle); break; case UV_PROCESS: process = (uv_process_t*)handle; ev_child_stop(process->loop->ev, &process->child_watcher); break; case UV_FS_EVENT: uv__fs_event_destroy((uv_fs_event_t*)handle); break; default: assert(0); } handle->flags |= UV_CLOSING; /* This is used to call the on_close callback in the next loop. */ ev_idle_start(handle->loop->ev, &handle->next_watcher); ev_feed_event(handle->loop->ev, &handle->next_watcher, EV_IDLE); assert(ev_is_pending(&handle->next_watcher)); }
static void idle_start (void *impl, flux_watcher_t *w) { assert (w->signature == IDLE_SIG); ev_idle_start (w->r->loop, (ev_idle *)impl); }
static void ready (EV_P_ ev_async *w, int revents) { if (eio_poll () == -1) ev_idle_start (EV_A_ &repeat_watcher); }
explicit RunOnceEvent(std::function<void()> func) : callback(func) { struct ev_loop *loop = EV_DEFAULT; ev_idle_init(&event, &RunOnceEvent::trampoline); ev_idle_start(EV_A_ &event); }
eNextState EvConnectSock(AsyncIO *IO, double conn_timeout, double first_rw_timeout, int ReadFirst) { struct sockaddr_in egress_sin; int fdflags; int rc = -1; SetEVState(IO, eIOConnectSock); become_session(IO->CitContext); if (ReadFirst) { IO->NextState = eReadMessage; } else { IO->NextState = eSendReply; } IO->SendBuf.fd = IO->RecvBuf.fd = socket( (IO->ConnectMe->IPv6)?PF_INET6:PF_INET, SOCK_STREAM, IPPROTO_TCP); if (IO->SendBuf.fd < 0) { EV_syslog(LOG_ERR, "EVENT: socket() failed: %s\n", strerror(errno)); StrBufPrintf(IO->ErrMsg, "Failed to create socket: %s", strerror(errno)); IO->SendBuf.fd = IO->RecvBuf.fd = 0; return eAbort; } fdflags = fcntl(IO->SendBuf.fd, F_GETFL); if (fdflags < 0) { EV_syslog(LOG_ERR, "EVENT: unable to get socket %d flags! %s \n", IO->SendBuf.fd, strerror(errno)); StrBufPrintf(IO->ErrMsg, "Failed to get socket %d flags: %s", IO->SendBuf.fd, strerror(errno)); close(IO->SendBuf.fd); IO->SendBuf.fd = IO->RecvBuf.fd = 0; return eAbort; } fdflags = fdflags | O_NONBLOCK; if (fcntl(IO->SendBuf.fd, F_SETFL, fdflags) < 0) { EV_syslog( LOG_ERR, "EVENT: unable to set socket %d nonblocking flags! %s \n", IO->SendBuf.fd, strerror(errno)); StrBufPrintf(IO->ErrMsg, "Failed to set socket flags: %s", strerror(errno)); close(IO->SendBuf.fd); IO->SendBuf.fd = IO->RecvBuf.fd = 0; return eAbort; } /* TODO: maye we could use offsetof() to calc the position of data... * http://doc.dvgu.ru/devel/ev.html#associating_custom_data_with_a_watcher */ ev_io_init(&IO->recv_event, IO_recv_callback, IO->RecvBuf.fd, EV_READ); IO->recv_event.data = IO; ev_io_init(&IO->send_event, IO_send_callback, IO->SendBuf.fd, EV_WRITE); IO->send_event.data = IO; ev_timer_init(&IO->conn_fail, IO_connfail_callback, conn_timeout, 0); IO->conn_fail.data = IO; ev_timer_init(&IO->rw_timeout, IO_Timeout_callback, first_rw_timeout,0); IO->rw_timeout.data = IO; /* for debugging you may bypass it like this: * IO->Addr.sin_addr.s_addr = inet_addr("127.0.0.1"); * ((struct sockaddr_in)IO->ConnectMe->Addr).sin_addr.s_addr = * inet_addr("127.0.0.1"); */ if (IO->ConnectMe->IPv6) { rc = connect(IO->SendBuf.fd, &IO->ConnectMe->Addr, sizeof(struct sockaddr_in6)); } else { /* If citserver is bound to a specific IP address on the host, make * sure we use that address for outbound connections. */ memset(&egress_sin, 0, sizeof(egress_sin)); egress_sin.sin_family = AF_INET; if (!IsEmptyStr(CtdlGetConfigStr("c_ip_addr"))) { egress_sin.sin_addr.s_addr = inet_addr(CtdlGetConfigStr("c_ip_addr")); if (egress_sin.sin_addr.s_addr == !INADDR_ANY) { egress_sin.sin_addr.s_addr = INADDR_ANY; } /* If this bind fails, no problem; we can still use INADDR_ANY */ bind(IO->SendBuf.fd, (struct sockaddr *)&egress_sin, sizeof(egress_sin)); } rc = connect(IO->SendBuf.fd, (struct sockaddr_in *)&IO->ConnectMe->Addr, sizeof(struct sockaddr_in)); } if (rc >= 0){ SetEVState(IO, eIOConnNow); EV_syslog(LOG_DEBUG, "connect() = %d immediate success.\n", IO->SendBuf.fd); set_start_callback(event_base, IO, 0); return IO->NextState; } else if (errno == EINPROGRESS) { SetEVState(IO, eIOConnWait); EV_syslog(LOG_DEBUG, "connect() = %d have to wait now.\n", IO->SendBuf.fd); ev_io_init(&IO->conn_event, IO_connestd_callback, IO->SendBuf.fd, EV_READ|EV_WRITE); IO->conn_event.data = IO; ev_io_start(event_base, &IO->conn_event); ev_timer_start(event_base, &IO->conn_fail); return IO->NextState; } else { SetEVState(IO, eIOConnfail); ev_idle_init(&IO->conn_fail_immediate, IO_connfailimmediate_callback); IO->conn_fail_immediate.data = IO; ev_idle_start(event_base, &IO->conn_fail_immediate); EV_syslog(LOG_ERR, "connect() = %d failed: %s\n", IO->SendBuf.fd, strerror(errno)); StrBufPrintf(IO->ErrMsg, "Failed to connect: %s", strerror(errno)); return IO->NextState; } return IO->NextState; }
int main(int argc, char *argv[]) { #if EV_MULTIPLICITY lem_loop = ev_default_loop(LEM_LOOPFLAGS); if (lem_loop == NULL) { #else if (!ev_default_loop(LEM_LOOPFLAGS)) { #endif lem_log_error("lem: error initializing event loop"); return EXIT_FAILURE; } if (setsignal(SIGPIPE, SIG_IGN, 0) #if !EV_CHILD_ENABLE || setsignal(SIGCHLD, SIG_DFL, SA_NOCLDSTOP | SA_NOCLDWAIT) #endif ) goto error; /* create main Lua state */ L = luaL_newstate(); if (L == NULL) { lem_log_error("lem: error initializing Lua state"); goto error; } luaL_openlibs(L); /* push thread table */ lua_newtable(L); /* initialize runqueue */ ev_idle_init(&rq.w, runqueue_pop); ev_idle_start(LEM_ &rq.w); rq.queue = lem_xmalloc(LEM_INITIAL_QUEUESIZE * sizeof(struct lem_runqueue_slot)); rq.first = rq.last = 0; rq.mask = LEM_INITIAL_QUEUESIZE - 1; /* initialize threadpool */ if (pool_init()) { lem_log_error("lem: error initializing threadpool"); goto error; } /* load file */ if (queue_file(argc, argv, 1)) goto error; /* start the mainloop */ ev_loop(LEM_ 0); lem_debug("event loop exited"); /* if there is an error message left on L print it */ if (lua_type(L, -1) == LUA_TSTRING) lem_log_error("lem: %s", lua_tostring(L, -1)); /* shutdown Lua */ lua_close(L); /* free runqueue */ free(rq.queue); /* destroy loop */ #if EV_MULTIPLICITY ev_loop_destroy(lem_loop); #else ev_default_destroy(); #endif lem_debug("Bye %s", exit_status == EXIT_SUCCESS ? "o/" : ":("); return exit_status; error: if (L) lua_close(L); if (rq.queue) free(rq.queue); #if EV_MULTIPLICITY ev_loop_destroy(lem_loop); #else ev_default_destroy(); #endif return EXIT_FAILURE; }