summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Provos <provos@gmail.com>2008-05-08 05:56:20 +0000
committerNiels Provos <provos@gmail.com>2008-05-08 05:56:20 +0000
commit3f56e364b76ccc3a688768e92952d08052556120 (patch)
treec7bf34ee5ab15df76f80ce639dc0a37228d68eed
parent3b2022ef3a9eba280b256ac7bbe99f224a8584ad (diff)
downloadlibevent-3f56e364b76ccc3a688768e92952d08052556120.tar.gz
event_base_new_with_config() and related methods
svn:r789
-rw-r--r--ChangeLog1
-rw-r--r--event-internal.h10
-rw-r--r--event.c76
-rw-r--r--include/event2/event.h52
-rw-r--r--test/regress.c23
5 files changed, 159 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index bca7bf80..7e827109 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -92,6 +92,7 @@ Changes in current version:
o turn event_initialized() into a function, and add function equivalents to EVENT_SIGNAL and EVENT_FD so that people don't need to include event_struct.h
o Build test directory correctly with CPPFLAGS set.
o Provide an API for retrieving the supported event mechanisms.
+ o event_base_new_with_config() and corresponding config APIs.
Changes in 1.4.0:
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
diff --git a/event-internal.h b/event-internal.h
index 10fd5d5b..97246ca1 100644
--- a/event-internal.h
+++ b/event-internal.h
@@ -95,6 +95,16 @@ struct event_base {
struct event th_notify;
};
+struct event_config_entry {
+ TAILQ_ENTRY(event_config_entry) (next);
+
+ const char *avoid_method;
+};
+
+struct event_config {
+ TAILQ_HEAD(event_configq, event_config_entry) entries;
+};
+
/* Internal use only: Functions that might be missing from <sys/queue.h> */
#ifndef HAVE_TAILQFOREACH
#define TAILQ_FIRST(head) ((head)->tqh_first)
diff --git a/event.c b/event.c
index 11c91864..2f5ffa93 100644
--- a/event.c
+++ b/event.c
@@ -188,6 +188,26 @@ event_init(void)
struct event_base *
event_base_new(void)
{
+ return (event_base_new_with_config(NULL));
+}
+
+static int
+event_config_is_avoided_method(struct event_config *cfg, const char *method)
+{
+ struct event_config_entry *entry;
+
+ TAILQ_FOREACH(entry, &cfg->entries, next) {
+ if (entry->avoid_method != NULL &&
+ strcmp(entry->avoid_method, method) == 0)
+ return (1);
+ }
+
+ return (0);
+}
+
+struct event_base *
+event_base_new_with_config(struct event_config *cfg)
+{
int i;
struct event_base *base;
@@ -208,6 +228,13 @@ event_base_new(void)
base->evbase = NULL;
for (i = 0; eventops[i] && !base->evbase; i++) {
+ if (cfg != NULL) {
+ /* determine if this backend should be avoided */
+ if (event_config_is_avoided_method(cfg,
+ eventops[i]->name))
+ continue;
+ }
+
base->evsel = eventops[i];
base->evbase = base->evsel->init(base);
@@ -348,6 +375,55 @@ event_supported_methods()
return (methods);
}
+struct event_config *
+event_config_new(void)
+{
+ struct event_config *cfg = mm_malloc(sizeof(*cfg));
+
+ if (cfg == NULL)
+ return (NULL);
+
+ TAILQ_INIT(&cfg->entries);
+
+ return (cfg);
+}
+
+static void
+event_config_entry_free(struct event_config_entry *entry)
+{
+ if (entry->avoid_method != NULL)
+ mm_free((char *)entry->avoid_method);
+ mm_free(entry);
+}
+
+void
+event_config_free(struct event_config *cfg)
+{
+ struct event_config_entry *entry;
+
+ while ((entry = TAILQ_FIRST(&cfg->entries)) != NULL) {
+ TAILQ_REMOVE(&cfg->entries, entry, next);
+ event_config_entry_free(entry);
+ }
+}
+
+int
+event_config_avoid_method(struct event_config *cfg, const char *method)
+{
+ struct event_config_entry *entry = mm_malloc(sizeof(*entry));
+ if (entry == NULL)
+ return (-1);
+
+ if ((entry->avoid_method = mm_strdup(method)) == NULL) {
+ mm_free(entry);
+ return (-1);
+ }
+
+ TAILQ_INSERT_TAIL(&cfg->entries, entry, next);
+
+ return (0);
+}
+
int
event_priority_init(int npriorities)
{
diff --git a/include/event2/event.h b/include/event2/event.h
index 4ceede73..8dff9a7c 100644
--- a/include/event2/event.h
+++ b/include/event2/event.h
@@ -58,6 +58,7 @@ typedef unsigned short u_short;
struct event_base;
struct event;
+struct event_config;
/**
Initialize the event API.
@@ -66,7 +67,8 @@ struct event;
the current_base global. If using only event_base_new(), each event
added must have an event base set with event_base_set()
- @see event_base_set(), event_base_free(), event_init()
+ @see event_base_set(), event_base_free(), event_init(),
+ event_base_new_with_config()
*/
struct event_base *event_base_new(void);
@@ -109,8 +111,52 @@ const char *event_base_get_method(struct event_base *);
error is encountered NULL is returned.
*/
const char **event_supported_methods(void);
-
-
+
+/**
+ Allocates a new event configuration object.
+
+ The event configuration object can be used to change the behavior of
+ an event base.
+
+ @return an event_config object that can be used to store configuration or
+ NULL when an error is encountered.
+*/
+
+struct event_config *event_config_new(void);
+
+/**
+ Deallocates all memory associated with an event configuration object
+
+ @param cfg the event configuration object to be freed.
+*/
+void event_config_free(struct event_config *cfg);
+
+/**
+ Enters an event method that should be avoided into the configuration.
+
+ This can be used to avoid event mechanisms that do not support certain
+ file descriptor types. An application can make use of multiple event
+ bases to accomodate incompatible file descriptor types.
+
+ @param cfg the event configuration object
+ @param method the event method to avoid
+ @return 0 on success, -1 on failure.
+*/
+int event_config_avoid_method(struct event_config *cfg, const char *method);
+
+/**
+ Initialize the event API.
+
+ Use event_base_new_with_config() to initialize a new event base, taking
+ the specified configuration under consideration. The configuration object
+ can currently be used to avoid certain event notification mechanisms.
+
+ @param cfg the event configuration object
+ @return an initialized event_base that can be used to registering events.
+ @see event_base_new(), event_base_free(), event_init(), event_assign()
+*/
+struct event_base *event_base_new_with_config(struct event_config *cfg);
+
/**
Deallocate all memory associated with an event_base, and free the base.
diff --git a/test/regress.c b/test/regress.c
index b8c69f0e..fa5202b0 100644
--- a/test/regress.c
+++ b/test/regress.c
@@ -2070,6 +2070,9 @@ static void
test_methods(void)
{
const char **methods = event_supported_methods();
+ struct event_config *cfg;
+ struct event_base *base;
+ const char *backend;
fprintf(stderr, "Testing supported methods: ");
@@ -2078,11 +2081,31 @@ test_methods(void)
exit(1);
}
+ backend = methods[0];
while (*methods != NULL) {
fprintf(stderr, "%s ", *methods);
++methods;
}
+ cfg = event_config_new();
+ assert(cfg != NULL);
+
+ assert(event_config_avoid_method(cfg, backend) == 0);
+
+ base = event_base_new_with_config(cfg);
+ if (base == NULL) {
+ fprintf(stderr, "FAILED\n");
+ exit(1);
+ }
+
+ if (strcmp(backend, event_base_get_method(base)) == 0) {
+ fprintf(stderr, "FAILED\n");
+ exit(1);
+ }
+
+ event_base_free(base);
+ event_config_free(cfg);
+
fprintf(stderr, "OK\n");
}