[Gnucash-changes] Eliminate a double free of memory.
hampton-gnucash at rainbolthampton.net
Thu Jun 2 18:55:18 EDT 2005
On Thu, 2005-06-02 at 17:33 -0400, Derek Atkins wrote:
> Quoting David Hampton <hampton-gnucash at rainbolthampton.net>:
> > I think this will work because gtk_widget_destroy correctly handles
> > recursive invocation. If the widget is already in the process of being
> > destroyed then the call to gtk_widget_destroy from
> > gnc_customer_window_close_handler is a noop, otherwise it will actually
> > destroy the dialog.
> What if the gtk_widget_destroy() finishes and returns before the CM callback
> happens? For example, if the CM events are suspended, the CM system will cache
> the event and then return, causing gtk_widget_destroy() to finish. Then later
> when the events are resumed it will call the CM callback which will call
> gtk_widget_destroy() on the already-freed widget. Wouldn't that be a problem?
It might be possible to add a call to g_signal_connect_after(cw->dialog,
"destroy", gtk_widget_destroyed, &cw->dialog) when the dialog is created
to resolve this case. If the window destruction completes before the
CM close function is called, then this new callback will have zeroed the
Of course, since the gnc_customer_window_close_handler function frees
cw, it would have to remove this callback so the original invocation
order we were discussing won't write to freed memory. I don't know if
this will work though as I don't know if glib handles deleting callback
functions from within a callback. It appears that glib builds an
ordered list of all handlers before calling the first handler, so the
above solution will not work for all cases.
I suppose this could be flipped and the gnc_customer_window_destroy_cb
callback could be connected "after" the gtk_widget_destroyed handler.
In this case if the dialog has been closed via the window manager close
button cw->dialog will always be NULL regardless of whether the CM
callback runs immediately or at some later time. If the dialog has been
closed some other way, then cw->dialog will be non-NULL and this
function can call gtk_widget_destroy. I think this works.
More information about the gnucash-devel