fixes for threaded operations from Andrew Danforth

svn:r129
This commit is contained in:
Niels Provos 2005-01-03 18:58:40 +00:00
parent bd6999b4a2
commit 3ba224dbd5
7 changed files with 102 additions and 55 deletions

View File

@ -74,7 +74,7 @@ struct devpollop {
int nevents;
int dpfd;
sigset_t evsigmask;
} devpollop;
};
void *devpoll_init (void);
int devpoll_add (void *, struct event *);
@ -98,42 +98,49 @@ devpoll_init(void)
{
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)
return (NULL);
devpollop.nevents = nfiles;
devpollop.fds = calloc(nfiles, sizeof(struct evdevpoll));
if (devpollop.fds == NULL) {
free(devpollop.events);
/* Initialize fields */
devpollop->events = calloc(nfiles, sizeof(struct pollfd));
if (devpollop->events == NULL) {
free(devpollop);
close(dpfd);
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
@ -254,7 +261,7 @@ devpoll_add(void *arg, struct event *ev)
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);
}
@ -326,7 +333,8 @@ devpoll_del(void *arg, struct event *ev)
}
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)

35
epoll.c
View File

@ -76,7 +76,7 @@ struct epollop {
int nevents;
int epfd;
sigset_t evsigmask;
} epollop;
};
void *epoll_init (void);
int epoll_add (void *, struct event *);
@ -109,13 +109,12 @@ epoll_init(void)
{
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;
@ -129,24 +128,30 @@ epoll_init(void)
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)
return (NULL);
epollop.nevents = nfiles;
epollop.fds = calloc(nfiles, sizeof(struct evepoll));
if (epollop.fds == NULL) {
free(epollop.events);
epollop->events = malloc(nfiles * sizeof(struct epoll_event));
if (epollop->events == NULL) {
free(epollop);
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

View File

@ -150,7 +150,9 @@ bufferevent_writecb(int fd, short event, void *arg)
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;

20
event.3
View File

@ -269,6 +269,20 @@ and
.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
@ -409,6 +423,12 @@ This event base can be used in conjunction with calls to
.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

View File

@ -74,7 +74,7 @@ struct kqop {
struct kevent *events;
int nevents;
int kq;
} kqueueop;
};
void *kq_init (void);
int kq_add (void *, struct event *);
@ -96,34 +96,40 @@ void *
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)
return (NULL);
kqueueop.events = malloc(NEVENT * sizeof(struct kevent));
if (kqueueop.events == NULL) {
free (kqueueop.changes);
kqueueop->changes = malloc(NEVENT * sizeof(struct kevent));
if (kqueueop->changes == NULL) {
free (kqueueop);
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

11
poll.c
View File

@ -65,7 +65,7 @@ struct pollop {
struct pollfd *event_set;
struct event **event_back;
sigset_t evsigmask;
} pollop;
};
void *poll_init (void);
int poll_add (void *, struct event *);
@ -85,15 +85,18 @@ struct eventop pollops = {
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);
}
/*

View File

@ -69,7 +69,7 @@ struct selectop {
fd_set *event_readset;
fd_set *event_writeset;
sigset_t evsigmask;
} sop;
};
void *select_init (void);
int select_add (void *, struct event *);
@ -89,15 +89,18 @@ const struct eventop selectops = {
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);
}
/*