diff --git a/event/API b/event/API index 7c9a0a7550ee2ae477c12e3d7f07159eaab4396b..7ee4ada719f73fbee2423781d9f8e04de1ee0f0e 100644 --- a/event/API +++ b/event/API @@ -232,3 +232,26 @@ the event notification, and DATA is the arbitrary pointer passed to event_subscribe. Returns a pointer to an event subscription structure if the operation is successful, 0 otherwise. + +* event_poll: Poll for new events + + #include <event.h> + + int event_poll(event_handle_t handle); + + Polls for new events. Calls callbacks for all pending events. Does + not block - simply processes events that are currently queued. + +* event_poll_blocking: Poll for new events + + #include <event.h> + + int event_poll_blocking(event_handle_t handle, unsigned int timeout); + + Same as event_poll, but blocks waiting for an event. Times out + after the given amount of time, or doesn't time out if 0 is given. + + IMPORTANT: elvin uses timeouts internally. So, this function does + NOT guarantee that when it returns, either an event has been + recieved or your timeout has passed. This should not be much of + a problem, but you have been warned! diff --git a/event/example/tbrecv.c b/event/example/tbrecv.c index 2192ed9d3c9382c5f2acd17abb669c2307e6833f..992016b7ade1c42d85a2fc9267fbd3b79a9a0c12 100644 --- a/event/example/tbrecv.c +++ b/event/example/tbrecv.c @@ -131,6 +131,16 @@ main(int argc, char **argv) */ event_main(handle); + /* + * Or, we can use a blocking poll like so: + */ + + /* + while (1) { + event_poll_blocking(handle,0); + } + */ + /* * Unregister with the event system: */ diff --git a/event/lib/event.c b/event/lib/event.c index 736a5971dd53d82023982a9de2591c7aa239ccf9..601bac5c90630f06463bfbd672fee6516dae5be9 100644 --- a/event/lib/event.c +++ b/event/lib/event.c @@ -204,31 +204,77 @@ event_unregister(event_handle_t handle) /* - * + * An internal function to handle the two different event_poll calls, without + * making the library user mess around with arguments they don't care about. */ int -event_poll(event_handle_t handle) +internal_event_poll(event_handle_t handle, int blocking, unsigned int timeout) { extern int depth; int rv; + elvin_timeout_t elvin_timeout = NULL; if (!handle->mainloop) { ERROR("multithreaded programs cannot use event_poll\n"); return 0; } + /* + * If the user wants a timeout, set up an elvin timeout now. We just + * use a NULL callback, so that it simply causes a timeout, and doesn't + * actually do anything. + */ + if (timeout) { + elvin_timeout = elvin_sync_add_timeout(NULL, timeout, NULL, + NULL, handle->status); + if (!elvin_timeout) { + ERROR("Elvin elvin_sync_add_timeout failed\n"); + elvin_error_fprintf(stderr, handle->status); + return elvin_error_get_code(handle->status); + } + } + depth++; - rv = elvin_sync_default_select_and_dispatch(0, handle->status); + rv = elvin_sync_default_select_and_dispatch(blocking, handle->status); depth--; if (rv == 0) { ERROR("Elvin select_and_dispatch failed\n"); elvin_error_fprintf(stderr, handle->status); } + /* + * Try to remove the timeout - if it didn't go off, we don't want to + * hit it later. We don't check the return value, since, if it did go + * off (and we don't really have a good way of knowing that), it's not + * there any more, so it looks like an error. + */ + if (timeout && elvin_timeout) { + elvin_error_t error; + elvin_sync_remove_timeout(elvin_timeout, error); + } + return elvin_error_get_code(handle->status); } +/* + * A non-blocking poll of the event system + */ + +int +event_poll(event_handle_t handle) +{ + return internal_event_poll(handle,0,0); +} + +/* + * A blocking poll of the event system, with an optional timeout + */ + +int event_poll_blocking(event_handle_t handle, unsigned int timeout) +{ + return internal_event_poll(handle,1,timeout); +} /* * Enter the main loop of the event system, waiting to receive event diff --git a/event/lib/event.h b/event/lib/event.h index 13679e8bfce869182ab8154c811ee6dcc1316767..f83b5767c631f2b217a32c1a2464b9c64013ec0b 100644 --- a/event/lib/event.h +++ b/event/lib/event.h @@ -142,6 +142,7 @@ typedef void (*event_notify_callback_t)(event_handle_t handle, event_handle_t event_register(char *name, int threaded); int event_unregister(event_handle_t handle); int event_poll(event_handle_t handle); +int event_poll_blocking(event_handle_t handle, unsigned int timeout); int event_main(event_handle_t handle); int event_notify(event_handle_t handle, event_notification_t notification); int event_schedule(event_handle_t handle, event_notification_t notification,