We need to avoid passing pollfd.events == 0, to poll(),
as it will report POLLERR and POLLHUP events, but our caller
does not expect the event handler to be called.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
* picked up yet by poll_event_loop_once
*/
struct tevent_fd *fresh;
* picked up yet by poll_event_loop_once
*/
struct tevent_fd *fresh;
+ /*
+ * A DLIST for disabled fde's.
+ */
+ struct tevent_fd *disabled;
+ /*
+ * one or more events were deleted or disabled
+ */
DLIST_REMOVE(poll_ev->fresh, fd);
}
DLIST_REMOVE(poll_ev->fresh, fd);
}
+ for (fd = poll_ev->disabled; fd; fd = fn) {
+ fn = fd->next;
+ fd->event_ctx = NULL;
+ DLIST_REMOVE(poll_ev->disabled, fd);
+ }
+
if (poll_ev->signal_fd == -1) {
/*
* Non-threaded, no signal pipe
if (poll_ev->signal_fd == -1) {
/*
* Non-threaded, no signal pipe
ev->additional_data, struct poll_event_context);
if (del_idx == UINT64_MAX) {
ev->additional_data, struct poll_event_context);
if (del_idx == UINT64_MAX) {
+ struct tevent_fd **listp =
+ (struct tevent_fd **)fde->additional_data;
- DLIST_REMOVE(poll_ev->fresh, fde);
+ DLIST_REMOVE((*listp), fde);
{
struct poll_event_context *poll_ev = talloc_get_type_abort(
ev->additional_data, struct poll_event_context);
{
struct poll_event_context *poll_ev = talloc_get_type_abort(
ev->additional_data, struct poll_event_context);
+ struct tevent_fd **listp;
+
+ if (fde->flags != 0) {
+ listp = &poll_ev->fresh;
+ } else {
+ listp = &poll_ev->disabled;
+ }
fde->additional_flags = UINT64_MAX;
fde->additional_flags = UINT64_MAX;
- fde->additional_data = NULL;
- DLIST_ADD(poll_ev->fresh, fde);
+ fde->additional_data = listp;
+
+ DLIST_ADD((*listp), fde);
talloc_set_destructor(fde, poll_event_fd_destructor);
}
talloc_set_destructor(fde, poll_event_fd_destructor);
}
fde->flags = flags;
if (idx == UINT64_MAX) {
fde->flags = flags;
if (idx == UINT64_MAX) {
+ struct tevent_fd **listp =
+ (struct tevent_fd **)fde->additional_data;
+
+ /*
+ * We move it between the fresh and disabled lists.
+ */
+ DLIST_REMOVE((*listp), fde);
+ tevent_poll_event_add_fd_internal(ev, fde);
+ poll_event_wake_pollthread(poll_ev);
+ return;
+ }
+
+ if (fde->flags == 0) {
- * poll_event_setup_fresh not yet called after this fde was
- * added. We don't have to do anything to transfer the changed
- * flags to the array passed to poll(2)
+ * We need to remove it from the array
+ * and move it to the disabled list.
+ poll_ev->fdes[idx] = NULL;
+ poll_ev->deleted = true;
+ DLIST_REMOVE(ev->fd_events, fde);
+ tevent_poll_event_add_fd_internal(ev, fde);
+ poll_event_wake_pollthread(poll_ev);
ev->timer_events ||
ev->immediate_events ||
ev->signal_events ||
ev->timer_events ||
ev->immediate_events ||
ev->signal_events ||
+ poll_ev->fresh ||
+ poll_ev->disabled) {
int ret;
ret = _tevent_loop_once(ev, location);
if (ret != 0) {
int ret;
ret = _tevent_loop_once(ev, location);
if (ret != 0) {