tevent: split out tevent_common_invoke_fd_handler()
authorStefan Metzmacher <metze@samba.org>
Tue, 22 Jul 2014 12:45:33 +0000 (14:45 +0200)
committerRalph Boehme <slow@samba.org>
Wed, 11 Jul 2018 21:04:21 +0000 (23:04 +0200)
We'll undo the 0.9.36 ABI change on the 0.9.37 release
at the end of this patchset.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
lib/tevent/ABI/tevent-0.9.36.sigs
lib/tevent/tevent_epoll.c
lib/tevent/tevent_fd.c
lib/tevent/tevent_internal.h
lib/tevent/tevent_poll.c
lib/tevent/tevent_port.c

index 451e380688c862d6ba83a15bc7e9f9793ff07434..443bb7cb6c92642d3c7fa0d238d959ab5225149e 100644 (file)
@@ -32,6 +32,7 @@ tevent_common_fd_get_flags: uint16_t (struct tevent_fd *)
 tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t)
 tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t)
 tevent_common_have_events: bool (struct tevent_context *)
+tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *)
 tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *)
 tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *)
 tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *)
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..7859cbb00ef51ed47b266c6695b09466f2678c28 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,29 @@ void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
 {
        fde->close_fn = close_fn;
 }
+
+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 d74684c72c2cf610f48f7c34659db9aa1379a90b..1183b9f7f83180ae2f9da64d6d4d04a36adee4ba 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 282f3cf3082c32dfb0ba1359289554a34d242940..74c418ca42185ce6b7a713e91799893ebed9e3f7 100644 (file)
@@ -565,8 +565,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);
                }
        }
 
index 8cf9fd1a0de7aa9bc6abea8b21212cf2b420041c..e91d442389dce56a0d730a4084cf7374959e4d91 100644 (file)
@@ -600,8 +600,7 @@ static int port_event_loop(struct port_event_context *port_ev, struct timeval *t
                 */
                flags &= fde->flags;
                if (flags) {
-                       fde->handler(ev, fde, flags, fde->private_data);
-                       break;
+                       return tevent_common_invoke_fd_handler(fde, flags, NULL);
                }
        }