Пример #1
0
/**
 * free all event-threads
 *
 * frees all the registered event-threads and event-queue
 */
void chassis_event_threads_free(chassis_event_threads_t *threads) {
	guint i;
	chassis_event_op_t *op;

	if (!threads) return;

	/* all threads are running, now wait until they are down again */
	for (i = 0; i < threads->event_threads->len; i++) {
		chassis_event_thread_t *event_thread = threads->event_threads->pdata[i];

		chassis_event_thread_free(event_thread);
	}

	g_ptr_array_free(threads->event_threads, TRUE);

	/* free the events that are still in the queue */
	while ((op = g_async_queue_try_pop(threads->event_queue))) {
		chassis_event_op_free(op);
	}
	g_async_queue_unref(threads->event_queue);

	/* close the notification pipe */
	if (threads->event_notify_fds[0] != -1) {
		closesocket(threads->event_notify_fds[0]);
	}
	if (threads->event_notify_fds[1] != -1) {
		closesocket(threads->event_notify_fds[1]);
	}


	g_free(threads);
}
Пример #2
0
/**
 * 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;
	}
}
Пример #3
0
/**
 * 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);
}
Пример #4
0
/**
 * 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);
}
Пример #5
0
/**
 * 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 */
}