mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 22:16:16 +01:00
Move the boxed private type data to TypeNode
This way we don't need to keep a custom array that we bsearch on (and that isn't threadsafe) but can use the gtype.c machinery that is threadsafe. And fast, too! https://bugzilla.gnome.org/show_bug.cgi?id=554887
This commit is contained in:
parent
ac666d2ae3
commit
11d4e59712
@ -114,7 +114,10 @@ gobject_public_h_sources = \
|
||||
gmarshal.h
|
||||
|
||||
# GObject library header files that don't get installed
|
||||
gobject_private_h_sources = gatomicarray.h
|
||||
gobject_private_h_sources = \
|
||||
gatomicarray.h \
|
||||
gtype-private.h
|
||||
|
||||
# GObject library C sources to build the library from
|
||||
gobject_c_sources = \
|
||||
gatomicarray.c \
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "gboxed.h"
|
||||
#include "gbsearcharray.h"
|
||||
#include "gtype-private.h"
|
||||
#include "gvalue.h"
|
||||
#include "gvaluearray.h"
|
||||
#include "gclosure.h"
|
||||
@ -46,39 +46,6 @@
|
||||
* based libraries.
|
||||
*/
|
||||
|
||||
/* --- typedefs & structures --- */
|
||||
typedef struct
|
||||
{
|
||||
GType type;
|
||||
GBoxedCopyFunc copy;
|
||||
GBoxedFreeFunc free;
|
||||
} BoxedNode;
|
||||
|
||||
|
||||
/* --- prototypes --- */
|
||||
static gint boxed_nodes_cmp (gconstpointer p1,
|
||||
gconstpointer p2);
|
||||
|
||||
|
||||
/* --- variables --- */
|
||||
static GBSearchArray *boxed_bsa = NULL;
|
||||
static const GBSearchConfig boxed_bconfig = {
|
||||
sizeof (BoxedNode),
|
||||
boxed_nodes_cmp,
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
/* --- functions --- */
|
||||
static gint
|
||||
boxed_nodes_cmp (gconstpointer p1,
|
||||
gconstpointer p2)
|
||||
{
|
||||
const BoxedNode *node1 = p1, *node2 = p2;
|
||||
|
||||
return G_BSEARCH_ARRAY_CMP (node1->type, node2->type);
|
||||
}
|
||||
|
||||
static inline void /* keep this function in sync with gvalue.c */
|
||||
value_meminit (GValue *value,
|
||||
GType value_type)
|
||||
@ -129,8 +96,6 @@ g_boxed_type_init (void)
|
||||
const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, };
|
||||
GType type;
|
||||
|
||||
boxed_bsa = g_bsearch_array_create (&boxed_bconfig);
|
||||
|
||||
/* G_TYPE_BOXED
|
||||
*/
|
||||
type = g_type_register_fundamental (G_TYPE_BOXED, g_intern_static_string ("GBoxed"), &info, &finfo,
|
||||
@ -307,26 +272,6 @@ g_byte_array_get_type (void)
|
||||
return type_id;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
_g_type_boxed_copy (GType type, gconstpointer value)
|
||||
{
|
||||
BoxedNode key, *node;
|
||||
|
||||
key.type = G_VALUE_TYPE (value);
|
||||
node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
|
||||
return node->copy (value);
|
||||
}
|
||||
|
||||
static void
|
||||
_g_type_boxed_free (GType type, gpointer value)
|
||||
{
|
||||
BoxedNode key, *node;
|
||||
|
||||
key.type = G_VALUE_TYPE (value);
|
||||
node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
|
||||
node->free (value);
|
||||
}
|
||||
|
||||
static void
|
||||
boxed_proxy_value_init (GValue *value)
|
||||
{
|
||||
@ -426,7 +371,7 @@ g_boxed_type_register_static (const gchar *name,
|
||||
"p",
|
||||
boxed_proxy_lcopy_value,
|
||||
};
|
||||
static const GTypeInfo type_info = {
|
||||
GTypeInfo type_info = {
|
||||
0, /* class_size */
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
@ -449,14 +394,7 @@ g_boxed_type_register_static (const gchar *name,
|
||||
|
||||
/* install proxy functions upon successfull registration */
|
||||
if (type)
|
||||
{
|
||||
BoxedNode key;
|
||||
|
||||
key.type = type;
|
||||
key.copy = boxed_copy;
|
||||
key.free = boxed_free;
|
||||
boxed_bsa = g_bsearch_array_insert (boxed_bsa, &boxed_bconfig, &key);
|
||||
}
|
||||
_g_type_boxed_init (type, boxed_copy, boxed_free);
|
||||
|
||||
return type;
|
||||
}
|
||||
@ -487,7 +425,7 @@ g_boxed_copy (GType boxed_type,
|
||||
|
||||
/* check if our proxying implementation is used, we can short-cut here */
|
||||
if (value_table->value_copy == boxed_proxy_value_copy)
|
||||
dest_boxed = _g_type_boxed_copy (boxed_type, src_boxed);
|
||||
dest_boxed = _g_type_boxed_copy (boxed_type, (gpointer) src_boxed);
|
||||
else
|
||||
{
|
||||
GValue src_value, dest_value;
|
||||
@ -614,7 +552,7 @@ value_set_boxed_internal (GValue *value,
|
||||
if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
|
||||
g_boxed_free (G_VALUE_TYPE (value), value->data[0].v_pointer);
|
||||
value->data[1].v_uint = need_free ? 0 : G_VALUE_NOCOPY_CONTENTS;
|
||||
value->data[0].v_pointer = need_copy ? g_boxed_copy (G_VALUE_TYPE (value), boxed) : (gconstpointer) boxed;
|
||||
value->data[0].v_pointer = need_copy ? g_boxed_copy (G_VALUE_TYPE (value), boxed) : (gpointer) boxed;
|
||||
}
|
||||
|
||||
/**
|
||||
|
41
gobject/gtype-private.h
Normal file
41
gobject/gtype-private.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* GObject - GLib Type, Object, Parameter and Signal Library
|
||||
* Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION)
|
||||
#error "Only <glib-object.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __G_TYPE_PRIVATE_H__
|
||||
#define __G_TYPE_PRIVATE_H__
|
||||
|
||||
#include "gboxed.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* for gboxed.c */
|
||||
gpointer _g_type_boxed_copy (GType type,
|
||||
gpointer value);
|
||||
void _g_type_boxed_free (GType type,
|
||||
gpointer value);
|
||||
void _g_type_boxed_init (GType type,
|
||||
GBoxedCopyFunc copy_func,
|
||||
GBoxedFreeFunc free_func);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_TYPE_PRIVATE_H__ */
|
@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "gtype.h"
|
||||
#include "gtype-private.h"
|
||||
#include "gtypeplugin.h"
|
||||
#include "gvaluecollector.h"
|
||||
#include "gbsearcharray.h"
|
||||
@ -168,6 +169,7 @@
|
||||
/* --- typedefs --- */
|
||||
typedef struct _TypeNode TypeNode;
|
||||
typedef struct _CommonData CommonData;
|
||||
typedef struct _BoxedData BoxedData;
|
||||
typedef struct _IFaceData IFaceData;
|
||||
typedef struct _ClassData ClassData;
|
||||
typedef struct _InstanceData InstanceData;
|
||||
@ -253,6 +255,7 @@ struct _TypeNode
|
||||
#define NODE_FUNDAMENTAL_TYPE(node) (node->supers[node->n_supers])
|
||||
#define NODE_NAME(node) (g_quark_to_string (node->qname))
|
||||
#define NODE_REFCOUNT(node) ((guint) g_atomic_int_get ((int *) &(node)->ref_count))
|
||||
#define NODE_IS_BOXED(node) (NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_BOXED)
|
||||
#define NODE_IS_IFACE(node) (NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_INTERFACE)
|
||||
#define CLASSED_NODE_IFACES_ENTRIES(node) (&(node)->_prot.iface_entries)
|
||||
#define CLASSED_NODE_IFACES_ENTRIES_LOCKED(node)(G_ATOMIC_ARRAY_GET_LOCKED(CLASSED_NODE_IFACES_ENTRIES((node)), IFaceEntries))
|
||||
@ -296,6 +299,13 @@ struct _CommonData
|
||||
GTypeValueTable *value_table;
|
||||
};
|
||||
|
||||
struct _BoxedData
|
||||
{
|
||||
CommonData data;
|
||||
GBoxedCopyFunc copy_func;
|
||||
GBoxedFreeFunc free_func;
|
||||
};
|
||||
|
||||
struct _IFaceData
|
||||
{
|
||||
CommonData common;
|
||||
@ -342,6 +352,7 @@ struct _InstanceData
|
||||
union _TypeData
|
||||
{
|
||||
CommonData common;
|
||||
BoxedData boxed;
|
||||
IFaceData iface;
|
||||
ClassData class;
|
||||
InstanceData instance;
|
||||
@ -1120,6 +1131,12 @@ type_data_make_W (TypeNode *node,
|
||||
data->iface.dflt_data = info->class_data;
|
||||
data->iface.dflt_vtable = NULL;
|
||||
}
|
||||
else if (NODE_IS_BOXED (node))
|
||||
{
|
||||
data = g_malloc0 (sizeof (BoxedData) + vtable_size);
|
||||
if (vtable_size)
|
||||
vtable = G_STRUCT_MEMBER_P (data, sizeof (BoxedData));
|
||||
}
|
||||
else
|
||||
{
|
||||
data = g_malloc0 (sizeof (CommonData) + vtable_size);
|
||||
@ -4164,6 +4181,34 @@ g_type_name_from_class (GTypeClass *g_class)
|
||||
}
|
||||
|
||||
|
||||
/* --- private api for gboxed.c --- */
|
||||
gpointer
|
||||
_g_type_boxed_copy (GType type, gpointer value)
|
||||
{
|
||||
TypeNode *node = lookup_type_node_I (type);
|
||||
|
||||
return node->data->boxed.copy_func (value);
|
||||
}
|
||||
|
||||
void
|
||||
_g_type_boxed_free (GType type, gpointer value)
|
||||
{
|
||||
TypeNode *node = lookup_type_node_I (type);
|
||||
|
||||
node->data->boxed.free_func (value);
|
||||
}
|
||||
|
||||
void
|
||||
_g_type_boxed_init (GType type,
|
||||
GBoxedCopyFunc copy_func,
|
||||
GBoxedFreeFunc free_func)
|
||||
{
|
||||
TypeNode *node = lookup_type_node_I (type);
|
||||
|
||||
node->data->boxed.copy_func = copy_func;
|
||||
node->data->boxed.free_func = free_func;
|
||||
}
|
||||
|
||||
/* --- initialization --- */
|
||||
/**
|
||||
* g_type_init_with_debug_flags:
|
||||
|
Loading…
Reference in New Issue
Block a user