summaryrefslogtreecommitdiff
path: root/src/libmowgli/eventloop/eventloop.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmowgli/eventloop/eventloop.h')
-rw-r--r--src/libmowgli/eventloop/eventloop.h259
1 files changed, 259 insertions, 0 deletions
diff --git a/src/libmowgli/eventloop/eventloop.h b/src/libmowgli/eventloop/eventloop.h
new file mode 100644
index 0000000..4c07b27
--- /dev/null
+++ b/src/libmowgli/eventloop/eventloop.h
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2011, 2012 William Pitcock <nenolod@dereferenced.org>.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MOWGLI_EVENTLOOP_EVENTLOOP_H__
+#define __MOWGLI_EVENTLOOP_EVENTLOOP_H__
+
+#ifndef _WIN32
+
+typedef int mowgli_descriptor_t;
+
+#else
+
+typedef SOCKET mowgli_descriptor_t;
+
+#endif
+
+typedef enum {
+ MOWGLI_EVENTLOOP_TYPE_POLLABLE,
+ MOWGLI_EVENTLOOP_TYPE_HELPER,
+ MOWGLI_EVENTLOOP_TYPE_ERROR = -1
+} mowgli_eventloop_io_type_t;
+
+typedef struct {
+ mowgli_eventloop_io_type_t type;
+} mowgli_eventloop_io_obj_t;
+
+typedef struct _mowgli_eventloop mowgli_eventloop_t;
+
+typedef struct _mowgli_pollable mowgli_eventloop_pollable_t;
+typedef struct _mowgli_helper mowgli_eventloop_helper_proc_t;
+
+typedef struct _mowgli_linebuf mowgli_linebuf_t;
+
+typedef enum {
+ MOWGLI_EVENTLOOP_IO_READ,
+ MOWGLI_EVENTLOOP_IO_WRITE,
+ MOWGLI_EVENTLOOP_IO_ERROR = -1
+} mowgli_eventloop_io_dir_t;
+
+typedef void mowgli_eventloop_io_t;
+
+/* checked casts */
+static inline mowgli_eventloop_pollable_t *mowgli_eventloop_io_pollable(mowgli_eventloop_io_t *io)
+{
+ mowgli_eventloop_io_obj_t *obj = (mowgli_eventloop_io_obj_t *) io;
+
+ return_val_if_fail(io != NULL, NULL);
+ return_val_if_fail(obj->type == MOWGLI_EVENTLOOP_TYPE_POLLABLE, NULL);
+
+ return (mowgli_eventloop_pollable_t *) io;
+}
+
+static inline mowgli_eventloop_helper_proc_t *mowgli_eventloop_io_helper(mowgli_eventloop_io_t *io)
+{
+ mowgli_eventloop_io_obj_t *obj = (mowgli_eventloop_io_obj_t *) io;
+
+ return_val_if_fail(io != NULL, NULL);
+ return_val_if_fail(obj->type == MOWGLI_EVENTLOOP_TYPE_HELPER, NULL);
+
+ return (mowgli_eventloop_helper_proc_t *) io;
+}
+
+static inline mowgli_eventloop_io_type_t mowgli_eventloop_io_type(mowgli_eventloop_io_t *io)
+{
+ mowgli_eventloop_io_obj_t *obj = (mowgli_eventloop_io_obj_t *) io;
+
+ return_val_if_fail(io != NULL, MOWGLI_EVENTLOOP_TYPE_ERROR);
+
+ return obj->type;
+}
+
+typedef void mowgli_eventloop_io_cb_t(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata);
+
+struct _mowgli_pollable {
+ mowgli_eventloop_io_obj_t type;
+
+ mowgli_descriptor_t fd;
+ unsigned int slot;
+ unsigned int events;
+
+ mowgli_eventloop_io_cb_t *read_function;
+ mowgli_eventloop_io_cb_t *write_function;
+ mowgli_eventloop_io_cb_t *error_function;
+
+ void *userdata;
+
+ mowgli_node_t node;
+
+ mowgli_eventloop_t *eventloop;
+};
+
+typedef struct {
+ void (*timeout_once)(mowgli_eventloop_t *eventloop, int timeout);
+ void (*run_once)(mowgli_eventloop_t *eventloop);
+ void (*pollsetup)(mowgli_eventloop_t *eventloop);
+ void (*pollshutdown)(mowgli_eventloop_t *eventloop);
+ void (*setselect)(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function);
+ void (*select)(mowgli_eventloop_t *eventloop, int time);
+ void (*destroy)(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable);
+} mowgli_eventloop_ops_t;
+
+struct _mowgli_eventloop {
+ time_t currtime;
+ time_t deadline;
+
+ const char *last_ran;
+
+ mowgli_list_t timer_list;
+ mowgli_mutex_t mutex;
+
+ mowgli_eventloop_ops_t *eventloop_ops;
+ void *poller;
+
+ bool death_requested;
+
+ void *data;
+};
+
+typedef void mowgli_event_dispatch_func_t(void *userdata);
+
+typedef struct {
+ mowgli_node_t node;
+
+ mowgli_event_dispatch_func_t *func;
+ void *arg;
+ const char *name;
+ time_t frequency;
+ time_t when;
+ bool active;
+} mowgli_eventloop_timer_t;
+
+static inline void mowgli_eventloop_set_time(mowgli_eventloop_t *eventloop, time_t newtime)
+{
+ return_if_fail(eventloop != NULL);
+
+ eventloop->currtime = newtime;
+}
+
+static inline time_t mowgli_eventloop_get_time(mowgli_eventloop_t *eventloop)
+{
+ return_val_if_fail(eventloop != NULL, 0);
+
+ return eventloop->currtime;
+}
+
+static inline void mowgli_eventloop_synchronize(mowgli_eventloop_t *eventloop)
+{
+ mowgli_eventloop_set_time(eventloop, time(NULL));
+}
+
+static inline bool mowgli_eventloop_ignore_errno(int error)
+{
+ switch (error)
+ {
+#ifdef EINPROGRESS
+ case EINPROGRESS:
+#endif
+#if defined(EWOULDBLOCK)
+ case EWOULDBLOCK:
+#endif
+#if defined(EAGAIN) && (EWOULDBLOCK != EAGAIN)
+ case EAGAIN:
+#endif
+#ifdef EINTR
+ case EINTR:
+#endif
+#ifdef ERESTART
+ case ERESTART:
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS:
+#endif
+#ifdef ENOENT
+ case ENOENT:
+#endif
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+typedef void mowgli_eventloop_helper_start_fn_t(mowgli_eventloop_helper_proc_t *helper, void *userdata);
+
+struct _mowgli_helper {
+ mowgli_eventloop_io_obj_t type;
+
+ mowgli_process_t *child;
+ mowgli_eventloop_t *eventloop;
+
+ mowgli_descriptor_t fd;
+ mowgli_eventloop_pollable_t *pfd;
+
+ mowgli_eventloop_io_cb_t *read_function;
+
+ void *userdata;
+};
+
+/* helper.c */
+extern mowgli_eventloop_helper_proc_t *mowgli_helper_create(mowgli_eventloop_t *eventloop, mowgli_eventloop_helper_start_fn_t *start_fn, const char *helpername, void *userdata);
+
+/* creation of helpers inside other executable images */
+extern mowgli_eventloop_helper_proc_t *mowgli_helper_spawn(mowgli_eventloop_t *eventloop, const char *path, char *const argv[]);
+extern mowgli_eventloop_helper_proc_t *mowgli_helper_setup(mowgli_eventloop_t *eventloop);
+
+/* synchronization of helpers happens on reading from mowgli_eventloop_helper_proc_t::in_pfd. */
+extern void mowgli_helper_set_read_cb(mowgli_eventloop_t *eventloop, mowgli_eventloop_helper_proc_t *helper, mowgli_eventloop_io_cb_t *read_fn);
+extern void mowgli_helper_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_helper_proc_t *helper);
+
+/* null_pollops.c */
+extern void mowgli_simple_eventloop_run_once(mowgli_eventloop_t *eventloop);
+extern void mowgli_simple_eventloop_timeout_once(mowgli_eventloop_t *eventloop, int timeout);
+extern void mowgli_simple_eventloop_error_handler(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata);
+
+/* eventloop.c */
+extern mowgli_eventloop_t *mowgli_eventloop_create(void);
+extern void mowgli_eventloop_destroy(mowgli_eventloop_t *eventloop);
+extern void mowgli_eventloop_run(mowgli_eventloop_t *eventloop);
+extern void mowgli_eventloop_run_once(mowgli_eventloop_t *eventloop);
+extern void mowgli_eventloop_timeout_once(mowgli_eventloop_t *eventloop, int timeout);
+extern void mowgli_eventloop_break(mowgli_eventloop_t *eventloop);
+extern void mowgli_eventloop_timers_only(mowgli_eventloop_t *eventloop);
+extern void mowgli_eventloop_set_data(mowgli_eventloop_t *eventloop, void *data);
+extern void *mowgli_eventloop_get_data(mowgli_eventloop_t *eventloop);
+
+/* timer.c */
+extern mowgli_eventloop_timer_t *mowgli_timer_add(mowgli_eventloop_t *eventloop, const char *name, mowgli_event_dispatch_func_t *func, void *arg, time_t when);
+extern mowgli_eventloop_timer_t *mowgli_timer_add_once(mowgli_eventloop_t *eventloop, const char *name, mowgli_event_dispatch_func_t *func, void *arg, time_t when);
+extern void mowgli_timer_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_timer_t *timer);
+extern void mowgli_eventloop_run_timers(mowgli_eventloop_t *eventloop);
+extern time_t mowgli_eventloop_next_timer(mowgli_eventloop_t *eventloop);
+extern mowgli_eventloop_timer_t *mowgli_timer_find(mowgli_eventloop_t *eventloop, mowgli_event_dispatch_func_t *func, void *arg);
+
+/* pollable.c */
+extern mowgli_eventloop_pollable_t *mowgli_pollable_create(mowgli_eventloop_t *eventloop, mowgli_descriptor_t fd, void *userdata);
+extern void mowgli_pollable_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable);
+extern void mowgli_pollable_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function);
+extern void mowgli_pollable_set_nonblocking(mowgli_eventloop_pollable_t *pollable, bool nonblocking);
+
+#endif
+