ref: bf2f9ea62a48d70496057e4f7e444e746e61f462
parent: 8040eba4c0f8a0996eb6487104646a0e5b261ee7
author: Simon Howard <[email protected]>
date: Sat Sep 9 12:48:09 EDT 2006
Add reference counts on callback tables so that if a callback destroys the widget that owns the callback the program doesnt crash. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 599
--- a/textscreen/txt_widget.c
+++ b/textscreen/txt_widget.c
@@ -33,6 +33,7 @@
struct txt_callback_table_s
{
+ int refcount;
txt_callback_t *callbacks;
int num_callbacks;
};
@@ -44,21 +45,34 @@
table = malloc(sizeof(txt_callback_table_t));
table->callbacks = NULL;
table->num_callbacks = 0;
+ table->refcount = 1;
return table;
}
-void TXT_DestroyCallbackTable(txt_callback_table_t *table)
+void TXT_RefCallbackTable(txt_callback_table_t *table)
{
+ ++table->refcount;
+}
+
+void TXT_UnrefCallbackTable(txt_callback_table_t *table)
+{
int i;
- for (i=0; i<table->num_callbacks; ++i)
+ --table->refcount;
+
+ if (table->refcount == 0)
{
- free(table->callbacks[i].signal_name);
- }
+ // No more references to this table
+
+ for (i=0; i<table->num_callbacks; ++i)
+ {
+ free(table->callbacks[i].signal_name);
+ }
- free(table->callbacks);
- free(table);
+ free(table->callbacks);
+ free(table);
+ }
}
void TXT_InitWidget(TXT_UNCAST_ARG(widget), txt_widget_class_t *widget_class)
@@ -111,6 +125,11 @@
table = widget->callback_table;
+ // Don't destroy the table while we're searching through it
+ // (one of the callbacks may destroy this window)
+
+ TXT_RefCallbackTable(table);
+
// Search the table for all callbacks with this name and invoke
// the functions.
@@ -121,6 +140,10 @@
table->callbacks[i].func(widget, table->callbacks[i].user_data);
}
}
+
+ // Finished using the table
+
+ TXT_UnrefCallbackTable(table);
}
void TXT_CalcWidgetSize(TXT_UNCAST_ARG(widget))
@@ -148,7 +171,7 @@
TXT_CAST_ARG(txt_widget_t, widget);
widget->widget_class->destructor(widget);
- TXT_DestroyCallbackTable(widget->callback_table);
+ TXT_UnrefCallbackTable(widget->callback_table);
free(widget);
}