event_handle_t * event_register( event_id_t data, event_type_t type, event_fn_t fn, void *arg) { event_handle_t *handle; GIOCondition cond; /* sanity-checking */ if ((type == EV_READFD) || (type == EV_WRITEFD)) { /* make sure we aren't given a high fd that will overflow a fd_set */ if (data >= (int)FD_SETSIZE) { error(_("event_register: Invalid file descriptor %jd"), data); /*NOTREACHED*/ } } else if (type == EV_TIME) { if (data <= 0) { error(_("event_register: interval for EV_TIME must be greater than 0; got %jd"), data); } } handle = g_new0(event_handle_t, 1); handle->fn = fn; handle->arg = arg; handle->type = type; handle->data = data; handle->is_dead = FALSE; event_debug(1, _("event: register: %p->data=%jd, type=%s\n"), handle, handle->data, event_type2str(handle->type)); /* add to the list of events */ all_events = g_slist_prepend(all_events, (gpointer)handle); /* and set up the GSource for this event */ switch (type) { case EV_READFD: case EV_WRITEFD: /* create a new source */ if (type == EV_READFD) { cond = G_IO_IN | G_IO_HUP | G_IO_ERR; } else { cond = G_IO_OUT | G_IO_ERR; } handle->source = new_fdsource(data, cond); /* attach it to the default GMainLoop */ g_source_attach(handle->source, NULL); handle->source_id = g_source_get_id(handle->source); /* And set its callbacks */ g_source_set_callback(handle->source, event_handle_callback, (gpointer)handle, NULL); /* drop our reference to it, so when it's detached, it will be * destroyed. */ g_source_unref(handle->source); break; case EV_TIME: /* Glib provides a nice shortcut for timeouts. The *1000 converts * seconds to milliseconds. */ handle->source_id = g_timeout_add(data * 1000, event_handle_callback, (gpointer)handle); /* But it doesn't give us the source directly.. */ handle->source = g_main_context_find_source_by_id(NULL, handle->source_id); /* EV_TIME must always be handled after EV_READ */ g_source_set_priority(handle->source, 10); break; case EV_WAIT: /* nothing to do -- these are handled independently of GMainLoop */ break; default: error(_("Unknown event type %s"), event_type2str(type)); } return handle; }
void event_activate( event_handle_t *handle) { GIOCondition cond; assert(handle != NULL); g_static_mutex_lock(&event_mutex); /* add to the list of events */ all_events = g_slist_prepend(all_events, (gpointer)handle); /* and set up the GSource for this event */ switch (handle->type) { case EV_READFD: case EV_WRITEFD: /* create a new source */ if (handle->type == EV_READFD) { cond = G_IO_IN | G_IO_HUP | G_IO_ERR; } else { cond = G_IO_OUT | G_IO_ERR; } handle->source = new_fdsource(handle->data, cond); /* attach it to the default GMainLoop */ g_source_attach(handle->source, NULL); handle->source_id = g_source_get_id(handle->source); /* And set its callbacks */ g_source_set_callback(handle->source, event_handle_callback, (gpointer)handle, NULL); /* drop our reference to it, so when it's detached, it will be * destroyed. */ g_source_unref(handle->source); break; case EV_TIME: /* Glib provides a nice shortcut for timeouts. The *1000 converts * seconds to milliseconds. */ handle->source_id = g_timeout_add(handle->data * 1000, event_handle_callback, (gpointer)handle); /* But it doesn't give us the source directly.. */ handle->source = g_main_context_find_source_by_id(NULL, handle->source_id); /* EV_TIME must always be handled after EV_READ */ g_source_set_priority(handle->source, 10); break; case EV_WAIT: /* nothing to do -- these are handled independently of GMainLoop */ break; default: error(_("Unknown event type %s"), event_type2str(handle->type)); } g_static_mutex_unlock(&event_mutex); return; }