From 3ba224dbd5e5e482bb2be47fa704beff46540a28 Mon Sep 17 00:00:00 2001 From: Niels Provos Date: Mon, 3 Jan 2005 18:58:40 +0000 Subject: [PATCH] fixes for threaded operations from Andrew Danforth svn:r129 --- devpoll.c | 44 ++++++++++++++++++++++++++------------------ epoll.c | 31 ++++++++++++++++++------------- evbuffer.c | 4 +++- event.3 | 20 ++++++++++++++++++++ kqueue.c | 26 ++++++++++++++++---------- poll.c | 11 +++++++---- select.c | 11 +++++++---- 7 files changed, 97 insertions(+), 50 deletions(-) diff --git a/devpoll.c b/devpoll.c index 3532d59a..99ad4174 100644 --- a/devpoll.c +++ b/devpoll.c @@ -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) + /* 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 @@ -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) diff --git a/epoll.c b/epoll.c index 2ffc2335..8c6fad9f 100644 --- a/epoll.c +++ b/epoll.c @@ -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) + 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 diff --git a/evbuffer.c b/evbuffer.c index b8254d86..380a474d 100644 --- a/evbuffer.c +++ b/evbuffer.c @@ -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; diff --git a/event.3 b/event.3 index bfff5928..e6d41a58 100644 --- a/event.3 +++ b/event.3 @@ -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 diff --git a/kqueue.c b/kqueue.c index 68d6cb03..7373d335 100644 --- a/kqueue.c +++ b/kqueue.c @@ -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) + 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 diff --git a/poll.c b/poll.c index ec2366d8..f34451c2 100644 --- a/poll.c +++ b/poll.c @@ -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); } /* diff --git a/select.c b/select.c index 865f2427..f1353427 100644 --- a/select.c +++ b/select.c @@ -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); } /* -- 2.40.0