#include <config.h>
-#include "gobjectalias.h"
#include "gsignal.h"
+
#include "gbsearcharray.h"
#include "gvaluecollector.h"
#include "gvaluetypes.h"
#include "gboxed.h"
+#include "gobject.h"
+#include "genums.h"
+
+#include "gobjectalias.h"
+
#include <string.h>
#include <signal.h>
/* pre allocation configurations
*/
#define MAX_STACK_VALUES (16)
-#define HANDLER_PRE_ALLOC (48)
#define REPORT_BUG "please report occurrence circumstances to gtk-devel-list@gnome.org"
#ifdef G_ENABLE_DEBUG
#endif /* G_ENABLE_DEBUG */
-/* --- generic allocation --- */
-/* we special case allocations generically by replacing
- * these functions with more speed/memory aware variants
- */
-#ifndef DISABLE_MEM_POOLS
-static inline gpointer
-g_generic_node_alloc (GTrashStack **trash_stack_p,
- guint sizeof_node,
- guint nodes_pre_alloc)
-{
- gpointer node = g_trash_stack_pop (trash_stack_p);
-
- if (!node)
- {
- guint8 *block;
-
- nodes_pre_alloc = MAX (nodes_pre_alloc, 1);
- block = g_malloc (sizeof_node * nodes_pre_alloc);
- while (--nodes_pre_alloc)
- {
- g_trash_stack_push (trash_stack_p, block);
- block += sizeof_node;
- }
- node = block;
- }
-
- return node;
-}
-#define g_generic_node_free(trash_stack_p, node) g_trash_stack_push (trash_stack_p, node)
-#else /* !DISABLE_MEM_POOLS */
-#define g_generic_node_alloc(t,sizeof_node,p) g_malloc (sizeof_node)
-#define g_generic_node_free(t,node) g_free (node)
-#endif /* !DISABLE_MEM_POOLS */
-
-
/* --- typedefs --- */
typedef struct _SignalNode SignalNode;
typedef struct _SignalKey SignalKey;
/* permanent portion */
guint signal_id;
GType itype;
- gchar *name;
+ const gchar *name;
guint destroyed : 1;
/* reinitializable portion */
Handler *next;
Handler *prev;
GQuark detail;
- guint ref_count : 16;
-#define HANDLER_MAX_REF_COUNT (1 << 16)
- guint block_count : 12;
-#define HANDLER_MAX_BLOCK_COUNT (1 << 12)
+ guint ref_count;
+ guint block_count : 16;
+#define HANDLER_MAX_BLOCK_COUNT (1 << 16)
guint after : 1;
GClosure *closure;
};
{
Handler *handler;
HandlerMatch *next;
- union {
- guint signal_id;
- gpointer dummy;
- } d;
+ guint signal_id;
};
typedef struct
static GHashTable *g_handler_list_bsa_ht = NULL;
static Emission *g_recursive_emissions = NULL;
static Emission *g_restart_emissions = NULL;
-#ifndef DISABLE_MEM_POOLS
-static GTrashStack *g_handler_ts = NULL;
-#endif
static gulong g_handler_sequential_number = 1;
G_LOCK_DEFINE_STATIC (g_signal_mutex);
#define SIGNAL_LOCK() G_LOCK (g_signal_mutex)
{
HandlerMatch *node;
- /* yeah, we could use our own memchunk here, introducing yet more
- * rarely used cached nodes and extra allocation overhead.
- * instead, we use GList* nodes, since they are exactly the size
- * we need and are already cached. g_signal_init() asserts this.
- */
- node = (HandlerMatch*) g_list_alloc ();
+ node = g_slice_new (HandlerMatch);
node->handler = handler;
node->next = list;
- node->d.signal_id = signal_id;
+ node->signal_id = signal_id;
handler_ref (handler);
return node;
{
HandlerMatch *next = node->next;
- handler_unref_R (node->d.signal_id, instance, node->handler);
- g_list_free_1 ((GList*) node);
+ handler_unref_R (node->signal_id, instance, node->handler);
+ g_slice_free (HandlerMatch, node);
return next;
}
static inline Handler*
handler_new (gboolean after)
{
- Handler *handler = g_generic_node_alloc (&g_handler_ts,
- sizeof (Handler),
- HANDLER_PRE_ALLOC);
+ Handler *handler = g_slice_new (Handler);
#ifndef G_DISABLE_CHECKS
if (g_handler_sequential_number < 1)
g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG);
{
g_return_if_fail (handler->ref_count > 0);
-#ifndef G_DISABLE_CHECKS
- if (handler->ref_count >= HANDLER_MAX_REF_COUNT - 1)
- g_error (G_STRLOC ": handler ref_count overflow, %s", REPORT_BUG);
-#endif
-
- handler->ref_count += 1;
+ g_atomic_int_inc (&handler->ref_count);
}
static inline void
gpointer instance,
Handler *handler)
{
+ gboolean is_zero;
+
g_return_if_fail (handler->ref_count > 0);
- handler->ref_count -= 1;
- if (!handler->ref_count)
+ is_zero = g_atomic_int_dec_and_test (&handler->ref_count);
+
+ if (G_UNLIKELY (is_zero))
{
HandlerList *hlist = NULL;
SIGNAL_UNLOCK ();
g_closure_unref (handler->closure);
SIGNAL_LOCK ();
- g_generic_node_free (&g_handler_ts, handler);
+ g_slice_free (Handler, handler);
}
}
SIGNAL_LOCK ();
if (!g_n_signal_nodes)
{
- /* handler_id_node_prepend() requires this */
- g_assert (sizeof (GList) == sizeof (HandlerMatch));
-
/* setup handler list binary searchable array hash table (in german, that'd be one word ;) */
g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL);
g_signal_key_bsa = g_bsearch_array_create (&g_signal_key_bconfig);
g_signal_name (guint signal_id)
{
SignalNode *node;
- gchar *name;
+ const gchar *name;
SIGNAL_LOCK ();
node = LOOKUP_SIGNAL_NODE (signal_id);
name = node ? node->name : NULL;
SIGNAL_UNLOCK ();
- return name;
+ return (char*) name;
}
void
key.quark = g_quark_from_string (node->name);
key.signal_id = signal_id;
g_signal_key_bsa = g_bsearch_array_insert (g_signal_key_bsa, &g_signal_key_bconfig, &key);
- g_strdelimit (node->name, "_", '-');
- key.quark = g_quark_from_static_string (node->name);
+ g_strdelimit (name, "_", '-');
+ node->name = g_intern_string (name);
+ key.quark = g_quark_from_string (name);
g_signal_key_bsa = g_bsearch_array_insert (g_signal_key_bsa, &g_signal_key_bconfig, &key);
}
node->destroyed = FALSE;
}
SIGNAL_UNLOCK ();
+ g_free (name);
+
return signal_id;
}
GQuark detail,
GValue *return_value)
{
- const GValue *param_values;
gpointer instance;
SignalNode *node;
#ifdef G_ENABLE_DEBUG
+ const GValue *param_values;
guint i;
#endif
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (signal_id > 0);
+#ifdef G_ENABLE_DEBUG
param_values = instance_and_params + 1;
-
+#endif
+
SIGNAL_LOCK ();
node = LOOKUP_SIGNAL_NODE (signal_id);
if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
}
/* --- compile standard marshallers --- */
-#include "gobject.h"
-#include "genums.h"
#include "gmarshal.c"
+
+#define __G_SIGNAL_C__
+#include "gobjectaliasdef.c"