Skip to content
Permalink
Browse files

Plug memory leak in register code

The table storing cell dimensions was never freed. The size of this table is
directly proportional to the number of cells in the register. So the more
transactions/splits in a register, the more memory was leaked - each time
a register was opened and closed. With my huge test book I saw leaks of
4Mb-10Mb per page that was opened/closed.
  • Loading branch information...
gjanssens committed Sep 9, 2018
1 parent 4cc6146 commit 3845611f30848d6aca9b4764e24c050e801e0803
@@ -159,7 +159,6 @@ void gnc_split_reg_sort_action_cb (GtkWidget *w, gpointer data);
void gnc_split_reg_sort_notes_cb (GtkWidget *w, gpointer data);


void gnc_split_reg_destroy_cb(GtkWidget *widget, gpointer data);
void gnc_split_reg_size_allocate( GtkWidget *widget,
GtkAllocation *allocation,
gpointer user_data );
@@ -168,6 +167,7 @@ void gnc_split_reg_size_allocate( GtkWidget *widget,
static void gnc_split_reg_class_init( GNCSplitRegClass *klass );
static void gnc_split_reg_init( GNCSplitReg *gsr );
static void gnc_split_reg_init2( GNCSplitReg *gsr );
void gnc_split_reg_dispose(GObject *obj);

FROM_STRING_FUNC(SortType, ENUM_LIST_SORTTYPE)
AS_STRING_FUNC(SortType, ENUM_LIST_SORTTYPE)
@@ -314,6 +314,8 @@ gnc_split_reg_class_init( GNCSplitRegClass *klass )
klass->help_changed_cb = NULL;
klass->show_popup_menu_cb = NULL;
klass->include_date_cb = NULL;

object_class->dispose = gnc_split_reg_dispose;
}

GtkWidget*
@@ -354,9 +356,6 @@ gnc_split_reg_init( GNCSplitReg *gsr )
gsr->height = -1;
gsr->numRows = 10;
gsr->read_only = FALSE;

g_signal_connect( gsr, "destroy",
G_CALLBACK (gnc_split_reg_destroy_cb), gsr );
}

static void
@@ -444,12 +443,18 @@ gsr_setup_status_widgets( GNCSplitReg *gsr )
}

void
gnc_split_reg_destroy_cb(GtkWidget *widget, gpointer data)
gnc_split_reg_dispose(GObject *obj)
{
GNCSplitReg *gsr = data;
GNCSplitReg *gsr = GNC_SPLIT_REG(obj);

if (gsr->filter_text)
g_free (gsr->filter_text);
gsr->filter_text = NULL;

if (gsr->reg)
g_signal_handlers_disconnect_by_data (gsr->reg, gsr);
gtk_widget_destroy (GTK_WIDGET (gsr->reg));
gsr->reg = NULL;
}

/**
@@ -710,7 +715,9 @@ gnc_split_reg_ld_destroy( GNCLedgerDisplay *ledger )
}
g_free (state_section);
g_free (acct_fullname);

gnc_ledger_display_set_user_data (ledger, NULL);
g_object_unref (gsr);
}

void
@@ -763,6 +763,7 @@ gnucash_sheet_finalize (GObject *object)

sheet = GNUCASH_SHEET (object);

g_table_resize (sheet->blocks, 0, 0);
g_table_destroy (sheet->blocks);
sheet->blocks = NULL;

@@ -2214,7 +2215,7 @@ gnucash_sheet_block_set_from_table (GnucashSheet *sheet,

if (block->style && (block->style != style))
{
gnucash_style_unref (block->style);
gnucash_sheet_style_unref (sheet, block->style);
block->style = NULL;
}

@@ -2223,7 +2224,7 @@ gnucash_sheet_block_set_from_table (GnucashSheet *sheet,
if (block->style == NULL)
{
block->style = style;
gnucash_style_ref(block->style);
gnucash_sheet_style_ref(sheet, block->style);
return TRUE;
}

@@ -2323,14 +2324,15 @@ static void
gnucash_sheet_block_destroy (gpointer _block, gpointer user_data)
{
SheetBlock *block = _block;
GnucashSheet *sheet = GNUCASH_SHEET(user_data);

if (block == NULL)
return;

if (block->style)
{
gnucash_style_unref (block->style);
block->style = NULL;
gnucash_sheet_style_unref (sheet, block->style);
/* Don't free the block itself here. It's managed by the block table */
}
}

