r20042 - gnucash/trunk/src/engine - Fix more memory leaks. Also, when closing a book (to open a new one, not year end), free objects.
Phil Longstaff
plongstaff at code.gnucash.org
Sun Jan 9 13:01:47 EST 2011
Author: plongstaff
Date: 2011-01-09 13:01:47 -0500 (Sun, 09 Jan 2011)
New Revision: 20042
Trac: http://svn.gnucash.org/trac/changeset/20042
Modified:
gnucash/trunk/src/engine/Account.c
gnucash/trunk/src/engine/Recurrence.c
gnucash/trunk/src/engine/Recurrence.h
gnucash/trunk/src/engine/SX-book.c
gnucash/trunk/src/engine/SchedXaction.c
gnucash/trunk/src/engine/Transaction.c
gnucash/trunk/src/engine/engine.i
gnucash/trunk/src/engine/gnc-lot.c
Log:
Fix more memory leaks. Also, when closing a book (to open a new one, not year end), free objects.
Modified: gnucash/trunk/src/engine/Account.c
===================================================================
--- gnucash/trunk/src/engine/Account.c 2011-01-09 18:00:32 UTC (rev 20041)
+++ gnucash/trunk/src/engine/Account.c 2011-01-09 18:01:47 UTC (rev 20042)
@@ -266,6 +266,10 @@
else
g_free ( acct_name );
}
+ if (accounts != NULL)
+ {
+ g_list_free(accounts);
+ }
return invalid_list;
}
@@ -1230,13 +1234,26 @@
PINFO ("freeing splits for account %p (%s)",
acc, priv->accountName ? priv->accountName : "(null)");
- slist = g_list_copy(priv->splits);
- for (lp = slist; lp; lp = lp->next)
+ book = qof_instance_get_book(acc);
+
+ /* If book is shutting down, just clear the split list. The splits
+ themselves will be destroyed by the transaction code */
+ if (!qof_book_shutting_down(book))
{
- Split *s = lp->data;
- xaccSplitDestroy (s);
+ slist = g_list_copy(priv->splits);
+ for (lp = slist; lp; lp = lp->next)
+ {
+ Split *s = lp->data;
+ xaccSplitDestroy (s);
+ }
+ g_list_free(slist);
}
- g_list_free(slist);
+ else
+ {
+ g_list_free(priv->splits);
+ priv->splits = NULL;
+ }
+
/* It turns out there's a case where this assertion does not hold:
When the user tries to delete an Imbalance account, while also
deleting all the splits in it. The splits will just get
@@ -1245,18 +1262,17 @@
g_assert(priv->splits == NULL || qof_book_shutting_down(acc->inst.book));
*/
- book = qof_instance_get_book(acc);
if (!qof_book_shutting_down(book))
{
col = qof_book_get_collection(book, GNC_ID_TRANS);
qof_collection_foreach(col, destroy_pending_splits_for_account, acc);
- }
- /* the lots should be empty by now */
- for (lp = priv->lots; lp; lp = lp->next)
- {
- GNCLot *lot = lp->data;
- gnc_lot_destroy (lot);
+ /* the lots should be empty by now */
+ for (lp = priv->lots; lp; lp = lp->next)
+ {
+ GNCLot *lot = lp->data;
+ gnc_lot_destroy (lot);
+ }
}
g_list_free(priv->lots);
priv->lots = NULL;
@@ -4807,6 +4823,16 @@
/* ================================================================ */
/* QofObject function implementation and registration */
+
+static void
+gnc_account_book_end(QofBook* book)
+{
+ Account *root_account = gnc_book_get_root_account(book);
+
+ xaccAccountBeginEdit(root_account);
+ xaccAccountDestroy(root_account);
+}
+
#ifdef _MSC_VER
/* MSVC compiler doesn't have C99 "designated initializers"
* so we wrap them in a macro that is empty on MSVC. */
@@ -4821,7 +4847,7 @@
DI(.type_label = ) "Account",
DI(.create = ) (gpointer)xaccMallocAccount,
DI(.book_begin = ) NULL,
- DI(.book_end = ) NULL,
+ DI(.book_end = ) gnc_account_book_end,
DI(.is_dirty = ) qof_collection_is_dirty,
DI(.mark_clean = ) qof_collection_mark_clean,
DI(.foreach = ) qof_collection_foreach,
Modified: gnucash/trunk/src/engine/Recurrence.c
===================================================================
--- gnucash/trunk/src/engine/Recurrence.c 2011-01-09 18:00:32 UTC (rev 20041)
+++ gnucash/trunk/src/engine/Recurrence.c 2011-01-09 18:01:47 UTC (rev 20042)
@@ -541,9 +541,9 @@
}
gboolean
-recurrenceListIsWeeklyMultiple(GList *recurrences)
+recurrenceListIsWeeklyMultiple(const GList *recurrences)
{
- GList *r_iter;
+ const GList *r_iter;
for (r_iter = recurrences; r_iter != NULL; r_iter = r_iter->next)
{
Modified: gnucash/trunk/src/engine/Recurrence.h
===================================================================
--- gnucash/trunk/src/engine/Recurrence.h 2011-01-09 18:00:32 UTC (rev 20041)
+++ gnucash/trunk/src/engine/Recurrence.h 2011-01-09 18:01:47 UTC (rev 20042)
@@ -161,7 +161,7 @@
/** @return True if the recurrence list is a common "semi-monthly" recurrence. **/
gboolean recurrenceListIsSemiMonthly(GList *recurrences);
/** @return True if the recurrence list is a common "weekly" recurrence. **/
-gboolean recurrenceListIsWeeklyMultiple(GList *recurrences);
+gboolean recurrenceListIsWeeklyMultiple(const GList *recurrences);
/**
* Pretty-print an intentionally-short summary of the period of a (GList of)
Modified: gnucash/trunk/src/engine/SX-book.c
===================================================================
--- gnucash/trunk/src/engine/SX-book.c 2011-01-09 18:00:32 UTC (rev 20041)
+++ gnucash/trunk/src/engine/SX-book.c 2011-01-09 18:01:47 UTC (rev 20042)
@@ -125,7 +125,7 @@
static void
sxtg_book_end (QofBook *book)
{
- gnc_book_set_template_root (book, NULL);
+// gnc_book_set_template_root (book, NULL);
}
static gboolean
Modified: gnucash/trunk/src/engine/SchedXaction.c
===================================================================
--- gnucash/trunk/src/engine/SchedXaction.c 2011-01-09 18:00:32 UTC (rev 20041)
+++ gnucash/trunk/src/engine/SchedXaction.c 2011-01-09 18:01:47 UTC (rev 20042)
@@ -483,11 +483,15 @@
/*
* xaccAccountDestroy removes the account from
- * its group for us AFAICT
+ * its group for us AFAICT. If shutting down,
+ * the account is being deleted separately.
*/
- xaccAccountBeginEdit(sx->template_acct);
- xaccAccountDestroy(sx->template_acct);
+ if (!qof_book_shutting_down(qof_instance_get_book(sx)))
+ {
+ xaccAccountBeginEdit(sx->template_acct);
+ xaccAccountDestroy(sx->template_acct);
+ }
for ( l = sx->deferredList; l; l = l->next )
{
@@ -1248,6 +1252,9 @@
* temporal-state-data instance list. The list should not be modified by the
* caller; use the gnc_sx_{add,remove}_defer_instance() functions to modifiy
* the list.
+ *
+ * @param sx Scheduled transaction
+ * @return Defer list which must not be modified by the caller
**/
GList*
gnc_sx_get_defer_instances( SchedXaction *sx )
@@ -1255,6 +1262,29 @@
return sx->deferredList;
}
+static void
+destroy_sx_on_book_close(QofInstance *ent, gpointer data)
+{
+ SchedXaction* sx = GNC_SCHEDXACTION(ent);
+
+ gnc_sx_begin_edit(sx);
+ xaccSchedXactionDestroy(sx);
+}
+
+/**
+ * Destroys all SXes in the book because the book is being destroyed.
+ *
+ * @param book Book being destroyed
+ */
+static void
+gnc_sx_book_end(QofBook* book)
+{
+ QofCollection *col;
+
+ col = qof_book_get_collection(book, GNC_ID_SCHEDXACTION);
+ qof_collection_foreach(col, destroy_sx_on_book_close, NULL);
+}
+
#ifdef _MSC_VER
/* MSVC compiler doesn't have C99 "designated initializers"
* so we wrap them in a macro that is empty on MSVC. */
@@ -1269,7 +1299,7 @@
DI(.type_label = ) "Scheduled Transaction",
DI(.create = ) (gpointer)xaccSchedXactionMalloc,
DI(.book_begin = ) NULL,
- DI(.book_end = ) NULL,
+ DI(.book_end = ) gnc_sx_book_end,
DI(.is_dirty = ) qof_collection_is_dirty,
DI(.mark_clean = ) qof_collection_mark_clean,
DI(.foreach = ) qof_collection_foreach,
Modified: gnucash/trunk/src/engine/Transaction.c
===================================================================
--- gnucash/trunk/src/engine/Transaction.c 2011-01-09 18:00:32 UTC (rev 20041)
+++ gnucash/trunk/src/engine/Transaction.c 2011-01-09 18:01:47 UTC (rev 20042)
@@ -1182,14 +1182,26 @@
qof_event_gen (&trans->inst, QOF_EVENT_DESTROY, NULL);
- /* We only own the splits that still think they belong to us. */
- trans->splits = g_list_copy(trans->splits);
+ /* We only own the splits that still think they belong to us. This is done
+ in 2 steps. In the first, the splits are marked as being destroyed, but they
+ are not destroyed yet. In the second, the destruction is committed which will
+ do the actual destruction. If both steps are done for a split before they are
+ done for the next split, then a split will still be on the split list after it
+ has been freed. This can cause other parts of the code (e.g. in xaccSplitDestroy())
+ to reference the split after it has been freed. */
for (node = trans->splits; node; node = node->next)
{
Split *s = node->data;
if (s->parent == trans)
{
xaccSplitDestroy(s);
+ }
+ }
+ for (node = trans->splits; node; node = node->next)
+ {
+ Split *s = node->data;
+ if (s->parent == trans)
+ {
xaccSplitCommitEdit(s);
}
}
@@ -2296,6 +2308,27 @@
\********************************************************************/
/* QofObject function implementation */
+static void
+destroy_tx_on_book_close(QofInstance *ent, gpointer data)
+{
+ Transaction* tx = GNC_TRANSACTION(ent);
+
+ xaccTransDestroy(tx);
+}
+
+/** Handles book end - frees all transactions from the book
+ *
+ * @param book Book being closed
+ */
+static void
+gnc_transaction_book_end(QofBook* book)
+{
+ QofCollection *col;
+
+ col = qof_book_get_collection(book, GNC_ID_TRANS);
+ qof_collection_foreach(col, destroy_tx_on_book_close, NULL);
+}
+
#ifdef _MSC_VER
/* MSVC compiler doesn't have C99 "designated initializers"
* so we wrap them in a macro that is empty on MSVC. */
@@ -2312,7 +2345,7 @@
DI(.type_label = ) "Transaction",
DI(.create = ) (gpointer)xaccMallocTransaction,
DI(.book_begin = ) NULL,
- DI(.book_end = ) NULL,
+ DI(.book_end = ) gnc_transaction_book_end,
DI(.is_dirty = ) qof_collection_is_dirty,
DI(.mark_clean = ) qof_collection_mark_clean,
DI(.foreach = ) qof_collection_foreach,
Modified: gnucash/trunk/src/engine/engine.i
===================================================================
--- gnucash/trunk/src/engine/engine.i 2011-01-09 18:00:32 UTC (rev 20041)
+++ gnucash/trunk/src/engine/engine.i 2011-01-09 18:01:47 UTC (rev 20042)
@@ -134,11 +134,14 @@
{
SCM key_scm = SCM_CAR (path_scm);
char *key;
+ gchar* gkey;
if (!scm_is_string (key_scm))
break;
- key = g_strdup (scm_to_locale_string (key_scm));
+ key = scm_to_locale_string (key_scm);
+ gkey = g_strdup (key);
+ gnc_free_scm_locale_string(key);
path = g_list_prepend (path, key);
Modified: gnucash/trunk/src/engine/gnc-lot.c
===================================================================
--- gnucash/trunk/src/engine/gnc-lot.c 2011-01-09 18:00:32 UTC (rev 20041)
+++ gnucash/trunk/src/engine/gnc-lot.c 2011-01-09 18:01:47 UTC (rev 20042)
@@ -614,6 +614,23 @@
/* ============================================================= */
+static void
+destroy_lot_on_book_close(QofInstance *ent, gpointer data)
+{
+ GNCLot* lot = GNC_LOT(ent);
+
+ gnc_lot_destroy(lot);
+}
+
+static void
+gnc_lot_book_end(QofBook* book)
+{
+ QofCollection *col;
+
+ col = qof_book_get_collection(book, GNC_ID_LOT);
+ qof_collection_foreach(col, destroy_lot_on_book_close, NULL);
+}
+
#ifdef _MSC_VER
/* MSVC compiler doesn't have C99 "designated initializers"
* so we wrap them in a macro that is empty on MSVC. */
@@ -628,7 +645,7 @@
DI(.type_label = ) "Lot",
DI(.create = ) (gpointer)gnc_lot_new,
DI(.book_begin = ) NULL,
- DI(.book_end = ) NULL,
+ DI(.book_end = ) gnc_lot_book_end,
DI(.is_dirty = ) qof_collection_is_dirty,
DI(.mark_clean = ) qof_collection_mark_clean,
DI(.foreach = ) qof_collection_foreach,
More information about the gnucash-changes
mailing list