mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-09 12:28:19 -04:00
fixes for threaded operations from Andrew Danforth
svn:r129
This commit is contained in:
parent
bd6999b4a2
commit
3ba224dbd5
48
devpoll.c
48
devpoll.c
@ -74,7 +74,7 @@ struct devpollop {
|
|||||||
int nevents;
|
int nevents;
|
||||||
int dpfd;
|
int dpfd;
|
||||||
sigset_t evsigmask;
|
sigset_t evsigmask;
|
||||||
} devpollop;
|
};
|
||||||
|
|
||||||
void *devpoll_init (void);
|
void *devpoll_init (void);
|
||||||
int devpoll_add (void *, struct event *);
|
int devpoll_add (void *, struct event *);
|
||||||
@ -98,42 +98,49 @@ devpoll_init(void)
|
|||||||
{
|
{
|
||||||
int dpfd, nfiles = NEVENT;
|
int dpfd, nfiles = NEVENT;
|
||||||
struct rlimit rl;
|
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"))
|
if (getenv("EVENT_NODEVPOLL"))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
memset(&devpollop, 0, sizeof(devpollop));
|
if (!(devpollop = calloc(1, sizeof(struct devpollop))))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
if (getrlimit(RLIMIT_NOFILE, &rl) == 0 &&
|
if (getrlimit(RLIMIT_NOFILE, &rl) == 0 &&
|
||||||
rl.rlim_cur != RLIM_INFINITY)
|
rl.rlim_cur != RLIM_INFINITY)
|
||||||
nfiles = rl.rlim_cur;
|
nfiles = rl.rlim_cur;
|
||||||
|
|
||||||
/* Initalize the kernel queue */
|
/* Initialize the kernel queue */
|
||||||
|
|
||||||
if ((dpfd = open("/dev/poll", O_RDWR)) == -1) {
|
if ((dpfd = open("/dev/poll", O_RDWR)) == -1) {
|
||||||
log_error("open: /dev/poll");
|
log_error("open: /dev/poll");
|
||||||
|
free(devpollop);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
devpollop.dpfd = dpfd;
|
devpollop->dpfd = dpfd;
|
||||||
|
|
||||||
/* Initalize fields */
|
/* Initialize fields */
|
||||||
devpollop.events = malloc(nfiles * sizeof(struct pollfd));
|
devpollop->events = calloc(nfiles, sizeof(struct pollfd));
|
||||||
if (devpollop.events == NULL)
|
if (devpollop->events == NULL) {
|
||||||
return (NULL);
|
free(devpollop);
|
||||||
devpollop.nevents = nfiles;
|
close(dpfd);
|
||||||
|
|
||||||
devpollop.fds = calloc(nfiles, sizeof(struct evdevpoll));
|
|
||||||
if (devpollop.fds == NULL) {
|
|
||||||
free(devpollop.events);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
devpollop.nfds = nfiles;
|
devpollop->nevents = nfiles;
|
||||||
|
|
||||||
evsignal_init(&devpollop.evsigmask);
|
devpollop->fds = calloc(nfiles, sizeof(struct evdevpoll));
|
||||||
|
if (devpollop->fds == NULL) {
|
||||||
|
free(devpollop->events);
|
||||||
|
free(devpollop);
|
||||||
|
close(dpfd);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
devpollop->nfds = nfiles;
|
||||||
|
|
||||||
return (&devpollop);
|
evsignal_init(&devpollop->evsigmask);
|
||||||
|
|
||||||
|
return (devpollop);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -254,7 +261,7 @@ devpoll_add(void *arg, struct event *ev)
|
|||||||
|
|
||||||
fd = ev->ev_fd;
|
fd = ev->ev_fd;
|
||||||
if (fd >= devpollop->nfds) {
|
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)
|
if (devpoll_recalc(ev->ev_base, devpollop, fd) == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
@ -326,7 +333,8 @@ devpoll_del(void *arg, struct event *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dpev.fd = fd;
|
dpev.fd = fd;
|
||||||
dpev.events = events | POLLREMOVE;
|
/* dpev.events = events | POLLREMOVE; */
|
||||||
|
dpev.events = POLLREMOVE;
|
||||||
dpev.revents = 0;
|
dpev.revents = 0;
|
||||||
|
|
||||||
if (pwrite(devpollop->dpfd, &dpev, sizeof(dpev), 0) == -1)
|
if (pwrite(devpollop->dpfd, &dpev, sizeof(dpev), 0) == -1)
|
||||||
|
35
epoll.c
35
epoll.c
@ -76,7 +76,7 @@ struct epollop {
|
|||||||
int nevents;
|
int nevents;
|
||||||
int epfd;
|
int epfd;
|
||||||
sigset_t evsigmask;
|
sigset_t evsigmask;
|
||||||
} epollop;
|
};
|
||||||
|
|
||||||
void *epoll_init (void);
|
void *epoll_init (void);
|
||||||
int epoll_add (void *, struct event *);
|
int epoll_add (void *, struct event *);
|
||||||
@ -109,13 +109,12 @@ epoll_init(void)
|
|||||||
{
|
{
|
||||||
int epfd, nfiles = NEVENT;
|
int epfd, nfiles = NEVENT;
|
||||||
struct rlimit rl;
|
struct rlimit rl;
|
||||||
|
struct epollop *epollop;
|
||||||
|
|
||||||
/* Disable epollueue when this environment variable is set */
|
/* Disable epollueue when this environment variable is set */
|
||||||
if (getenv("EVENT_NOEPOLL"))
|
if (getenv("EVENT_NOEPOLL"))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
memset(&epollop, 0, sizeof(epollop));
|
|
||||||
|
|
||||||
if (getrlimit(RLIMIT_NOFILE, &rl) == 0 &&
|
if (getrlimit(RLIMIT_NOFILE, &rl) == 0 &&
|
||||||
rl.rlim_cur != RLIM_INFINITY)
|
rl.rlim_cur != RLIM_INFINITY)
|
||||||
nfiles = rl.rlim_cur;
|
nfiles = rl.rlim_cur;
|
||||||
@ -129,24 +128,30 @@ epoll_init(void)
|
|||||||
|
|
||||||
FD_CLOSEONEXEC(epfd);
|
FD_CLOSEONEXEC(epfd);
|
||||||
|
|
||||||
epollop.epfd = epfd;
|
if (!(epollop = calloc(1, sizeof(struct epollop))))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
epollop->epfd = epfd;
|
||||||
|
|
||||||
/* Initalize fields */
|
/* Initalize fields */
|
||||||
epollop.events = malloc(nfiles * sizeof(struct epoll_event));
|
epollop->events = malloc(nfiles * sizeof(struct epoll_event));
|
||||||
if (epollop.events == NULL)
|
if (epollop->events == NULL) {
|
||||||
return (NULL);
|
free(epollop);
|
||||||
epollop.nevents = nfiles;
|
|
||||||
|
|
||||||
epollop.fds = calloc(nfiles, sizeof(struct evepoll));
|
|
||||||
if (epollop.fds == NULL) {
|
|
||||||
free(epollop.events);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
epollop.nfds = nfiles;
|
epollop->nevents = nfiles;
|
||||||
|
|
||||||
evsignal_init(&epollop.evsigmask);
|
epollop->fds = calloc(nfiles, sizeof(struct evepoll));
|
||||||
|
if (epollop->fds == NULL) {
|
||||||
|
free(epollop->events);
|
||||||
|
free(epollop);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
epollop->nfds = nfiles;
|
||||||
|
|
||||||
return (&epollop);
|
evsignal_init(&epollop->evsigmask);
|
||||||
|
|
||||||
|
return (epollop);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -150,7 +150,9 @@ bufferevent_writecb(int fd, short event, void *arg)
|
|||||||
if (EVBUFFER_LENGTH(bufev->output)) {
|
if (EVBUFFER_LENGTH(bufev->output)) {
|
||||||
res = evbuffer_write(bufev->output, fd);
|
res = evbuffer_write(bufev->output, fd);
|
||||||
if (res == -1) {
|
if (res == -1) {
|
||||||
if (errno == EAGAIN || errno == EINTR)
|
if (errno == EAGAIN ||
|
||||||
|
errno == EINTR ||
|
||||||
|
errno == EINPROGRESS)
|
||||||
goto reschedule;
|
goto reschedule;
|
||||||
/* error case */
|
/* error case */
|
||||||
what |= EVBUFFER_ERROR;
|
what |= EVBUFFER_ERROR;
|
||||||
|
20
event.3
20
event.3
@ -269,6 +269,20 @@ and
|
|||||||
.Fn event_del
|
.Fn event_del
|
||||||
and does not need to be reinitialized unless the function called and/or
|
and does not need to be reinitialized unless the function called and/or
|
||||||
the argument to it are to be changed.
|
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
|
.Pp
|
||||||
The function
|
The function
|
||||||
.Fn event_add
|
.Fn event_add
|
||||||
@ -409,6 +423,12 @@ This event base can be used in conjunction with calls to
|
|||||||
.Fn event_base_set
|
.Fn event_base_set
|
||||||
and
|
and
|
||||||
.Fn event_base_dispatch .
|
.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
|
.Pp
|
||||||
.Sh BUFFERED EVENTS
|
.Sh BUFFERED EVENTS
|
||||||
.Nm libevent
|
.Nm libevent
|
||||||
|
28
kqueue.c
28
kqueue.c
@ -74,7 +74,7 @@ struct kqop {
|
|||||||
struct kevent *events;
|
struct kevent *events;
|
||||||
int nevents;
|
int nevents;
|
||||||
int kq;
|
int kq;
|
||||||
} kqueueop;
|
};
|
||||||
|
|
||||||
void *kq_init (void);
|
void *kq_init (void);
|
||||||
int kq_add (void *, struct event *);
|
int kq_add (void *, struct event *);
|
||||||
@ -96,34 +96,40 @@ void *
|
|||||||
kq_init(void)
|
kq_init(void)
|
||||||
{
|
{
|
||||||
int kq;
|
int kq;
|
||||||
|
struct kqop *kqueueop;
|
||||||
|
|
||||||
/* Disable kqueue when this environment variable is set */
|
/* Disable kqueue when this environment variable is set */
|
||||||
if (getenv("EVENT_NOKQUEUE"))
|
if (getenv("EVENT_NOKQUEUE"))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
memset(&kqueueop, 0, sizeof(kqueueop));
|
if (!(kqueueop = calloc(1, sizeof(struct kqop))))
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
/* Initalize the kernel queue */
|
/* Initalize the kernel queue */
|
||||||
|
|
||||||
if ((kq = kqueue()) == -1) {
|
if ((kq = kqueue()) == -1) {
|
||||||
log_error("kqueue");
|
log_error("kqueue");
|
||||||
|
free (kqueueop);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
kqueueop.kq = kq;
|
kqueueop->kq = kq;
|
||||||
|
|
||||||
/* Initalize fields */
|
/* Initalize fields */
|
||||||
kqueueop.changes = malloc(NEVENT * sizeof(struct kevent));
|
kqueueop->changes = malloc(NEVENT * sizeof(struct kevent));
|
||||||
if (kqueueop.changes == NULL)
|
if (kqueueop->changes == NULL) {
|
||||||
return (NULL);
|
free (kqueueop);
|
||||||
kqueueop.events = malloc(NEVENT * sizeof(struct kevent));
|
|
||||||
if (kqueueop.events == NULL) {
|
|
||||||
free (kqueueop.changes);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
kqueueop.nevents = NEVENT;
|
kqueueop->events = malloc(NEVENT * sizeof(struct kevent));
|
||||||
|
if (kqueueop->events == NULL) {
|
||||||
|
free (kqueueop);
|
||||||
|
free (kqueueop->changes);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
kqueueop->nevents = NEVENT;
|
||||||
|
|
||||||
return (&kqueueop);
|
return (kqueueop);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
11
poll.c
11
poll.c
@ -65,7 +65,7 @@ struct pollop {
|
|||||||
struct pollfd *event_set;
|
struct pollfd *event_set;
|
||||||
struct event **event_back;
|
struct event **event_back;
|
||||||
sigset_t evsigmask;
|
sigset_t evsigmask;
|
||||||
} pollop;
|
};
|
||||||
|
|
||||||
void *poll_init (void);
|
void *poll_init (void);
|
||||||
int poll_add (void *, struct event *);
|
int poll_add (void *, struct event *);
|
||||||
@ -85,15 +85,18 @@ struct eventop pollops = {
|
|||||||
void *
|
void *
|
||||||
poll_init(void)
|
poll_init(void)
|
||||||
{
|
{
|
||||||
|
struct pollop *pollop;
|
||||||
|
|
||||||
/* Disable kqueue when this environment variable is set */
|
/* Disable kqueue when this environment variable is set */
|
||||||
if (getenv("EVENT_NOPOLL"))
|
if (getenv("EVENT_NOPOLL"))
|
||||||
return (NULL);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
11
select.c
11
select.c
@ -69,7 +69,7 @@ struct selectop {
|
|||||||
fd_set *event_readset;
|
fd_set *event_readset;
|
||||||
fd_set *event_writeset;
|
fd_set *event_writeset;
|
||||||
sigset_t evsigmask;
|
sigset_t evsigmask;
|
||||||
} sop;
|
};
|
||||||
|
|
||||||
void *select_init (void);
|
void *select_init (void);
|
||||||
int select_add (void *, struct event *);
|
int select_add (void *, struct event *);
|
||||||
@ -89,15 +89,18 @@ const struct eventop selectops = {
|
|||||||
void *
|
void *
|
||||||
select_init(void)
|
select_init(void)
|
||||||
{
|
{
|
||||||
|
struct selectop *sop;
|
||||||
|
|
||||||
/* Disable kqueue when this environment variable is set */
|
/* Disable kqueue when this environment variable is set */
|
||||||
if (getenv("EVENT_NOSELECT"))
|
if (getenv("EVENT_NOSELECT"))
|
||||||
return (NULL);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user