mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-12 22:10:12 -04:00
Add new functions to access backends by their features and to query the features of a backend.
svn:r842
This commit is contained in:
parent
9515c8076e
commit
05965921ab
@ -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:
|
||||
|
@ -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)))
|
||||
|
@ -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
|
||||
|
3
epoll.c
3
epoll.c
@ -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
|
||||
|
@ -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 {
|
||||
@ -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> */
|
||||
|
41
event.c
41
event.c
@ -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 *
|
||||
@ -236,13 +241,13 @@ 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) {
|
||||
@ -250,6 +255,9 @@ event_base_new_with_config(struct event_config *cfg)
|
||||
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 */
|
||||
@ -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 */
|
||||
@ -397,7 +411,7 @@ event_get_supported_methods(void)
|
||||
mm_free(methods);
|
||||
|
||||
methods = tmp;
|
||||
|
||||
|
||||
return (methods);
|
||||
}
|
||||
|
||||
@ -410,7 +424,8 @@ event_config_new(void)
|
||||
return (NULL);
|
||||
|
||||
TAILQ_INIT(&cfg->entries);
|
||||
|
||||
cfg->require_features = 0;
|
||||
|
||||
return (cfg);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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);
|
||||
|
3
kqueue.c
3
kqueue.c
@ -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 *
|
||||
|
3
poll.c
3
poll.c
@ -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 *
|
||||
|
Loading…
x
Reference in New Issue
Block a user