tevent: split out tevent_common_invoke_fd_handler()
authorStefan Metzmacher <metze@samba.org>
Tue, 22 Jul 2014 12:45:33 +0000 (14:45 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 17 May 2018 07:51:48 +0000 (09:51 +0200)
We'll remove _PRIVATE_ with the next release.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
lib/tevent/tevent_epoll.c
lib/tevent/tevent_fd.c
lib/tevent/tevent_internal.h
lib/tevent/tevent_poll.c

index 4147c67af2a014ed16b829c7730ac0f1fbb93a34..5f7ef5d83d173ed31ecf1efa4a18d74d8eda2461 100644 (file)
@@ -725,8 +725,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
                 */
                flags &= fde->flags;
                if (flags) {
-                       fde->handler(epoll_ev->ev, fde, flags, fde->private_data);
-                       break;
+                       return tevent_common_invoke_fd_handler(fde, flags, NULL);
                }
        }
 
index f33ae841b3964324fb4a43319591f824f756a6c8..f8234641ad3de0008053248dd52525f6986eb1db 100644 (file)
 
 int tevent_common_fd_destructor(struct tevent_fd *fde)
 {
+       if (fde->destroyed) {
+               tevent_common_check_double_free(fde, "tevent_fd double free");
+               goto done;
+       }
+       fde->destroyed = true;
+
        if (fde->event_ctx) {
                DLIST_REMOVE(fde->event_ctx->fd_events, fde);
        }
@@ -37,6 +43,13 @@ int tevent_common_fd_destructor(struct tevent_fd *fde)
        if (fde->close_fn) {
                fde->close_fn(fde->event_ctx, fde, fde->fd, fde->private_data);
                fde->fd = -1;
+               fde->close_fn = NULL;
+       }
+
+       fde->event_ctx = NULL;
+done:
+       if (fde->busy) {
+               return -1;
        }
 
        return 0;
@@ -92,3 +105,30 @@ void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
 {
        fde->close_fn = close_fn;
 }
+
+_PRIVATE_
+int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
+                                   bool *removed)
+{
+       if (removed != NULL) {
+               *removed = false;
+       }
+
+       if (fde->event_ctx == NULL) {
+               return 0;
+       }
+
+       fde->busy = true;
+       fde->handler(fde->event_ctx, fde, flags, fde->private_data);
+       fde->busy = false;
+
+       if (fde->destroyed) {
+               talloc_set_destructor(fde, NULL);
+               TALLOC_FREE(fde);
+               if (removed != NULL) {
+                       *removed = true;
+               }
+       }
+
+       return 0;
+}
index a590a5bb3b756aaa88e6f2a93dccf71501b9fc41..ed39aa2bebe45ca3e7d075b18febcd4937b91b2e 100644 (file)
@@ -170,6 +170,8 @@ struct tevent_req {
 struct tevent_fd {
        struct tevent_fd *prev, *next;
        struct tevent_context *event_ctx;
+       bool busy;
+       bool destroyed;
        int fd;
        uint16_t flags; /* see TEVENT_FD_* flags */
        tevent_fd_handler_t handler;
@@ -343,6 +345,8 @@ void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
                                   tevent_fd_close_fn_t close_fn);
 uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde);
 void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
+int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags,
+                                   bool *removed);
 
 struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev,
                                             TALLOC_CTX *mem_ctx,
index f1d52533f5dee72079d43bc4e304ac276d1f7158..a1f7ef22206d5ec01d43cb6f405c4e4f5b90b8c0 100644 (file)
@@ -603,8 +603,7 @@ static int poll_event_loop_poll(struct tevent_context *ev,
                flags &= fde->flags;
                if (flags != 0) {
                        DLIST_DEMOTE(ev->fd_events, fde);
-                       fde->handler(ev, fde, flags, fde->private_data);
-                       return 0;
+                       return tevent_common_invoke_fd_handler(fde, flags, NULL);
                }
        }