diff options
author | Tim Janik <timj@gimp.org> | 1998-02-10 06:53:08 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 1998-02-10 06:53:08 +0000 |
commit | 6898536a026027839cf1f6662f30f793dbe4e8d3 (patch) | |
tree | 0ab69467c31ba342957802e0e94aa7698f2e59b1 | |
parent | f98686da856ea0c0dfb6050f233c0cb02ee8c861 (diff) | |
download | gtk+-6898536a026027839cf1f6662f30f793dbe4e8d3.tar.gz |
ok, there have been several severe bugs in the signal handler referencing
Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org>
* gtk/gtksignal.h:
* gtk/gtksignal.c:
ok, there have been several severe bugs in the signal handler
referencing and ->next connection stuff. these bugs caused
invokations of handlers that are disconnected and - worse -
destroyed already. invokation of *destroyd* handlers mean:
anything can be executed , because the handler structure can just
as well be realocated.
at the cost of an extra ->prev field per handler we should have a
reasonable stable system now, because of the various places that
can cause a handler to be disconnected (*any* handler invokation can
cause *any* or *all* handlers to be disconnected, there is no way
around a doubly linked list, actually handler disconnection has never
worked correctly because of this.
handlers are connected together via a *doubly* linked list now, and it
is *not* valid to remove a handler out of this list untill all its
references have been droped, i.e. handler->ref_count==0.
to prevent emissions of disconnected but still referenced handlers,
disconnected handlers are simply marked as blocked and get an id of 0
which is an invalid signal handler id.
the handler->id has been changed to have 28 significant bits (using
alignment gaps), since 65536 (old range: guint16) signal connections
(as a total) can easily be reached by complex applications.
this whole handler thingy is at least as tedious as writing doubly
linked list implementations ;)
-rw-r--r-- | ChangeLog | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 28 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 28 | ||||
-rw-r--r-- | gtk/gtkmain.c | 16 | ||||
-rw-r--r-- | gtk/gtksignal.c | 241 | ||||
-rw-r--r-- | gtk/gtksignal.h | 9 |
10 files changed, 326 insertions, 136 deletions
@@ -1,3 +1,31 @@ +Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org> + + * gtk/gtksignal.h: + * gtk/gtksignal.c: + ok, there have been several severe bugs in the signal handler + referencing and ->next connection stuff. these bugs caused + invokations of handlers that are disconnected and - worse - + destroyed already. invokation of *destroyd* handlers mean: + anything can be executed , because the handler structure can just + as well be realocated. + at the cost of an extra ->prev field per handler we should have a + reasonable stable system now, because of the various places that + can cause a handler to be disconnected (*any* handler invokation can + cause *any* or *all* handlers to be disconnected, there is no way + around a doubly linked list, actually handler disconnection has never + worked correctly because of this. + handlers are connected together via a *doubly* linked list now, and it + is *not* valid to remove a handler out of this list untill all its + references have been droped, i.e. handler->ref_count==0. + to prevent emissions of disconnected but still referenced handlers, + disconnected handlers are simply marked as blocked and get an id of 0 + which is an invalid signal handler id. + the handler->id has been changed to have 28 significant bits (using + alignment gaps), since 65536 (old range: guint16) signal connections + (as a total) can easily be reached by complex applications. + this whole handler thingy is at least as tedious as writing doubly + linked list implementations ;) + Mon Feb 9 23:08:16 1998 Owen Taylor <owt1@cornell.edu> * gtk/gtkwidget.c (gtk_widget_unparent): Check for diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index d6f2beb9d6..2565d72961 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,31 @@ +Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org> + + * gtk/gtksignal.h: + * gtk/gtksignal.c: + ok, there have been several severe bugs in the signal handler + referencing and ->next connection stuff. these bugs caused + invokations of handlers that are disconnected and - worse - + destroyed already. invokation of *destroyd* handlers mean: + anything can be executed , because the handler structure can just + as well be realocated. + at the cost of an extra ->prev field per handler we should have a + reasonable stable system now, because of the various places that + can cause a handler to be disconnected (*any* handler invokation can + cause *any* or *all* handlers to be disconnected, there is no way + around a doubly linked list, actually handler disconnection has never + worked correctly because of this. + handlers are connected together via a *doubly* linked list now, and it + is *not* valid to remove a handler out of this list untill all its + references have been droped, i.e. handler->ref_count==0. + to prevent emissions of disconnected but still referenced handlers, + disconnected handlers are simply marked as blocked and get an id of 0 + which is an invalid signal handler id. + the handler->id has been changed to have 28 significant bits (using + alignment gaps), since 65536 (old range: guint16) signal connections + (as a total) can easily be reached by complex applications. + this whole handler thingy is at least as tedious as writing doubly + linked list implementations ;) + Mon Feb 9 23:08:16 1998 Owen Taylor <owt1@cornell.edu> * gtk/gtkwidget.c (gtk_widget_unparent): Check for diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index d6f2beb9d6..2565d72961 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,31 @@ +Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org> + + * gtk/gtksignal.h: + * gtk/gtksignal.c: + ok, there have been several severe bugs in the signal handler + referencing and ->next connection stuff. these bugs caused + invokations of handlers that are disconnected and - worse - + destroyed already. invokation of *destroyd* handlers mean: + anything can be executed , because the handler structure can just + as well be realocated. + at the cost of an extra ->prev field per handler we should have a + reasonable stable system now, because of the various places that + can cause a handler to be disconnected (*any* handler invokation can + cause *any* or *all* handlers to be disconnected, there is no way + around a doubly linked list, actually handler disconnection has never + worked correctly because of this. + handlers are connected together via a *doubly* linked list now, and it + is *not* valid to remove a handler out of this list untill all its + references have been droped, i.e. handler->ref_count==0. + to prevent emissions of disconnected but still referenced handlers, + disconnected handlers are simply marked as blocked and get an id of 0 + which is an invalid signal handler id. + the handler->id has been changed to have 28 significant bits (using + alignment gaps), since 65536 (old range: guint16) signal connections + (as a total) can easily be reached by complex applications. + this whole handler thingy is at least as tedious as writing doubly + linked list implementations ;) + Mon Feb 9 23:08:16 1998 Owen Taylor <owt1@cornell.edu> * gtk/gtkwidget.c (gtk_widget_unparent): Check for diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index d6f2beb9d6..2565d72961 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,31 @@ +Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org> + + * gtk/gtksignal.h: + * gtk/gtksignal.c: + ok, there have been several severe bugs in the signal handler + referencing and ->next connection stuff. these bugs caused + invokations of handlers that are disconnected and - worse - + destroyed already. invokation of *destroyd* handlers mean: + anything can be executed , because the handler structure can just + as well be realocated. + at the cost of an extra ->prev field per handler we should have a + reasonable stable system now, because of the various places that + can cause a handler to be disconnected (*any* handler invokation can + cause *any* or *all* handlers to be disconnected, there is no way + around a doubly linked list, actually handler disconnection has never + worked correctly because of this. + handlers are connected together via a *doubly* linked list now, and it + is *not* valid to remove a handler out of this list untill all its + references have been droped, i.e. handler->ref_count==0. + to prevent emissions of disconnected but still referenced handlers, + disconnected handlers are simply marked as blocked and get an id of 0 + which is an invalid signal handler id. + the handler->id has been changed to have 28 significant bits (using + alignment gaps), since 65536 (old range: guint16) signal connections + (as a total) can easily be reached by complex applications. + this whole handler thingy is at least as tedious as writing doubly + linked list implementations ;) + Mon Feb 9 23:08:16 1998 Owen Taylor <owt1@cornell.edu> * gtk/gtkwidget.c (gtk_widget_unparent): Check for diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index d6f2beb9d6..2565d72961 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,31 @@ +Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org> + + * gtk/gtksignal.h: + * gtk/gtksignal.c: + ok, there have been several severe bugs in the signal handler + referencing and ->next connection stuff. these bugs caused + invokations of handlers that are disconnected and - worse - + destroyed already. invokation of *destroyd* handlers mean: + anything can be executed , because the handler structure can just + as well be realocated. + at the cost of an extra ->prev field per handler we should have a + reasonable stable system now, because of the various places that + can cause a handler to be disconnected (*any* handler invokation can + cause *any* or *all* handlers to be disconnected, there is no way + around a doubly linked list, actually handler disconnection has never + worked correctly because of this. + handlers are connected together via a *doubly* linked list now, and it + is *not* valid to remove a handler out of this list untill all its + references have been droped, i.e. handler->ref_count==0. + to prevent emissions of disconnected but still referenced handlers, + disconnected handlers are simply marked as blocked and get an id of 0 + which is an invalid signal handler id. + the handler->id has been changed to have 28 significant bits (using + alignment gaps), since 65536 (old range: guint16) signal connections + (as a total) can easily be reached by complex applications. + this whole handler thingy is at least as tedious as writing doubly + linked list implementations ;) + Mon Feb 9 23:08:16 1998 Owen Taylor <owt1@cornell.edu> * gtk/gtkwidget.c (gtk_widget_unparent): Check for diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index d6f2beb9d6..2565d72961 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,31 @@ +Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org> + + * gtk/gtksignal.h: + * gtk/gtksignal.c: + ok, there have been several severe bugs in the signal handler + referencing and ->next connection stuff. these bugs caused + invokations of handlers that are disconnected and - worse - + destroyed already. invokation of *destroyd* handlers mean: + anything can be executed , because the handler structure can just + as well be realocated. + at the cost of an extra ->prev field per handler we should have a + reasonable stable system now, because of the various places that + can cause a handler to be disconnected (*any* handler invokation can + cause *any* or *all* handlers to be disconnected, there is no way + around a doubly linked list, actually handler disconnection has never + worked correctly because of this. + handlers are connected together via a *doubly* linked list now, and it + is *not* valid to remove a handler out of this list untill all its + references have been droped, i.e. handler->ref_count==0. + to prevent emissions of disconnected but still referenced handlers, + disconnected handlers are simply marked as blocked and get an id of 0 + which is an invalid signal handler id. + the handler->id has been changed to have 28 significant bits (using + alignment gaps), since 65536 (old range: guint16) signal connections + (as a total) can easily be reached by complex applications. + this whole handler thingy is at least as tedious as writing doubly + linked list implementations ;) + Mon Feb 9 23:08:16 1998 Owen Taylor <owt1@cornell.edu> * gtk/gtkwidget.c (gtk_widget_unparent): Check for diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index d6f2beb9d6..2565d72961 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,31 @@ +Tue Feb 10 07:12:07 1998 Tim Janik <timj@gimp.org> + + * gtk/gtksignal.h: + * gtk/gtksignal.c: + ok, there have been several severe bugs in the signal handler + referencing and ->next connection stuff. these bugs caused + invokations of handlers that are disconnected and - worse - + destroyed already. invokation of *destroyd* handlers mean: + anything can be executed , because the handler structure can just + as well be realocated. + at the cost of an extra ->prev field per handler we should have a + reasonable stable system now, because of the various places that + can cause a handler to be disconnected (*any* handler invokation can + cause *any* or *all* handlers to be disconnected, there is no way + around a doubly linked list, actually handler disconnection has never + worked correctly because of this. + handlers are connected together via a *doubly* linked list now, and it + is *not* valid to remove a handler out of this list untill all its + references have been droped, i.e. handler->ref_count==0. + to prevent emissions of disconnected but still referenced handlers, + disconnected handlers are simply marked as blocked and get an id of 0 + which is an invalid signal handler id. + the handler->id has been changed to have 28 significant bits (using + alignment gaps), since 65536 (old range: guint16) signal connections + (as a total) can easily be reached by complex applications. + this whole handler thingy is at least as tedious as writing doubly + linked list implementations ;) + Mon Feb 9 23:08:16 1998 Owen Taylor <owt1@cornell.edu> * gtk/gtkwidget.c (gtk_widget_unparent): Check for diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index c069f62cdb..e442172454 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -100,7 +100,7 @@ static void gtk_message (gchar *str); static void gtk_print (gchar *str); -static gint done; +static gboolean iteration_done = FALSE; static guint main_level = 0; static gint initialized = FALSE; static GdkEvent *next_event = NULL; @@ -214,10 +214,10 @@ gtk_main () g_list_free (functions); - old_done = done; + old_done = iteration_done; while (!gtk_main_iteration ()) ; - done = old_done; + iteration_done = old_done; main_level--; } @@ -231,7 +231,7 @@ gtk_main_level (void) void gtk_main_quit () { - done = TRUE; + iteration_done = TRUE; } gint @@ -254,7 +254,7 @@ gtk_main_iteration_do (gboolean blocking) GdkEvent *event = NULL; GList *tmp_list; - done = FALSE; + iteration_done = FALSE; /* If this is a recursive call, and there are pending timeouts or * idles, finish them, then return immediately to avoid blocking @@ -263,12 +263,12 @@ gtk_main_iteration_do (gboolean blocking) if (current_timeouts) { gtk_handle_current_timeouts( gdk_time_get()); - return done; + return iteration_done; } if (current_idles) { gtk_handle_current_idles(); - return done; + return iteration_done; } /* If there is a valid event in 'next_event' then move it to 'event' @@ -479,7 +479,7 @@ event_handling_done: */ gtk_handle_timeouts (); - return done; + return iteration_done; } gint diff --git a/gtk/gtksignal.c b/gtk/gtksignal.c index 1711996af3..e9d3a854dc 100644 --- a/gtk/gtksignal.c +++ b/gtk/gtksignal.c @@ -119,8 +119,8 @@ static void gtk_params_get (GtkArg *params, static gint initialize = TRUE; static GHashTable *signal_hash_table = NULL; static GHashTable *signal_info_hash_table = NULL; -static gint next_signal = 1; -static gint next_handler_id = 1; +static guint next_signal = 1; +static guint next_handler_id = 1; static const gchar *handler_key = "gtk-signal-handlers"; @@ -600,62 +600,56 @@ gtk_signal_connect_object_while_alive (GtkObject *object, void gtk_signal_disconnect (GtkObject *object, - gint anid) + gint an_id) { - GtkHandler *tmp; - GtkHandler *prev; + GtkHandler *handler; g_return_if_fail (object != NULL); + g_return_if_fail (an_id > 0); - if (initialize) - gtk_signal_init (); - - prev = NULL; - tmp = gtk_object_get_data (object, handler_key); + handler = gtk_object_get_data (object, handler_key); - while (tmp) + while (handler) { - if (tmp->id == anid) + if (handler->id == an_id) { - if (prev) - prev->next = tmp->next; - else - gtk_signal_handler_unref (tmp, object); + handler->id = 0; + handler->blocked = TRUE; + gtk_signal_handler_unref (handler, object); return; } - - prev = tmp; - tmp = tmp->next; + handler = handler->next; } - g_warning ("gtk_signal_disconnect(): could not find handler (%d)", anid); + g_warning ("gtk_signal_disconnect(): could not find handler (%d)", an_id); } void gtk_signal_disconnect_by_data (GtkObject *object, gpointer data) { - GtkHandler *tmp; - GtkHandler *next; + GtkHandler *handler; gint found_one; - + g_return_if_fail (object != NULL); - - if (initialize) - gtk_signal_init (); - - tmp = gtk_object_get_data (object, handler_key); + found_one = FALSE; - - while (tmp) + handler = gtk_object_get_data (object, handler_key); + + while (handler) { - next = tmp->next; - if (tmp->func_data == data) + GtkHandler *handler_next; + + handler_next = handler->next; + if (handler->func_data == data && + handler->id > 0) { found_one = TRUE; - gtk_signal_handler_unref (tmp, object); + handler->id = 0; + handler->blocked = TRUE; + gtk_signal_handler_unref (handler, object); } - tmp = next; + handler = handler_next; } if (!found_one) @@ -664,20 +658,18 @@ gtk_signal_disconnect_by_data (GtkObject *object, void gtk_signal_handler_block (GtkObject *object, - gint anid) + gint an_id) { GtkHandler *tmp; g_return_if_fail (object != NULL); - - if (initialize) - gtk_signal_init (); + g_return_if_fail (an_id > 0); tmp = gtk_object_get_data (object, handler_key); while (tmp) { - if (tmp->id == anid) + if (tmp->id == an_id) { tmp->blocked = TRUE; return; @@ -686,14 +678,14 @@ gtk_signal_handler_block (GtkObject *object, tmp = tmp->next; } - g_warning ("gtk_signal_handler_block(): could not find handler (%d)", anid); + g_warning ("gtk_signal_handler_block(): could not find handler (%d)", an_id); } void gtk_signal_handler_block_by_data (GtkObject *object, gpointer data) { - GtkHandler *tmp; + GtkHandler *handler; gint found_one; g_return_if_fail (object != NULL); @@ -702,17 +694,18 @@ gtk_signal_handler_block_by_data (GtkObject *object, gtk_signal_init (); found_one = FALSE; - tmp = gtk_object_get_data (object, handler_key); + handler = gtk_object_get_data (object, handler_key); - while (tmp) + while (handler) { - if (tmp->func_data == data) + if (handler->func_data == data && + handler->id > 0) { - tmp->blocked = TRUE; found_one = TRUE; + handler->blocked = TRUE; } - tmp = tmp->next; + handler = handler->next; } if (!found_one) @@ -721,36 +714,37 @@ gtk_signal_handler_block_by_data (GtkObject *object, void gtk_signal_handler_unblock (GtkObject *object, - gint anid) + gint an_id) { - GtkHandler *tmp; + GtkHandler *handler; g_return_if_fail (object != NULL); + g_return_if_fail (an_id > 0); if (initialize) gtk_signal_init (); - tmp = gtk_object_get_data (object, handler_key); + handler = gtk_object_get_data (object, handler_key); - while (tmp) + while (handler) { - if (tmp->id == anid) + if (handler->id == an_id) { - tmp->blocked = FALSE; + handler->blocked = FALSE; return; } - tmp = tmp->next; + handler = handler->next; } - g_warning ("gtk_signal_handler_unblock(): could not find handler (%d)", anid); + g_warning ("gtk_signal_handler_unblock(): could not find handler (%d)", an_id); } void gtk_signal_handler_unblock_by_data (GtkObject *object, gpointer data) { - GtkHandler *tmp; + GtkHandler *handler; gint found_one; g_return_if_fail (object != NULL); @@ -759,17 +753,18 @@ gtk_signal_handler_unblock_by_data (GtkObject *object, gtk_signal_init (); found_one = FALSE; - tmp = gtk_object_get_data (object, handler_key); + handler = gtk_object_get_data (object, handler_key); - while (tmp) + while (handler) { - if (tmp->func_data == data) + if (handler->func_data == data && + handler->id > 0) { - tmp->blocked = FALSE; found_one = TRUE; + handler->blocked = FALSE; } - tmp = tmp->next; + handler = handler->next; } if (!found_one) @@ -779,18 +774,27 @@ gtk_signal_handler_unblock_by_data (GtkObject *object, void gtk_signal_handlers_destroy (GtkObject *object) { - GtkHandler *list; GtkHandler *handler; - list = gtk_object_get_data (object, handler_key); - if (list) + /* we make the "optimization" of destroying the first handler in the last + * place, since we don't want gtk_signal_handler_unref() to reset the objects + * handler_key data on each removal + */ + + handler = gtk_object_get_data (object, handler_key); + if (handler) { - while (list) + handler = handler->next; + while (handler) { - handler = list->next; - gtk_signal_handler_unref (list, object); - list = handler; + GtkHandler *next; + + next = handler->next; + gtk_signal_handler_unref (handler, object); + handler = next; } + handler = gtk_object_get_data (object, handler_key); + gtk_signal_handler_unref (handler, object); } } @@ -870,13 +874,14 @@ gtk_signal_handler_new () handler->id = 0; handler->ref_count = 1; handler->signal_type = 0; - handler->object_signal = FALSE; handler->blocked = FALSE; + handler->object_signal = FALSE; handler->after = FALSE; handler->no_marshal = FALSE; handler->func = NULL; handler->func_data = NULL; handler->destroy_func = NULL; + handler->prev = NULL; handler->next = NULL; return handler; @@ -892,8 +897,6 @@ static void gtk_signal_handler_unref (GtkHandler *handler, GtkObject *object) { - GtkHandler *tmp; - if (!handler->ref_count) { /* FIXME: i wanna get removed some when (maybe at gtk+-1.0?) */ @@ -909,13 +912,13 @@ gtk_signal_handler_unref (GtkHandler *handler, else if (handler->destroy_func) (* handler->destroy_func) (handler->func_data); - tmp = gtk_object_get_data (object, handler_key); - while (tmp && tmp->next != handler) - tmp = tmp->next; - if (tmp) - tmp->next = handler->next; + + if (handler->prev) + handler->prev->next = handler->next; else gtk_object_set_data (object, handler_key, handler->next); + if (handler->next) + handler->next->prev = handler->prev; g_mem_chunk_free (handler_mem_chunk, handler); } @@ -925,42 +928,39 @@ static void gtk_signal_handler_insert (GtkObject *object, GtkHandler *handler) { - GtkHandler *start; GtkHandler *tmp; - GtkHandler *prev; - - start = gtk_object_get_data (object, handler_key); - if (!start) - { - gtk_object_set_data (object, handler_key, handler); - } + + /* FIXME: remove */ g_assert (handler->next == NULL); + /* FIXME: remove */ g_assert (handler->prev == NULL); + + tmp = gtk_object_get_data (object, handler_key); + if (!tmp) + gtk_object_set_data (object, handler_key, handler); else - { - prev = NULL; - tmp = start; - - while (tmp) - { - if (tmp->signal_type < handler->signal_type) - { - if (prev) - prev->next = handler; - else - gtk_object_set_data (object, handler_key, handler); - handler->next = tmp; - break; - } - - if (!tmp->next) - { - tmp->next = handler; - break; - } + while (tmp) + { + if (tmp->signal_type < handler->signal_type) + { + if (tmp->prev) + { + tmp->prev->next = handler; + handler->prev = tmp->prev; + } + else + gtk_object_set_data (object, handler_key, handler); + tmp->prev = handler; + handler->next = tmp; + break; + } - prev = tmp; - tmp = tmp->next; - } - } + if (!tmp->next) + { + tmp->next = handler; + handler->prev = tmp; + break; + } + tmp = tmp->next; + } } static void @@ -1134,9 +1134,7 @@ gtk_signal_connect_by_type (GtkObject *object, handler->func = func; handler->func_data = func_data; handler->destroy_func = destroy_func; - - if (after) - handler->after = TRUE; + handler->after = after != FALSE; handler->no_marshal = no_marshal; gtk_signal_handler_insert (object, handler); @@ -1240,18 +1238,16 @@ gtk_handlers_run (GtkHandler *handlers, GtkHandlerInfo *info, gint after) { - GtkHandler *handlers_next; - while (handlers) { - /* REMOVE: if (!after) */ + GtkHandler *handlers_next; + gtk_signal_handler_ref (handlers); if (handlers->signal_type != info->signal_type) { - /* REMOVE: if (after) */ gtk_signal_handler_unref (handlers, info->object); - break; + return 0; } if (!handlers->blocked && (handlers->after == after)) @@ -1281,17 +1277,16 @@ gtk_handlers_run (GtkHandler *handlers, info->params, info->param_types, info->return_val); - + if (gtk_emission_check (stop_emissions, info->object, info->signal_type)) { gtk_emission_remove (&stop_emissions, info->object, info->signal_type); - + if (info->run_type & GTK_RUN_NO_RECURSE) gtk_emission_remove (&restart_emissions, info->object, info->signal_type); - /* REMOVE: if (after) */ gtk_signal_handler_unref (handlers, info->object); return DONE; } @@ -1301,18 +1296,16 @@ gtk_handlers_run (GtkHandler *handlers, { gtk_emission_remove (&restart_emissions, info->object, info->signal_type); - /* REMOVE: if (after) */ gtk_signal_handler_unref (handlers, info->object); return RESTART; } } - + handlers_next = handlers->next; - /* if (after) */ - gtk_signal_handler_unref (handlers, info->object); + gtk_signal_handler_unref (handlers, info->object); handlers = handlers_next; } - + return 0; } diff --git a/gtk/gtksignal.h b/gtk/gtksignal.h index d03d7d570b..e6c66f031e 100644 --- a/gtk/gtksignal.h +++ b/gtk/gtksignal.h @@ -60,16 +60,17 @@ struct _GtkSignalQuery struct _GtkHandler { - guint16 id; - guint16 ref_count; - guint16 signal_type; - guint object_signal : 1; + guint id : 28; guint blocked : 1; + guint object_signal : 1; guint after : 1; guint no_marshal : 1; + guint16 ref_count; + guint16 signal_type; GtkSignalFunc func; gpointer func_data; GtkSignalDestroy destroy_func; + GtkHandler *prev; GtkHandler *next; }; |