[Gnucash-changes] r13196 - gnucash/trunk - Better handling of event
removal. This allows us to actually
Derek Atkins
warlord at cvs.gnucash.org
Fri Feb 10 17:43:20 EST 2006
Author: warlord
Date: 2006-02-10 17:43:19 -0500 (Fri, 10 Feb 2006)
New Revision: 13196
Trac: http://svn.gnucash.org/trac/changeset/13196
Modified:
gnucash/trunk/ChangeLog
gnucash/trunk/lib/libqof/qof/gnc-event.c
Log:
Better handling of event removal. This allows us to actually
clean up, but also makes sure we don't destroy the handler
list out from under us as we're processing events.
Modified: gnucash/trunk/ChangeLog
===================================================================
--- gnucash/trunk/ChangeLog 2006-02-10 15:32:39 UTC (rev 13195)
+++ gnucash/trunk/ChangeLog 2006-02-10 22:43:19 UTC (rev 13196)
@@ -11,6 +11,11 @@
detects that we're running on a "broken" system like Ubuntu.
This is in response to #330539.
+ * lib/libqof/qof/gnc-event.c:
+ Better handling of event removal. This allows us to actually
+ clean up, but also makes sure we don't destroy the handler
+ list out from under us as we're processing events.
+
2006-02-09 David Hampton <hampton at employees.org>
* src/bin/gnucash-bin.c: Pass argc by reference instead of value
Modified: gnucash/trunk/lib/libqof/qof/gnc-event.c
===================================================================
--- gnucash/trunk/lib/libqof/qof/gnc-event.c 2006-02-10 15:32:39 UTC (rev 13195)
+++ gnucash/trunk/lib/libqof/qof/gnc-event.c 2006-02-10 22:43:19 UTC (rev 13196)
@@ -38,6 +38,8 @@
/* Static Variables ************************************************/
static guint suspend_counter = 0;
static gint next_handler_id = 1;
+static guint handler_run_level = 0;
+static guint pending_deletes = 0;
static GList *handlers = NULL;
/* This static indicates the debugging module that this .o belongs to. */
@@ -113,14 +115,20 @@
of a generated event, such as GNC_EVENT_DESTROY. In that case,
we're in the middle of walking the GList and it is wrong to
modify the list. So, instead, we just NULL the handler. */
- /* handlers = g_list_remove_link (handlers, node); */
- LEAVE ("(handler_id=%d) handler=%p data=%p", handler_id, hi->handler, hi->user_data);
- /* safety */
+ LEAVE ("(handler_id=%d) handler=%p data=%p", handler_id,
+ hi->handler, hi->user_data);
+
+ /* safety -- clear the handler in case we're running events now */
hi->handler = NULL;
- /* g_list_free_1 (node);
- g_free (hi); */
+ if (handler_run_level == 0) {
+ handlers = g_list_remove_link (handlers, node);
+ g_list_free_1 (node);
+ g_free (hi);
+ } else {
+ pending_deletes++;
+ }
return;
}
@@ -177,6 +185,7 @@
return;
}
+ handler_run_level++;
for (node = handlers; node; node = next_node)
{
HandlerInfo *hi = node->data;
@@ -184,8 +193,30 @@
next_node = node->next;
PINFO ("id=%d hi=%p han=%p", hi->handler_id, hi, hi->handler);
if (hi->handler)
- hi->handler ((GUID *)&entity->guid, entity->e_type, event_type, hi->user_data);
+ hi->handler ((GUID *)&entity->guid, entity->e_type,
+ event_type, hi->user_data);
}
+ handler_run_level--;
+
+ /* If we're the outtermost event runner and we have pending deletes
+ * then go delete the handlers now.
+ */
+ if (handler_run_level == 0 && pending_deletes)
+ {
+ for (node = handlers; node; node = next_node)
+ {
+ HandlerInfo *hi = node->data;
+ next_node = node->next;
+ if (hi->handler == NULL)
+ {
+ /* remove this node from the list, then free this node */
+ handlers = g_list_remove_link (handlers, node);
+ g_list_free_1 (node);
+ g_free (hi);
+ }
+ }
+ pending_deletes = 0;
+ }
}
void
More information about the gnucash-changes
mailing list