]> granicus.if.org Git - libevent/commitdiff
fixes for threaded operations from Andrew Danforth
authorNiels Provos <provos@gmail.com>
Mon, 3 Jan 2005 18:58:40 +0000 (18:58 +0000)
committerNiels Provos <provos@gmail.com>
Mon, 3 Jan 2005 18:58:40 +0000 (18:58 +0000)
svn:r129

devpoll.c
epoll.c
evbuffer.c
event.3
kqueue.c
poll.c
select.c

index 3532d59ab095485c8f2f2cfcd8fdc2e0c368f71a..99ad4174cc5927296a1fd2c67477708a522b415e 100644 (file)
--- 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 2ffc2335fff2dd9d2cfeb2c5bed43ee655e02ef5..8c6fad9f653612acd05c632af78251dac9b035a7 100644 (file)
--- 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
index b8254d86a74818383505a5e6d619112a5d17c329..380a474d76137d569829618a687cbca54f9fef3f 100644 (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;
diff --git a/event.3 b/event.3
index bfff5928d385e734bbe6ca7f3d379939a2eacc9c..e6d41a582667664e86637aa75553d6b66e5aecfb 100644 (file)
--- 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
index 68d6cb03937d9c58990fdfdc03a9e3edccd3f2a7..7373d335a0b1c3359c1559be45e678b0bf08af50 100644 (file)
--- 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 ec2366d8f0b57a8236d28d380811e9baaf31098a..f34451c26fd01a24419c4be3e630a7b4c8eb0616 100644 (file)
--- 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);
 }
 
 /*
index 865f24279b0a05b315dda49e3015fc583c5dff55..f1353427b2c40ff47d63f1eaa5e25853e1c9530b 100644 (file)
--- 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);
 }
 
 /*