r10537: - we now use a much nicer way to handle talloc_free(timed_event)
authorStefan Metzmacher <metze@samba.org>
Tue, 27 Sep 2005 12:54:08 +0000 (12:54 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:39:03 +0000 (13:39 -0500)
  the events code replaces a destructor to one that returns allways -1
  while it's calling the event handler
- we don't need the composite and winsrepl specific fixes any more
- this also fixes the problem with smbcli, dcerpc, cldap, ldap and nbt
  request timeouts

metze
(This used to be commit 495996cfc49a1c6eefde6ff04fc75e0739be3aab)

source4/gtk/common/gtk_events.c
source4/lib/events/events_liboop.c
source4/lib/events/events_standard.c
source4/libcli/composite/composite.c
source4/libcli/wrepl/winsrepl.c

index fdc6d55621caa1c31dfdceee479165cc3c6bd24f..df4ffc5cc831af039ff04cfa5db53e3c57616b12 100644 (file)
@@ -209,46 +209,44 @@ static void gtk_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
 }
 
 struct gtk_timed_event {
-       BOOL running;
        guint te_id;
 };
 
-static gboolean gtk_event_timed_handler(gpointer data)
+/*
+  destroy a timed event
+*/
+static int gtk_event_timed_destructor(void *ptr)
 {
-       struct timed_event *te = talloc_get_type(data, struct timed_event);
+       struct timed_event *te = talloc_get_type(ptr, struct timed_event);
        struct gtk_timed_event *gtk_te = talloc_get_type(te->additional_data,
                                                         struct gtk_timed_event);
-       struct timeval t = timeval_current();
 
-       gtk_te->running = True;
-       te->handler(te->event_ctx, te, t, te->private_data);
-       gtk_te->running = False;
+       g_source_remove(gtk_te->te_id);
 
-       talloc_free(te);
+       return 0;
+}
 
-       /* return FALSE mean this event should be removed */
-       return gtk_false();
+static int gtk_event_timed_deny_destructor(void *ptr)
+{
+       return -1;
 }
 
-/*
-  destroy a timed event
-*/
-static int gtk_event_timed_destructor(void *ptr)
+static gboolean gtk_event_timed_handler(gpointer data)
 {
-       struct timed_event *te = talloc_get_type(ptr, struct timed_event);
+       struct timed_event *te = talloc_get_type(data, struct timed_event);
        struct gtk_timed_event *gtk_te = talloc_get_type(te->additional_data,
                                                         struct gtk_timed_event);
+       struct timeval t = timeval_current();
 
-       if (gtk_te->running) {
-               /* the event is running reject the talloc_free()
-                  as it's done by the gtk_event_timed_handler()
-                */
-               return -1;
-       }
+       /* deny the handler to free the event */
+       talloc_set_destructor(te, gtk_event_timed_deny_destructor);
+       te->handler(te->event_ctx, te, t, te->private_data);
 
-       g_source_remove(gtk_te->te_id);
+       talloc_set_destructor(te, gtk_event_timed_destructor);
+       talloc_free(te);
 
-       return 0;
+       /* return FALSE mean this event should be removed */
+       return gtk_false();
 }
 
 /*
@@ -285,7 +283,6 @@ static struct timed_event *gtk_event_add_timed(struct event_context *ev, TALLOC_
        timeout                 = ((diff_tv.tv_usec+999)/1000)+(diff_tv.tv_sec*1000);
 
        gtk_te->te_id           = g_timeout_add(timeout, gtk_event_timed_handler, te);
-       gtk_te->running         = False;
 
        talloc_set_destructor(te, gtk_event_timed_destructor);
 
index ad7c43cd4e1971d74ccd14d41b21e8f9c33f41bb..54cb8d5a526ab363755c25ba41fc653c951bfd4e 100644 (file)
@@ -172,12 +172,23 @@ static void oop_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
        fde->flags = flags;
 }
 
+static int oop_event_timed_destructor(void *ptr);
+static int oop_event_timed_deny_destructor(void *ptr)
+{
+       return -1;
+}
+
 static void *oop_event_timed_handler(oop_source *oop, struct timeval t, void *ptr)
 {
        struct timed_event *te = ptr;
 
+       /* deny the handler to free the event */
+       talloc_set_destructor(te, oop_event_timed_deny_destructor);
        te->handler(te->event_ctx, te, t, te->private_data);
 
+       talloc_set_destructor(te, oop_event_timed_destructor);
+       talloc_free(te);
+
        return OOP_CONTINUE;
 }
 
@@ -218,7 +229,7 @@ static struct timed_event *oop_event_add_timed(struct event_context *ev, TALLOC_
        te->private_data        = private_data;
        te->additional_data     = NULL;
 
-       oop->cancel_time(oop, te->next_event, oop_event_timed_handler, te);
+       oop->on_time(oop, te->next_event, oop_event_timed_handler, te);
 
        talloc_set_destructor(te, oop_event_timed_destructor);
 
index 810e8bbca30ec67f9e06c16ec7c6aa27d823bf1f..8fe8d009bfa2d0821a54e6dfc3dae533f72ae1bd 100644 (file)
@@ -284,6 +284,11 @@ static int std_event_timed_destructor(void *ptr)
        return 0;
 }
 
+static int std_event_timed_deny_destructor(void *ptr)
+{
+       return -1;
+}
+
 /*
   add a timed event
   return NULL on failure (memory allocation error)
@@ -340,17 +345,12 @@ static void std_event_loop_timer(struct event_context *ev)
                return;
        }
 
-       te->next_event = timeval_zero();
-
+       /* deny the handler to free the event */
+       talloc_set_destructor(te, std_event_timed_deny_destructor);
        te->handler(ev, te, t, te->private_data);
 
-       /* note the care taken to prevent referencing a event
-          that could have been freed by the handler */
-       if (std_ev->timed_events) {
-               if (timeval_is_zero(&std_ev->timed_events->next_event)) {
-                       talloc_free(te);
-               }
-       }
+       talloc_set_destructor(te, std_event_timed_destructor);
+       talloc_free(te);
 }
 
 #if WITH_EPOLL
index f6fc61d764c587a0a1483ccac7e4d7e1d25df511..4a5247c9ea9b434c040428df136a99fb6340a018 100644 (file)
@@ -52,12 +52,6 @@ static void composite_trigger(struct event_context *ev, struct timed_event *te,
 {
        struct composite_context *c = talloc_get_type(ptr, struct composite_context);
        if (c->async.fn) {
-               /*
-                * the event is a child of req,
-                * and req will be free'ed by the callback fn
-                * but the events code wants to free the event itself
-                */
-               talloc_steal(ev, te);   
                c->async.fn(c);
        }
 }
index 945f4a4b4c1b5a61bedc3f43658898061ddda833..853ee01d388a14bd4c4200a7ab0b4a6151680fb1 100644 (file)
@@ -385,12 +385,6 @@ static void wrepl_request_trigger_handler(struct event_context *ev, struct timed
 {
        struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request);
        if (req->async.fn) {
-               /*
-                * the event is a child of req,
-                * and req will be free'ed by the callback fn
-                * but the events code wants to free the event itself
-                */
-               talloc_steal(ev, te);
                req->async.fn(req);
        }
 }