libtests/Makefile
cgi/Makefile
libtests/index.html
+libtests/t-eventdist
dateparse.c dateparse.h xgetdate.c \
defs.c defs.h \
eclient.c eclient.h \
+ eventdist.c eventdist.h \
event.c event.h \
eventlog.c eventlog.h \
filepart.c filepart.h \
--- /dev/null
+/*
+ * This file is part of DisOrder
+ * Copyright (C) 2008 Richard Kettlewell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include "common.h"
+
+#include "mem.h"
+#include "eventdist.h"
+#include "hash.h"
+
+struct event_data {
+ struct event_data *next;
+ const char *event;
+ event_handler *callback;
+ void *callbackdata;
+};
+
+static hash *events;
+
+/** @brief Register an event handler
+ * @param event Event type to handle
+ * @param callback Function to call when event occurs
+ * @param callbackdata Passed to @p callback
+ * @return Handle for this registration (for use with event_cancel())
+ */
+event_handle event_register(const char *event,
+ event_handler *callback,
+ void *callbackdata) {
+ static const struct event_data *null;
+ struct event_data *ed = xmalloc(sizeof *ed), **head;
+
+ if(!events)
+ events = hash_new(sizeof (struct event_data *));
+ if(!(head = hash_find(events, event))) {
+ hash_add(events, event, &null, HASH_INSERT);
+ head = hash_find(events, event);
+ }
+ ed->next = *head;
+ ed->event = xstrdup(event);
+ ed->callback = callback;
+ ed->callbackdata = callbackdata;
+ *head = ed;
+ return ed;
+}
+
+/** @brief Stop handling an event
+ * @param handle Registration to cancel (as returned from event_register())
+ *
+ * @p handle is allowed to be NULL.
+ */
+void event_cancel(event_handle handle) {
+ struct event_data **head, **edp;
+
+ if(!handle)
+ return;
+ assert(events);
+ head = hash_find(events, handle->event);
+ for(edp = head; *edp && *edp != handle; edp = &(*edp)->next)
+ ;
+ assert(*edp == handle);
+ *edp = handle->next;
+}
+
+/** @brief Raise an event
+ * @param event Event type to raise
+ * @param eventdata Event-specific data
+ */
+void event_raise(const char *event,
+ void *eventdata) {
+ struct event_data *ed, **head;
+ if(!events)
+ return;
+ if(!(head = hash_find(events, event)))
+ return;
+ for(ed = *head; ed; ed = ed->next)
+ ed->callback(event, eventdata, ed->callbackdata);
+}
+
+/*
+Local Variables:
+c-basic-offset:2
+comment-column:40
+fill-column:79
+indent-tabs-mode:nil
+End:
+*/
--- /dev/null
+/*
+ * This file is part of DisOrder
+ * Copyright (C) 2008 Richard Kettlewell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#ifndef EVENTDIST_H
+#define EVENTDIST_H
+
+/** @brief Signature for event handlers
+ * @param event Event type
+ * @param eventdata Event-specific data
+ * @param callbackdata Handler-specific data (as passed to event_register())
+ */
+typedef void event_handler(const char *event,
+ void *eventdata,
+ void *callbackdata);
+
+/** @brief Handle identifying an event monitor */
+typedef struct event_data *event_handle;
+
+event_handle event_register(const char *event,
+ event_handler *callback,
+ void *callbackdata);
+void event_cancel(event_handle handle);
+void event_raise(const char *event,
+ void *eventdata);
+
+#endif /* EVENTDIST_H */
+
+/*
+Local Variables:
+c-basic-offset:2
+comment-column:40
+fill-column:79
+indent-tabs-mode:nil
+End:
+*/
t-cookies t-dateparse t-event t-filepart t-hash t-heap t-hex \
t-kvp t-mime t-printf t-regsub t-selection t-signame t-sink \
t-split t-syscalls t-trackname t-unicode t-url t-utf8 t-vector \
- t-words t-wstat t-macros t-cgi
+ t-words t-wstat t-macros t-cgi t-eventdist
noinst_PROGRAMS=$(TESTS)
t_vector_SOURCES=t-vector.c test.c test.h
t_words_SOURCES=t-words.c test.c test.h
t_wstat_SOURCES=t-wstat.c test.c test.h
+t_eventdist_SOURCES=t-eventdist.c test.c test.h
check-report: before-check check make-coverage-reports
before-check:
--- /dev/null
+/*
+ * This file is part of DisOrder.
+ * Copyright (C) 2008 Richard Kettlewell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+#include "test.h"
+#include "eventdist.h"
+
+static int wibbles, wobbles, wobble2s;
+
+static void on_wibble(const char *event, void *eventdata, void *callbackdata) {
+ check_string(event, "wibble");
+ check_string(eventdata, "wibble_eventdata");
+ check_string(callbackdata, "wibble_data");
+ ++wibbles;
+}
+
+static void on_wobble(const char *event, void *eventdata, void *callbackdata) {
+ check_string(event, "wobble");
+ check_string(eventdata, "wobble_eventdata");
+ check_string(callbackdata, "wobble_data");
+ ++wobbles;
+}
+
+static void on_wobble2(const char *event, void *eventdata, void *callbackdata) {
+ check_string(event, "wobble");
+ check_string(eventdata, "wobble_eventdata");
+ check_string(callbackdata, "wobble2_data");
+ ++wobble2s;
+}
+
+static void test_eventdist(void) {
+ event_handle wibble_handle, wobble_handle, wobble2_handle;
+ /* Raising unregistered events should be safe */
+ event_raise("wibble", NULL);
+ ++tests;
+
+ wibble_handle = event_register("wibble", on_wibble, (void *)"wibble_data");
+ wobble_handle = event_register("wobble", on_wobble, (void *)"wobble_data");
+ wobble2_handle = event_register("wobble", on_wobble2, (void *)"wobble2_data");
+ event_raise("wibble", (void *) "wibble_eventdata");
+ check_integer(wibbles, 1);
+ check_integer(wobbles, 0);
+ check_integer(wobble2s, 0);
+
+ event_raise("wobble", (void *)"wobble_eventdata");
+ check_integer(wibbles, 1);
+ check_integer(wobbles, 1);
+ check_integer(wobble2s, 1);
+
+ event_raise("wobble", (void *)"wobble_eventdata");
+ check_integer(wibbles, 1);
+ check_integer(wobbles, 2);
+ check_integer(wobble2s, 2);
+
+ event_cancel(wobble_handle);
+
+ event_raise("wibble", (void *)"wibble_eventdata");
+ check_integer(wibbles, 2);
+ check_integer(wobbles, 2);
+ check_integer(wobble2s, 2);
+
+ event_raise("wobble", (void *)"wobble_eventdata");
+ check_integer(wibbles, 2);
+ check_integer(wobbles, 2);
+ check_integer(wobble2s, 3);
+}
+
+TEST(eventdist);
+
+/*
+Local Variables:
+c-basic-offset:2
+comment-column:40
+fill-column:79
+indent-tabs-mode:nil
+End:
+*/