@@ -2588,7 +2590,7 @@ gnucash_sheet_init (GnucashSheet *sheet)

sheet->blocks = g_table_new (sizeof (SheetBlock),
gnucash_sheet_block_construct,
gnucash_sheet_block_destroy, NULL);
gnucash_sheet_block_destroy, sheet);

gtk_widget_add_events(GTK_WIDGET(sheet), (GDK_EXPOSURE_MASK
| GDK_BUTTON_PRESS_MASK
@@ -2723,7 +2725,7 @@ gnucash_sheet_new (Table *table)
/* some register data */
sheet->dimensions_hash_table = g_hash_table_new_full (g_int_hash,
g_int_equal,
g_free, NULL);
g_free, g_free);

/* add tooltips to sheet */
gtk_widget_set_has_tooltip (GTK_WIDGET(sheet), TRUE);
@@ -99,10 +99,15 @@ style_dimensions_destroy (BlockDimensions *dimensions)
if (dimensions == NULL)
return;

g_table_destroy (dimensions->cell_dimensions);
dimensions->cell_dimensions = NULL;
dimensions->refcount--;

g_free(dimensions);
if (dimensions->refcount == 0)
{
g_table_destroy (dimensions->cell_dimensions);
dimensions->cell_dimensions = NULL;

g_free(dimensions);
}
}


@@ -644,7 +649,7 @@ destroy_style_helper (gpointer key, gpointer value, gpointer user_data)
SheetBlockStyle *style = value;
GnucashSheet *sheet = user_data;

gnucash_sheet_style_destroy (sheet, style);
gnucash_sheet_style_unref (sheet, style);
g_free (cursor_name);
}

@@ -674,10 +679,12 @@ gnucash_sheet_create_styles (GnucashSheet *sheet)
for (node = cursors; node; node = node->next)
{
CellBlock *cursor = node->data;
SheetBlockStyle *style = gnucash_sheet_style_new (sheet, cursor);

gnucash_sheet_style_ref (sheet, style);
g_hash_table_insert (sheet->cursor_styles,
g_strdup (cursor->cursor_name),
gnucash_sheet_style_new (sheet, cursor));
style);
}
}

@@ -798,7 +805,7 @@ gnucash_sheet_get_style_from_cursor (GnucashSheet *sheet,
*/

void
gnucash_style_ref (SheetBlockStyle *style)
gnucash_sheet_style_ref (GnucashSheet *sheet, SheetBlockStyle *style)
{
g_return_if_fail (style != NULL);

@@ -807,14 +814,14 @@ gnucash_style_ref (SheetBlockStyle *style)


void
gnucash_style_unref (SheetBlockStyle *style)
gnucash_sheet_style_unref (GnucashSheet *sheet, SheetBlockStyle *style)
{
g_return_if_fail (style != NULL);

style->refcount--;

if (style->refcount < 0)
g_warning ("Unbalanced Style ref/unref");
if (style->refcount == 0)
gnucash_sheet_style_destroy (sheet, style);
}

typedef struct
@@ -109,8 +109,8 @@ void gnucash_sheet_style_get_cell_pixel_rel_coords (SheetBlockStyle *style,
gint *x, gint *y,
gint *w, gint *h);

void gnucash_style_ref (SheetBlockStyle *style);
void gnucash_style_unref (SheetBlockStyle *style);
void gnucash_sheet_style_ref (GnucashSheet *sheet, SheetBlockStyle *style);
void gnucash_sheet_style_unref (GnucashSheet *sheet, SheetBlockStyle *style);

void gnucash_sheet_get_borders (GnucashSheet *sheet, VirtualLocation virt_loc,
PhysicalCellBorders *borders);

0 comments on commit 3845611

Please sign in to comment.
You can’t perform that action at this time.