Skip to content

Commit

Permalink
Bug 797165 - Crash on price deletion.
Browse files Browse the repository at this point in the history
Caused by the introduction of caching used in gnc_pricedb_nth_price,
when prices were deleted, the cached list was never updated and so the
tree model could reference a deleted price and hence crash. This also
affected adding prices as the new prices would not show due to the
cache not being updated. To fix this a function was added to reset the
cache when prices are updated from the model.
  • Loading branch information
Bob-IT committed Apr 26, 2019
1 parent 9f0558f commit 4368e18
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 5 deletions.
12 changes: 8 additions & 4 deletions gnucash/gnome-utils/gnc-tree-model-price.c
Expand Up @@ -1474,7 +1474,7 @@ gnc_tree_model_price_row_delete (GncTreeModelPrice *model,
* item removal.
*/
static gboolean
gnc_tree_model_price_do_deletions (gpointer unused)
gnc_tree_model_price_do_deletions (gpointer price_db)
{
ENTER(" ");

Expand All @@ -1490,6 +1490,7 @@ gnc_tree_model_price_do_deletions (gpointer unused)

/* Remove the path. */
gnc_tree_model_price_row_delete(data->model, data->path);
gnc_pricedb_nth_price_reset_cache (price_db);

gtk_tree_path_free(data->path);
g_free(data);
Expand Down Expand Up @@ -1540,6 +1541,7 @@ gnc_tree_model_price_event_handler (QofInstance *entity,
gpointer event_data)
{
GncTreeModelPrice *model;
GncTreeModelPricePrivate *priv;
GtkTreePath *path;
GtkTreeIter iter;
remove_data *data;
Expand All @@ -1548,10 +1550,11 @@ gnc_tree_model_price_event_handler (QofInstance *entity,
ENTER("entity %p, event %d, model %p, event data %p",
entity, event_type, user_data, event_data);
model = (GncTreeModelPrice *)user_data;
priv = GNC_TREE_MODEL_PRICE_GET_PRIVATE(model);

/* Do deletions if any are pending. */
if (pending_removals)
gnc_tree_model_price_do_deletions(NULL);
gnc_tree_model_price_do_deletions (priv->price_db);

/* hard failures */
g_return_if_fail(GNC_IS_TREE_MODEL_PRICE(model));
Expand Down Expand Up @@ -1611,8 +1614,9 @@ gnc_tree_model_price_event_handler (QofInstance *entity,
switch (event_type)
{
case QOF_EVENT_ADD:
/* Tell the filters/views where the new account was added. */
/* Tell the filters/views where the new price was added. */
DEBUG("add %s", name);
gnc_pricedb_nth_price_reset_cache (priv->price_db);
gnc_tree_model_price_row_add (model, &iter);
break;

Expand All @@ -1631,7 +1635,7 @@ gnc_tree_model_price_event_handler (QofInstance *entity,
data->path = path;
pending_removals = g_slist_append (pending_removals, data);
g_idle_add_full(G_PRIORITY_HIGH_IDLE,
gnc_tree_model_price_do_deletions, NULL, NULL);
gnc_tree_model_price_do_deletions, priv->price_db, NULL);

LEAVE(" ");
return;
Expand Down
1 change: 1 addition & 0 deletions libgnucash/engine/gnc-pricedb-p.h
Expand Up @@ -57,6 +57,7 @@ struct gnc_price_db_s
QofInstance inst; /* globally unique object identifier */
GHashTable *commodity_hash;
gboolean bulk_update; /* TRUE while reading XML file, etc. */
gboolean reset_nth_price_cache;
};

struct _GncPriceDBClass
Expand Down
12 changes: 11 additions & 1 deletion libgnucash/engine/gnc-pricedb.c
Expand Up @@ -839,6 +839,7 @@ QOF_GOBJECT_IMPL(gnc_pricedb, GNCPriceDB, QOF_TYPE_INSTANCE);
static void
gnc_pricedb_init(GNCPriceDB* pdb)
{
pdb->reset_nth_price_cache = FALSE;
}

static void
Expand Down Expand Up @@ -2202,7 +2203,7 @@ gnc_pricedb_nth_price (GNCPriceDB *db,
if (!db || !c || n < 0) return NULL;
ENTER ("db=%p commodity=%s index=%d", db, gnc_commodity_get_mnemonic(c), n);

if (last_c && prices && last_c == c)
if (last_c && prices && last_c == c && db->reset_nth_price_cache == FALSE)
{
result = g_list_nth_data (prices, n);
LEAVE ("price=%p", result);
Expand All @@ -2217,6 +2218,8 @@ gnc_pricedb_nth_price (GNCPriceDB *db,
prices = NULL;
}

db->reset_nth_price_cache = FALSE;

currency_hash = g_hash_table_lookup (db->commodity_hash, c);
if (currency_hash)
{
Expand All @@ -2230,6 +2233,13 @@ gnc_pricedb_nth_price (GNCPriceDB *db,
return result;
}

void
gnc_pricedb_nth_price_reset_cache (GNCPriceDB *db)
{
if (db)
db->reset_nth_price_cache = TRUE;
}

GNCPrice *
gnc_pricedb_lookup_day_t64(GNCPriceDB *db,
const gnc_commodity *c,
Expand Down
2 changes: 2 additions & 0 deletions libgnucash/engine/gnc-pricedb.h
Expand Up @@ -633,6 +633,8 @@ gnc_pricedb_nth_price (GNCPriceDB *db,
const gnc_commodity *c,
const int n);

void gnc_pricedb_nth_price_reset_cache (GNCPriceDB *db);

/* The following two convenience functions are used to test the xml backend */
/** @brief Return the number of prices in the database.
*
Expand Down

0 comments on commit 4368e18

Please sign in to comment.