diff options
author | José Bollo <jose.bollo@iot.bzh> | 2016-04-21 15:14:36 +0200 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2016-04-21 15:14:36 +0200 |
commit | 45e4c16ed05d6b5fed969b08aa873d6c24b5f948 (patch) | |
tree | 731471bc6aa4c1f988246f936565d32cf7aca209 | |
parent | 26cefa686d680bcfd36d69cab18a25e986acc217 (diff) |
handles closing in callbacks
Change-Id: I7c12c31957794910cd92fdfe74257e6faae8770a
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r-- | src/utils-upoll.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/src/utils-upoll.c b/src/utils-upoll.c index 82d6dac8..2a270250 100644 --- a/src/utils-upoll.c +++ b/src/utils-upoll.c @@ -47,6 +47,7 @@ struct upollfd static int pollfd = 0; static struct upollfd *head = NULL; +static struct upoll *current = NULL; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static int update(struct upollfd *ufd) @@ -226,6 +227,8 @@ void upoll_close(struct upoll *upoll) ufd = upoll->fd; pthread_mutex_lock(&mutex); + if (current == upoll) + current = NULL; it = &ufd->head; while (*it != upoll) it = &(*it)->next; @@ -240,7 +243,6 @@ int upoll_wait(int timeout) int rc; struct epoll_event e; struct upollfd *ufd; - struct upoll *u; if (pollfd == 0) { errno = ECANCELED; @@ -252,18 +254,25 @@ int upoll_wait(int timeout) } while (rc < 0 && errno == EINTR); if (rc == 1) { ufd = e.data.ptr; - u = ufd->head; - while (u != NULL) { - if ((e.events & EPOLLIN) && u->read) { - u->read(u->closure); + current = ufd->head; + e.events &= EPOLLIN | EPOLLOUT | EPOLLHUP; + while (current != NULL && e.events != 0) { + if ((e.events & EPOLLIN) && current->read) { + current->read(current->closure); + e.events &= (uint32_t)~EPOLLIN; + continue; } - if ((e.events & EPOLLOUT) && u->write) { - u->write(u->closure); + if ((e.events & EPOLLOUT) && current->write) { + current->write(current->closure); + e.events &= (uint32_t)~EPOLLOUT; + continue; } - if ((e.events & EPOLLHUP) && u->hangup) { - u->hangup(u->closure); + if ((e.events & EPOLLHUP) && current->hangup) { + current->hangup(current->closure); + if (current == NULL) + break; } - u = u->next; + current = current->next; } } return rc < 0 ? rc : 0; |