Make events robust against their event_context being freed
authorVolker Lendecke <vl@samba.org>
Sat, 9 Aug 2008 19:39:18 +0000 (21:39 +0200)
committerVolker Lendecke <vl@samba.org>
Sun, 10 Aug 2008 16:40:47 +0000 (18:40 +0200)
source/lib/events.c

index 7750176d8e4bc0e6e59995013e8ffcc5d917a467..f03138708bacc0bcfe37b3e6bbe776bfee670618 100644 (file)
@@ -63,7 +63,9 @@ static int timed_event_destructor(struct timed_event *te)
 {
        DEBUG(10, ("Destroying timed event %lx \"%s\"\n", (unsigned long)te,
                te->event_name));
-       DLIST_REMOVE(te->event_ctx->timed_events, te);
+       if (te->event_ctx != NULL) {
+               DLIST_REMOVE(te->event_ctx->timed_events, te);
+       }
        return 0;
 }
 
@@ -131,9 +133,9 @@ struct timed_event *event_add_timed(struct event_context *event_ctx,
 
 static int fd_event_destructor(struct fd_event *fde)
 {
-       struct event_context *event_ctx = fde->event_ctx;
-
-       DLIST_REMOVE(event_ctx->fd_events, fde);
+       if (fde->event_ctx != NULL) {
+               DLIST_REMOVE(fde->event_ctx->fd_events, fde);
+       }
        return 0;
 }
 
@@ -354,9 +356,30 @@ int event_loop_once(struct event_context *ev)
        return 0;
 }
 
+static int event_context_destructor(struct event_context *ev)
+{
+       while (ev->fd_events != NULL) {
+               ev->fd_events->event_ctx = NULL;
+               DLIST_REMOVE(ev->fd_events, ev->fd_events);
+       }
+       while (ev->timed_events != NULL) {
+               ev->timed_events->event_ctx = NULL;
+               DLIST_REMOVE(ev->timed_events, ev->timed_events);
+       }
+       return 0;
+}
+
 struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
 {
-       return TALLOC_ZERO_P(mem_ctx, struct event_context);
+       struct event_context *result;
+
+       result = TALLOC_ZERO_P(mem_ctx, struct event_context);
+       if (result == NULL) {
+               return NULL;
+       }
+
+       talloc_set_destructor(result, event_context_destructor);
+       return result;
 }
 
 int set_event_dispatch_time(struct event_context *event_ctx,