summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2013-03-01 13:57:05 +0100
committerJeremy Allison <jra@samba.org>2013-03-01 12:01:07 -0800
commit6703c5b49ff8f1957a16b1bab5a0e0d18bf1af75 (patch)
tree52b5b99be0b5832ab243186e800251e5349b520f /lib
parent15ca40fb7ad1668013eb5ebef4479058d33df992 (diff)
downloadsamba-6703c5b49ff8f1957a16b1bab5a0e0d18bf1af75.tar.gz
samba-6703c5b49ff8f1957a16b1bab5a0e0d18bf1af75.tar.bz2
samba-6703c5b49ff8f1957a16b1bab5a0e0d18bf1af75.zip
tevent: Fix epoll_mod_event() to cope with modifying a multiplexed fde event.
Signed-off-by: Jeremy Allison <jra@samba.org> Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/tevent/tevent_epoll.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c
index 97130db0a7..d8c1050701 100644
--- a/lib/tevent/tevent_epoll.c
+++ b/lib/tevent/tevent_epoll.c
@@ -480,23 +480,43 @@ static void epoll_del_event(struct epoll_event_context *epoll_ev, struct tevent_
*/
static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde)
{
+ struct tevent_fd *mpx_fde = NULL;
struct epoll_event event;
int ret;
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
+ if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) {
+ /*
+ * This is a multiplexed fde, we need to include both
+ * flags in the modified event.
+ */
+ mpx_fde = talloc_get_type_abort(fde->additional_data,
+ struct tevent_fd);
+
+ mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
+ mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
+ }
+
ZERO_STRUCT(event);
event.events = epoll_map_flags(fde->flags);
+ if (mpx_fde != NULL) {
+ event.events |= epoll_map_flags(mpx_fde->flags);
+ }
event.data.ptr = fde;
ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event);
if (ret != 0 && errno == EBADF) {
tevent_debug(epoll_ev->ev, TEVENT_DEBUG_ERROR,
"EPOLL_CTL_MOD EBADF for "
- "fde[%p] fd[%d] - disabling\n",
- fde, fde->fd);
+ "fde[%p] mpx_fde[%p] fd[%d] - disabling\n",
+ fde, mpx_fde, fde->fd);
DLIST_REMOVE(epoll_ev->ev->fd_events, fde);
fde->event_ctx = NULL;
+ if (mpx_fde != NULL) {
+ DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde);
+ mpx_fde->event_ctx = NULL;
+ }
return;
} else if (ret != 0) {
epoll_panic(epoll_ev, "EPOLL_CTL_MOD failed", false);
@@ -508,6 +528,16 @@ static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct tevent_
if (fde->flags & TEVENT_FD_READ) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
}
+
+ if (mpx_fde == NULL) {
+ return;
+ }
+
+ mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
+ /* only if we want to read we want to tell the event handler about errors */
+ if (mpx_fde->flags & TEVENT_FD_READ) {
+ mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
+ }
}
static void epoll_update_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde)