]> git.decadent.org.uk Git - ion3.git/blobdiff - libmainloop/defer.c
Imported Upstream version 20090110
[ion3.git] / libmainloop / defer.c
index dfc0e89df2b4baf9aefcbee1713b019cee981c30..2358a270cf5830379ebb76afc0cbac7b8cde69fd 100644 (file)
@@ -1,12 +1,9 @@
 /*
  * ion/libmainloop/defer.c
  *
- * Copyright (c) Tuomo Valkonen 1999-2007
+ * Copyright (c) Tuomo Valkonen 1999-2009
  *
- * Ion is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
+ * See the included file LICENSE for details.
  */
 
 /* This file contains routines for deferred execution of potentially
@@ -21,6 +18,7 @@
 #include <libtu/dlist.h>
 #include <libtu/output.h>
 #include <libtu/locale.h>
+#include <libtu/debug.h>
 #include "defer.h"
 
 
@@ -81,15 +79,32 @@ static void defer_watch_handler(Watch *w, Obj *obj)
     
     free_defer(d);
     
-    warn(TR("Object destroyed while deferred actions are still pending."));
+    D(warn(TR("Object destroyed while deferred actions are still pending.")));
 }
 
+
+static bool already_deferred(Obj *obj, WDeferredAction *action, 
+                             WDeferred *list)
+{
+    WDeferred *d;
     
+    for(d=list; d!=NULL; d=d->next){
+        if(d->action==action && d->watch.obj==obj)
+            return TRUE;
+    }
+    
+    return FALSE;
+}
+
+
 bool mainloop_defer_action_on_list(Obj *obj, WDeferredAction *action, 
                                    WDeferred **list)
 {
     WDeferred *d;
     
+    if(already_deferred(obj, action, *list))
+        return TRUE;
+    
     d=alloc_defer();
     
     if(d==NULL){
@@ -100,7 +115,8 @@ bool mainloop_defer_action_on_list(Obj *obj, WDeferredAction *action,
     d->action=action;
     d->list=list;
     d->fn=extl_fn_none();
-    
+    watch_init(&(d->watch));
+
     if(obj!=NULL)
         watch_setup(&(d->watch), obj, defer_watch_handler);
     
@@ -139,7 +155,6 @@ bool mainloop_defer_extl_on_list(ExtlFn fn, WDeferred **list)
     d->action=NULL;
     d->list=list;
     d->fn=extl_ref_fn(fn);
-    
     watch_init(&(d->watch));
     
     LINK_ITEM(*list, d, next, prev);
@@ -169,8 +184,11 @@ static void do_execute(WDeferred *d)
     free_defer(d);
     
     if(a!=NULL){
-        if(obj!=NULL)
-            a(obj);
+        /* The deferral should not be on the list, if there
+         * was an object, and it got destroyed.
+         */
+        /*if(obj!=NULL)*/
+        a(obj);
     }else if(fn!=extl_fn_none()){
         extl_call(fn, NULL, NULL);
         extl_unref_fn(fn);