sropped the approach of copying all signal specific data into a

Fri Jul 17 05:30:47 1998  Tim Janik  <timj@gtk.org>

        * gtk/gtksignal.c (gtk_handlers_run) (gtk_signal_real_emit):
        sropped the approach of copying all signal specific data into a
        GtkHandlerInfo structure. we rather keep the signal data on the stack
        in gtk_signal_real_emit and pass that over to gtk_handlers_run. this
        avoids multiple lookups of the signal pointer and works savely together
        with destroy notifiers of handlers.

        * gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that
        someone destroys the entry on the ::activate signal.
This commit is contained in:
Tim Janik 1998-07-17 06:10:02 +00:00 committed by Tim Janik
parent ca7b223bf0
commit 2bc6d4548f
8 changed files with 118 additions and 107 deletions

View File

@ -1,5 +1,12 @@
Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org> Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org>
* gtk/gtksignal.c (gtk_handlers_run) (gtk_signal_real_emit):
sropped the approach of copying all signal specific data into a
GtkHandlerInfo structure. we rather keep the signal data on the stack
in gtk_signal_real_emit and pass that over to gtk_handlers_run. this
avoids multiple lookups of the signal pointer and works savely together
with destroy notifiers of handlers.
* gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that * gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that
someone destroys the entry on the ::activate signal. someone destroys the entry on the ::activate signal.

View File

@ -1,5 +1,12 @@
Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org> Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org>
* gtk/gtksignal.c (gtk_handlers_run) (gtk_signal_real_emit):
sropped the approach of copying all signal specific data into a
GtkHandlerInfo structure. we rather keep the signal data on the stack
in gtk_signal_real_emit and pass that over to gtk_handlers_run. this
avoids multiple lookups of the signal pointer and works savely together
with destroy notifiers of handlers.
* gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that * gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that
someone destroys the entry on the ::activate signal. someone destroys the entry on the ::activate signal.

View File

@ -1,5 +1,12 @@
Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org> Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org>
* gtk/gtksignal.c (gtk_handlers_run) (gtk_signal_real_emit):
sropped the approach of copying all signal specific data into a
GtkHandlerInfo structure. we rather keep the signal data on the stack
in gtk_signal_real_emit and pass that over to gtk_handlers_run. this
avoids multiple lookups of the signal pointer and works savely together
with destroy notifiers of handlers.
* gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that * gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that
someone destroys the entry on the ::activate signal. someone destroys the entry on the ::activate signal.

View File

@ -1,5 +1,12 @@
Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org> Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org>
* gtk/gtksignal.c (gtk_handlers_run) (gtk_signal_real_emit):
sropped the approach of copying all signal specific data into a
GtkHandlerInfo structure. we rather keep the signal data on the stack
in gtk_signal_real_emit and pass that over to gtk_handlers_run. this
avoids multiple lookups of the signal pointer and works savely together
with destroy notifiers of handlers.
* gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that * gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that
someone destroys the entry on the ::activate signal. someone destroys the entry on the ::activate signal.

View File

@ -1,5 +1,12 @@
Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org> Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org>
* gtk/gtksignal.c (gtk_handlers_run) (gtk_signal_real_emit):
sropped the approach of copying all signal specific data into a
GtkHandlerInfo structure. we rather keep the signal data on the stack
in gtk_signal_real_emit and pass that over to gtk_handlers_run. this
avoids multiple lookups of the signal pointer and works savely together
with destroy notifiers of handlers.
* gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that * gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that
someone destroys the entry on the ::activate signal. someone destroys the entry on the ::activate signal.

View File

@ -1,5 +1,12 @@
Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org> Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org>
* gtk/gtksignal.c (gtk_handlers_run) (gtk_signal_real_emit):
sropped the approach of copying all signal specific data into a
GtkHandlerInfo structure. we rather keep the signal data on the stack
in gtk_signal_real_emit and pass that over to gtk_handlers_run. this
avoids multiple lookups of the signal pointer and works savely together
with destroy notifiers of handlers.
* gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that * gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that
someone destroys the entry on the ::activate signal. someone destroys the entry on the ::activate signal.

View File

