int nevents;
int dpfd;
sigset_t evsigmask;
-} devpollop;
+};
void *devpoll_init (void);
int devpoll_add (void *, struct event *);
{
int dpfd, nfiles = NEVENT;
struct rlimit rl;
+ struct devpollop *devpollop;
- /* Disable devpollueue when this environment variable is set */
+ /* Disable devpoll when this environment variable is set */
if (getenv("EVENT_NODEVPOLL"))
return (NULL);
- memset(&devpollop, 0, sizeof(devpollop));
+ if (!(devpollop = calloc(1, sizeof(struct devpollop))))
+ return (NULL);
if (getrlimit(RLIMIT_NOFILE, &rl) == 0 &&
rl.rlim_cur != RLIM_INFINITY)
nfiles = rl.rlim_cur;
- /* Initalize the kernel queue */
-
+ /* Initialize the kernel queue */
if ((dpfd = open("/dev/poll", O_RDWR)) == -1) {
log_error("open: /dev/poll");
+ free(devpollop);
return (NULL);
}
- devpollop.dpfd = dpfd;
+ devpollop->dpfd = dpfd;
- /* Initalize fields */
- devpollop.events = malloc(nfiles * sizeof(struct pollfd));
- if (devpollop.events == NULL)
+ /* Initialize fields */
+ devpollop->events = calloc(nfiles, sizeof(struct pollfd));
+ if (devpollop->events == NULL) {
+ free(devpollop);
+ close(dpfd);
return (NULL);
- devpollop.nevents = nfiles;
+ }
+ devpollop->nevents = nfiles;
- devpollop.fds = calloc(nfiles, sizeof(struct evdevpoll));
- if (devpollop.fds == NULL) {
- free(devpollop.events);
+ devpollop->fds = calloc(nfiles, sizeof(struct evdevpoll));
+ if (devpollop->fds == NULL) {
+ free(devpollop->events);
+ free(devpollop);
+ close(dpfd);
return (NULL);
}
- devpollop.nfds = nfiles;
+ devpollop->nfds = nfiles;
- evsignal_init(&devpollop.evsigmask);
+ evsignal_init(&devpollop->evsigmask);
- return (&devpollop);
+ return (devpollop);
}
int
fd = ev->ev_fd;
if (fd >= devpollop->nfds) {
- /* Extent the file descriptor array as necessary */
+ /* Extend the file descriptor array as necessary */
if (devpoll_recalc(ev->ev_base, devpollop, fd) == -1)
return (-1);
}
}
dpev.fd = fd;
- dpev.events = events | POLLREMOVE;
+ /* dpev.events = events | POLLREMOVE; */
+ dpev.events = POLLREMOVE;
dpev.revents = 0;
if (pwrite(devpollop->dpfd, &dpev, sizeof(dpev), 0) == -1)
int nevents;
int epfd;
sigset_t evsigmask;
-} epollop;
+};
void *epoll_init (void);
int epoll_add (void *, struct event *);
{
int epfd, nfiles = NEVENT;
struct rlimit rl;
+ struct epollop *epollop;
/* Disable epollueue when this environment variable is set */
if (getenv("EVENT_NOEPOLL"))
return (NULL);
- memset(&epollop, 0, sizeof(epollop));
-
if (getrlimit(RLIMIT_NOFILE, &rl) == 0 &&
rl.rlim_cur != RLIM_INFINITY)
nfiles = rl.rlim_cur;
FD_CLOSEONEXEC(epfd);
- epollop.epfd = epfd;
+ if (!(epollop = calloc(1, sizeof(struct epollop))))
+ return (NULL);
+
+ epollop->epfd = epfd;
/* Initalize fields */
- epollop.events = malloc(nfiles * sizeof(struct epoll_event));
- if (epollop.events == NULL)
+ epollop->events = malloc(nfiles * sizeof(struct epoll_event));
+ if (epollop->events == NULL) {
+ free(epollop);
return (NULL);
- epollop.nevents = nfiles;
+ }
+ epollop->nevents = nfiles;
- epollop.fds = calloc(nfiles, sizeof(struct evepoll));
- if (epollop.fds == NULL) {
- free(epollop.events);
+ epollop->fds = calloc(nfiles, sizeof(struct evepoll));
+ if (epollop->fds == NULL) {
+ free(epollop->events);
+ free(epollop);
return (NULL);
}
- epollop.nfds = nfiles;
+ epollop->nfds = nfiles;
- evsignal_init(&epollop.evsigmask);
+ evsignal_init(&epollop->evsigmask);
- return (&epollop);
+ return (epollop);
}
int
if (EVBUFFER_LENGTH(bufev->output)) {
res = evbuffer_write(bufev->output, fd);
if (res == -1) {
- if (errno == EAGAIN || errno == EINTR)
+ if (errno == EAGAIN ||
+ errno == EINTR ||
+ errno == EINPROGRESS)
goto reschedule;
/* error case */
what |= EVBUFFER_ERROR;
.Fn event_del
and does not need to be reinitialized unless the function called and/or
the argument to it are to be changed.
+However, when an
+.Fa ev
+structure has been added to libevent using
+.Fn event_add
+the structure must persist until the event occurs (assuming
+.Fa EV_PERSIST
+is not set) or is removed
+using
+.Fn event_del .
+You may not reuse the same
+.Fa ev
+structure for multiple monitored descriptors; each descriptor
+needs its own
+.Fa ev .
.Pp
The function
.Fn event_add
.Fn event_base_set
and
.Fn event_base_dispatch .
+.Fn event_base_set
+should be called after preparing an event with
+.Fn event_set ,
+as
+.Fn event_set
+assigns the provided event to the most recently created event base.
.Pp
.Sh BUFFERED EVENTS
.Nm libevent
struct kevent *events;
int nevents;
int kq;
-} kqueueop;
+};
void *kq_init (void);
int kq_add (void *, struct event *);
kq_init(void)
{
int kq;
+ struct kqop *kqueueop;
/* Disable kqueue when this environment variable is set */
if (getenv("EVENT_NOKQUEUE"))
return (NULL);
- memset(&kqueueop, 0, sizeof(kqueueop));
+ if (!(kqueueop = calloc(1, sizeof(struct kqop))))
+ return (NULL);
/* Initalize the kernel queue */
if ((kq = kqueue()) == -1) {
log_error("kqueue");
+ free (kqueueop);
return (NULL);
}
- kqueueop.kq = kq;
+ kqueueop->kq = kq;
/* Initalize fields */
- kqueueop.changes = malloc(NEVENT * sizeof(struct kevent));
- if (kqueueop.changes == NULL)
+ kqueueop->changes = malloc(NEVENT * sizeof(struct kevent));
+ if (kqueueop->changes == NULL) {
+ free (kqueueop);
return (NULL);
- kqueueop.events = malloc(NEVENT * sizeof(struct kevent));
- if (kqueueop.events == NULL) {
- free (kqueueop.changes);
+ }
+ kqueueop->events = malloc(NEVENT * sizeof(struct kevent));
+ if (kqueueop->events == NULL) {
+ free (kqueueop);
+ free (kqueueop->changes);
return (NULL);
}
- kqueueop.nevents = NEVENT;
+ kqueueop->nevents = NEVENT;
- return (&kqueueop);
+ return (kqueueop);
}
int
struct pollfd *event_set;
struct event **event_back;
sigset_t evsigmask;
-} pollop;
+};
void *poll_init (void);
int poll_add (void *, struct event *);
void *
poll_init(void)
{
+ struct pollop *pollop;
+
/* Disable kqueue when this environment variable is set */
if (getenv("EVENT_NOPOLL"))
return (NULL);
- memset(&pollop, 0, sizeof(pollop));
+ if (!(pollop = calloc(1, sizeof(struct pollop))))
+ return (NULL);
- evsignal_init(&pollop.evsigmask);
+ evsignal_init(&pollop->evsigmask);
- return (&pollop);
+ return (pollop);
}
/*
fd_set *event_readset;
fd_set *event_writeset;
sigset_t evsigmask;
-} sop;
+};
void *select_init (void);
int select_add (void *, struct event *);
void *
select_init(void)
{
+ struct selectop *sop;
+
/* Disable kqueue when this environment variable is set */
if (getenv("EVENT_NOSELECT"))
return (NULL);
- memset(&sop, 0, sizeof(sop));
+ if (!(sop = calloc(1, sizeof(struct selectop))))
+ return (NULL);
- evsignal_init(&sop.evsigmask);
+ evsignal_init(&sop->evsigmask);
- return (&sop);
+ return (sop);
}
/*