X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=libmainloop%2Fdefer.c;h=2358a270cf5830379ebb76afc0cbac7b8cde69fd;hp=dfc0e89df2b4baf9aefcbee1713b019cee981c30;hb=e3aec18706513a87eaa7839dfdaf7e0fcd0d8d2a;hpb=803afbc1cd633f6c025bcd9537e9b7e9aedadd0d diff --git a/libmainloop/defer.c b/libmainloop/defer.c index dfc0e89..2358a27 100644 --- a/libmainloop/defer.c +++ b/libmainloop/defer.c @@ -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 #include #include +#include #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);