@ -1,5 +1,12 @@
Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org> Fri Jul 17 05:30:47 1998 Tim Janik <timj@gtk.org>
* gtk/gtksignal.c (gtk_handlers_run) (gtk_signal_real_emit):
sropped the approach of copying all signal specific data into a
GtkHandlerInfo structure. we rather keep the signal data on the stack
in gtk_signal_real_emit and pass that over to gtk_handlers_run. this
avoids multiple lookups of the signal pointer and works savely together
with destroy notifiers of handlers.
* gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that * gtk/gtkentry.c (gtk_entry_key_press): care for the posssibility that
someone destroys the entry on the ::activate signal. someone destroys the entry on the ::activate signal.

View File

@ -42,7 +42,6 @@ enum
typedef struct _GtkSignal GtkSignal; typedef struct _GtkSignal GtkSignal;
typedef struct _GtkSignalHash GtkSignalHash; typedef struct _GtkSignalHash GtkSignalHash;
typedef struct _GtkHandler GtkHandler; typedef struct _GtkHandler GtkHandler;
typedef struct _GtkHandlerInfo GtkHandlerInfo;
typedef struct _GtkEmission GtkEmission; typedef struct _GtkEmission GtkEmission;
typedef union _GtkEmissionAllocator GtkEmissionAllocator; typedef union _GtkEmissionAllocator GtkEmissionAllocator;
typedef struct _GtkDisconnectInfo GtkDisconnectInfo; typedef struct _GtkDisconnectInfo GtkDisconnectInfo;
@ -86,18 +85,6 @@ struct _GtkHandler
GtkHandler *next; GtkHandler *next;
}; };
struct _GtkHandlerInfo
{
GtkObject *object;
GtkSignalMarshaller marshaller;
GtkArg *params;
GtkType *param_types;
GtkType return_val;
GtkSignalRunType signal_flags;
guint nparams;
guint signal_id;
};
struct _GtkEmission struct _GtkEmission
{ {
GtkObject *object; GtkObject *object;
@ -154,7 +141,9 @@ static gint gtk_emission_check (GList *emissions,
GtkObject *object, GtkObject *object,
guint signal_type); guint signal_type);
static gint gtk_handlers_run (GtkHandler *handlers, static gint gtk_handlers_run (GtkHandler *handlers,
GtkHandlerInfo *info, GtkSignal *signal,
GtkObject *object,
GtkArg *params,
gint after); gint after);
static gboolean gtk_signal_collect_params (GtkArg *params, static gboolean gtk_signal_collect_params (GtkArg *params,
guint nparams, guint nparams,
@ -1357,23 +1346,34 @@ gtk_signal_real_emit (GtkObject *object,
guint signal_id, guint signal_id,
GtkArg *params) GtkArg *params)
{ {
GtkSignal *signal; GtkSignal signal;
GtkHandler *handlers; GtkHandler *handlers;
GtkHandlerInfo info; GtkSignalFunc *signal_func_offset;
guchar **signal_func_offset;
signal = LOOKUP_SIGNAL_ID (signal_id);
/* gtk_handlers_run() expects a reentrant GtkSignal*, so we allocate
* it locally on the stack. we save some lookups ourselves with this as well.
*/
signal = *LOOKUP_SIGNAL_ID (signal_id);
if (signal.function_offset)
{
signal_func_offset = (GtkSignalFunc*) ((guchar*) object->klass + signal.function_offset);
if (!*signal_func_offset)
signal_func_offset = (GtkSignalFunc*) 0;
}
else
signal_func_offset = NULL;
#ifdef G_ENABLE_DEBUG #ifdef G_ENABLE_DEBUG
if (gtk_debug_flags & GTK_DEBUG_SIGNALS || if (gtk_debug_flags & GTK_DEBUG_SIGNALS ||
object == gtk_trace_signal_object) object == gtk_trace_signal_object)
fprintf (stdout, "trace: signal_emit(\"%s\") for %s:%p\n", fprintf (stdout, "GTK-DEBUG: signal_emit (\"%s\") for %s:%p (class-pointer %p)\n",
signal->name, signal.name,
gtk_type_name (GTK_OBJECT_TYPE (object)), gtk_type_name (GTK_OBJECT_TYPE (object)),
object); object,
signal_func_offset);
#endif /* G_ENABLE_DEBUG */ #endif /* G_ENABLE_DEBUG */
if ((signal->signal_flags & GTK_RUN_NO_RECURSE) && if ((signal.signal_flags & GTK_RUN_NO_RECURSE) &&
gtk_emission_check (current_emissions, object, signal_id)) gtk_emission_check (current_emissions, object, signal_id))
{ {
gtk_emission_add (&restart_emissions, object, signal_id); gtk_emission_add (&restart_emissions, object, signal_id);
@ -1385,17 +1385,8 @@ gtk_signal_real_emit (GtkObject *object,
gtk_emission_add (&current_emissions, object, signal_id); gtk_emission_add (&current_emissions, object, signal_id);
emission_restart: emission_restart:
if (GTK_RUN_TYPE (signal->signal_flags) != GTK_RUN_LAST && signal->function_offset != 0) if (GTK_RUN_TYPE (signal.signal_flags) != GTK_RUN_LAST && signal_func_offset)
{ signal.marshaller (object, *signal_func_offset, NULL, params);
signal_func_offset = (guchar**) ((guchar*) object->klass +
signal->function_offset);
if (*signal_func_offset)
{
(* signal->marshaller) (object, (GtkSignalFunc) *signal_func_offset,
NULL, params);
signal = LOOKUP_SIGNAL_ID (signal_id);
}
}
if (GTK_OBJECT_CONNECTED (object)) if (GTK_OBJECT_CONNECTED (object))
{ {
@ -1404,17 +1395,7 @@ gtk_signal_real_emit (GtkObject *object,
{ {
gint return_val; gint return_val;
info.object = object; return_val = gtk_handlers_run (handlers, &signal, object, params, FALSE);
info.marshaller = signal->marshaller;
info.params = params;
info.param_types = signal->params;
info.return_val = signal->return_val;
info.nparams = signal->nparams;
info.signal_flags = signal->signal_flags;
info.signal_id = signal_id;
return_val = gtk_handlers_run (handlers, &info, FALSE);
signal = LOOKUP_SIGNAL_ID (signal_id);
switch (return_val) switch (return_val)
{ {
case EMISSION_CONTINUE: case EMISSION_CONTINUE:
@ -1425,23 +1406,10 @@ gtk_signal_real_emit (GtkObject *object,
goto emission_done; goto emission_done;
} }
} }
else
info.object = NULL;
} }
else
info.object = NULL;
if (GTK_RUN_TYPE (signal->signal_flags) != GTK_RUN_FIRST && signal->function_offset != 0) if (GTK_RUN_TYPE (signal.signal_flags) != GTK_RUN_FIRST && signal_func_offset)
{ signal.marshaller (object, *signal_func_offset, NULL, params);
signal_func_offset = (guchar**) ((guchar*) object->klass +
signal->function_offset);
if (*signal_func_offset)
{
(* signal->marshaller) (object, (GtkSignalFunc) *signal_func_offset,
NULL, params);
signal = LOOKUP_SIGNAL_ID (signal_id);
}
}
if (GTK_OBJECT_CONNECTED (object)) if (GTK_OBJECT_CONNECTED (object))
{ {
@ -1450,19 +1418,7 @@ gtk_signal_real_emit (GtkObject *object,
{ {
gint return_val; gint return_val;
if (!info.object) return_val = gtk_handlers_run (handlers, &signal, object, params, TRUE);
{
info.object = object;
info.marshaller = signal->marshaller;
info.params = params;
info.param_types = signal->params;
info.return_val = signal->return_val;
info.nparams = signal->nparams;
info.signal_flags = signal->signal_flags;
info.signal_id = signal_id;
}
return_val = gtk_handlers_run (handlers, &info, TRUE);
signal = LOOKUP_SIGNAL_ID (signal_id);
switch (return_val) switch (return_val)
{ {
case EMISSION_CONTINUE: case EMISSION_CONTINUE:
@ -1479,7 +1435,7 @@ gtk_signal_real_emit (GtkObject *object,
gtk_emission_remove (&current_emissions, object, signal_id); gtk_emission_remove (&current_emissions, object, signal_id);
if (signal->signal_flags & GTK_RUN_NO_RECURSE) if (signal.signal_flags & GTK_RUN_NO_RECURSE)
gtk_emission_remove (&restart_emissions, object, signal_id); gtk_emission_remove (&restart_emissions, object, signal_id);
gtk_object_unref (object); gtk_object_unref (object);
@ -1747,10 +1703,15 @@ gtk_emission_check (GList *emissions,
static gint static gint
gtk_handlers_run (GtkHandler *handlers, gtk_handlers_run (GtkHandler *handlers,
GtkHandlerInfo *info, GtkSignal *signal,
GtkObject *object,
GtkArg *params,
gint after) gint after)
{ {
while (handlers && handlers->signal_id == info->signal_id) /* *signal is a local copy on the stack of gtk_signal_real_emit(),
* so we don't need to look it up every time we invoked a function.
*/
while (handlers && handlers->signal_id == signal->signal_id)
{ {
GtkHandler *handlers_next; GtkHandler *handlers_next;
@ -1761,54 +1722,55 @@ gtk_handlers_run (GtkHandler *handlers,
if (handlers->func) if (handlers->func)
{ {
if (handlers->no_marshal) if (handlers->no_marshal)
(* (GtkCallbackMarshal) handlers->func) (info->object, (* (GtkCallbackMarshal) handlers->func) (object,
handlers->func_data, handlers->func_data,
info->nparams, signal->nparams,
info->params); params);
else if (handlers->object_signal) else if (handlers->object_signal)
(* info->marshaller) ((GtkObject*) handlers->func_data, /* don't GTK_OBJECT() cast */ /* don't GTK_OBJECT(handlers->func_data) cast */
handlers->func, (* signal->marshaller) ((GtkObject*) handlers->func_data,
handlers->func_data, handlers->func,
info->params); handlers->func_data,
params);
else else
(* info->marshaller) (info->object, (* signal->marshaller) (object,
handlers->func, handlers->func,
handlers->func_data, handlers->func_data,
info->params); params);
} }
else if (global_marshaller) else if (global_marshaller)
(* global_marshaller) (info->object, (* global_marshaller) (object,
handlers->func_data, handlers->func_data,
info->nparams, signal->nparams,
info->params, params,
info->param_types, signal->params,
info->return_val); signal->return_val);
if (gtk_emission_check (stop_emissions, info->object, if (gtk_emission_check (stop_emissions, object,
info->signal_id)) signal->signal_id))
{ {
gtk_emission_remove (&stop_emissions, info->object, gtk_emission_remove (&stop_emissions, object,
info->signal_id); signal->signal_id);
if (info->signal_flags & GTK_RUN_NO_RECURSE) if (signal->signal_flags & GTK_RUN_NO_RECURSE)
gtk_emission_remove (&restart_emissions, info->object, gtk_emission_remove (&restart_emissions, object,
info->signal_id); signal->signal_id);
gtk_signal_handler_unref (handlers, info->object); gtk_signal_handler_unref (handlers, object);
return EMISSION_DONE; return EMISSION_DONE;
} }
else if ((info->signal_flags & GTK_RUN_NO_RECURSE) && else if ((signal->signal_flags & GTK_RUN_NO_RECURSE) &&
gtk_emission_check (restart_emissions, info->object, gtk_emission_check (restart_emissions, object,
info->signal_id)) signal->signal_id))
{ {
gtk_emission_remove (&restart_emissions, info->object, gtk_emission_remove (&restart_emissions, object,
info->signal_id); signal->signal_id);
gtk_signal_handler_unref (handlers, info->object); gtk_signal_handler_unref (handlers, object);
return EMISSION_RESTART; return EMISSION_RESTART;
} }
} }
handlers_next = handlers->next; handlers_next = handlers->next;
gtk_signal_handler_unref (handlers, info->object); gtk_signal_handler_unref (handlers, object);
handlers = handlers_next; handlers = handlers_next;
} }