/** * handled events sent through the global event-queue * * each event-thread has its own listener on the event-queue and * calls chassis_event_handle() with its own event-base * * @see chassis_event_add() */ void chassis_event_handle(int G_GNUC_UNUSED event_fd, short G_GNUC_UNUSED events, void *user_data) { chassis_event_thread_t *event_thread = user_data; struct event_base *event_base = event_thread->event_base; chassis *chas = event_thread->chas; chassis_event_op_t *op; char ping[1024]; guint received = 0; gssize removed; while ((op = g_async_queue_try_pop(chas->threads->event_queue))) { chassis_event_op_apply(op, event_base); chassis_event_op_free(op); received++; } //g_message(""); /* the pipe has one . per event, remove as many as we received */ while (received > 0 && (removed = recv(event_thread->notify_fd, ping, MIN(received, sizeof(ping)), 0)) > 0) { received -= removed; } }
/** * add a event * * @see network_connection_pool_lua_add_connection() */ void chassis_event_add_local_with_timeout(chassis G_GNUC_UNUSED *chas, struct event *ev, struct timeval *tv) { struct event_base *event_base = chas->event_base; chassis_event_op_t *op; g_assert(event_base); op = chassis_event_op_new(); op->type = CHASSIS_EVENT_OP_ADD; op->ev = ev; chassis_event_op_set_timeout(op, tv); chassis_event_op_apply(op, event_base); chassis_event_op_free(op); }
/** * add a event to the current thread * * needs event-base stored in the thread local storage * * @see network_connection_pool_lua_add_connection() */ void chassis_event_add_local(chassis G_GNUC_UNUSED *chas, struct event *ev) { struct event_base *event_base = ev->ev_base; chassis_event_op_t *op; if (!event_base) event_base = g_private_get(tls_event_base_key); g_assert(event_base); /* the thread-local event-base has to be initialized */ op = chassis_event_op_new(); op->type = CHASSIS_EVENT_OP_ADD; op->ev = ev; chassis_event_op_apply(op, event_base); chassis_event_op_free(op); }
/** * handled events sent through the global event-queue * * @see chassis_event_add() */ void chassis_event_handle(int G_GNUC_UNUSED event_fd, short G_GNUC_UNUSED events, void *user_data) { chassis_event_t *event = user_data; struct event_base *event_base = event->event_base; chassis *chas = event->chas; chassis_event_op_t *op; do { char ping[1]; gsize ret; if (op = g_async_queue_try_pop_unlocked(chas->event_queue)) { chassis_event_op_apply(op, event_base); chassis_event_op_free(op); if (1 != (ret = recv(event->notify_fd, ping, 1, 0))) { /* we failed to pull .'s from the notify-queue */ int last_errno; last_errno = errno; g_debug("%s: cal chassis_event_handle, fd:%d, errno:%d", G_STRLOC, event->notify_fd, last_errno); switch (last_errno) { case EAGAIN: case E_NET_WOULDBLOCK: /* that's fine ... */ g_debug("%s: recv() from event-notify-fd failed: %s", G_STRLOC, g_strerror(last_errno)); break; default: g_critical("%s: recv() from event-notify-fd failed: %s", G_STRLOC, g_strerror(last_errno)); break; } } } } while (op); /* even if op is 'free()d' it still is != NULL */ }