Skip to content

Commit

Permalink
Add new functions to access backends by their features and to query t…
Browse files Browse the repository at this point in the history
…he features of a backend.

svn:r842
  • Loading branch information
nmathewson committed May 31, 2008
1 parent 9515c80 commit 0596592
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 15 deletions.
2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ Changes in current version:
o constify struct timeval * where possible
o make event_get_supported_methods obey environment variables
o support for edge-triggered events on epoll and kqueue backends: patch from Valery Kholodkov
o support for selecting event backends by their features, and for querying the features of a backend.
o change failing behavior of event_base_new_with_config: if a config is provided and no backend is selected, return NULL instead of aborting.


Changes in 1.4.0:
Expand Down
3 changes: 2 additions & 1 deletion WIN32-Code/win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ struct eventop win32ops = {
win32_del,
win32_dispatch,
win32_dealloc,
0
0, /* doesn't need reinit */
0, /* No features supported. */
};

#define FD_SET_ALLOC_SIZE(n) ((sizeof(struct win_fd_set) + ((n)-1)*sizeof(SOCKET)))
Expand Down
3 changes: 2 additions & 1 deletion devpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ struct eventop devpollops = {
devpoll_del,
devpoll_dispatch,
devpoll_dealloc,
1 /* need reinit */
1, /* need reinit */
EV_FEATURE_FDS|EV_FEATURE_O1,
};

#define NEVENT 32000
Expand Down
3 changes: 2 additions & 1 deletion epoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ struct eventop epollops = {
epoll_del,
epoll_dispatch,
epoll_dealloc,
1 /* need reinit */
1, /* need reinit */
EV_FEATURE_ET|EV_FEATURE_O1,
};

#ifdef HAVE_SETFD
Expand Down
3 changes: 3 additions & 0 deletions event-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct eventop {
void (*dealloc)(struct event_base *, void *);
/* set if we need to reinitialize the event base */
int need_reinit;
enum event_method_feature features;
};

struct event_base {
Expand Down Expand Up @@ -103,6 +104,8 @@ struct event_config_entry {

struct event_config {
TAILQ_HEAD(event_configq, event_config_entry) entries;

enum event_method_feature require_features;
};

/* Internal use only: Functions that might be missing from <sys/queue.h> */
Expand Down
41 changes: 33 additions & 8 deletions event.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,12 @@ event_is_method_disabled(const char *name)
for (i = 8; environment[i] != '\0'; ++i)
environment[i] = toupper(environment[i]);
return (getenv(environment) != NULL);

}

enum event_method_feature
event_base_get_features(struct event_base *base)
{
return base->evsel->features;
}

struct event_base *
Expand All @@ -236,20 +241,23 @@ event_base_new_with_config(struct event_config *cfg)

detect_monotonic();
gettime(base, &base->event_tv);

min_heap_ctor(&base->timeheap);
TAILQ_INIT(&base->eventqueue);
TAILQ_INIT(&base->sig.signalqueue);
base->sig.ev_signal_pair[0] = -1;
base->sig.ev_signal_pair[1] = -1;

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;
if ((eventops[i]->features & cfg->require_features)
!= cfg->require_features)
continue;
}

/* also obey the environment variables */
Expand All @@ -261,10 +269,16 @@ event_base_new_with_config(struct event_config *cfg)
base->evbase = base->evsel->init(base);
}

if (base->evbase == NULL)
event_errx(1, "%s: no event mechanism available", __func__);
if (base->evbase == NULL) {
if (cfg == NULL)
event_errx(1, "%s: no event mechanism available", __func__);
else {
event_base_free(base);
return NULL;
}
}

if (getenv("EVENT_SHOW_METHOD"))
if (getenv("EVENT_SHOW_METHOD"))
event_msgx("libevent using: %s", base->evsel->name);

/* allocate a single active event queue */
Expand Down Expand Up @@ -397,7 +411,7 @@ event_get_supported_methods(void)
mm_free(methods);

methods = tmp;

return (methods);
}

Expand All @@ -410,7 +424,8 @@ event_config_new(void)
return (NULL);

TAILQ_INIT(&cfg->entries);

cfg->require_features = 0;

return (cfg);
}

Expand Down Expand Up @@ -450,6 +465,16 @@ event_config_avoid_method(struct event_config *cfg, const char *method)
return (0);
}

int
event_config_require_features(struct event_config *cfg,
enum event_method_feature features)
{
if (!cfg)
return (-1);
cfg->require_features = features;
return (0);
}

int
event_priority_init(int npriorities)
{
Expand Down
45 changes: 44 additions & 1 deletion include/event2/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ int event_base_dispatch(struct event_base *);
*/
const char *event_base_get_method(struct event_base *);

/**
Return a bitmask of the features implemented by an event base.
*/
enum event_method_feature event_base_get_features(struct event_base *base);

/**
Gets all event notification mechanisms supported by libevent.
Expand Down Expand Up @@ -144,6 +149,43 @@ void event_config_free(struct event_config *cfg);
*/
int event_config_avoid_method(struct event_config *cfg, const char *method);

enum event_method_feature {
/* Require an event method that allows edge-triggered events with EV_ET. */
EV_FEATURE_ET = 0x01,
/* Require an event method where having one event triggered among
* many is [approximately] an O(1) operation. This excludes (for
* example) select and poll, which are approximately O(N) for N
* equal to the total number of possible events. */
EV_FEATURE_O1 = 0x02,
/* Require an event method that allows file descriptors as well as
* sockets. */
EV_FEATURE_FDS = 0x04,
} event_method_feature;

/**
Enters a required event method feature that the application demands.
Note that not every feature or combination of features is supported
on every platform. Code that requests features should be prepared
to handle the case where event_base_new_with_config() returns NULL, as in:
<pre>
event_config_require_features(cfg, EV_FEATURE_ET);
base = event_base_new_with_config(cfg);
if (base == NULL) {
// We can't get edge-triggered behavior here.
event_config_require_features(cfg, 0);
base = event_base_new_with_config(cfg);
}
</pre>
@param cfg the event configuration object
@param feature a bitfield of one or more event_method_feature values.
Replaces values from previous calls to this function.
@return 0 on success, -1 on failure.
*/
int event_config_require_features(struct event_config *cfg,
enum event_method_feature feature);

/**
Initialize the event API.
Expand All @@ -152,7 +194,8 @@ int event_config_avoid_method(struct event_config *cfg, const char *method);
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.
@return an initialized event_base that can be used to registering events,
or NULL if no event base can be created with the requested event_config.
@see event_base_new(), event_base_free(), event_init(), event_assign()
*/
struct event_base *event_base_new_with_config(struct event_config *cfg);
Expand Down
3 changes: 2 additions & 1 deletion kqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ const struct eventop kqops = {
kq_del,
kq_dispatch,
kq_dealloc,
1 /* need reinit */
1 /* need reinit */,
EV_FEATURE_ET|EV_FEATURE_O1|EV_FEATURE_FDS,
};

static void *
Expand Down
3 changes: 2 additions & 1 deletion poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ const struct eventop pollops = {
poll_del,
poll_dispatch,
poll_dealloc,
0
0, /* doesn't need_reinit */
EV_FEATURE_FDS,
};

static void *
Expand Down
3 changes: 2 additions & 1 deletion select.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ const struct eventop selectops = {
select_del,
select_dispatch,
select_dealloc,
0
0, /* doesn't need reinit. */
EV_FEATURE_FDS,
};

static int select_resize(struct selectop *sop, int fdsz);
Expand Down

0 comments on commit 0596592

Please sign in to comment.