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:
parent
ca7b223bf0
commit
2bc6d4548f
@ -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.
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
176
gtk/gtksignal.c
176
gtk/gtksignal.c
@ -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 (¤t_emissions, object, signal_id);
|
gtk_emission_add (¤t_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 (¤t_emissions, object, signal_id);
|
gtk_emission_remove (¤t_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user