[API] Make set_user_data() functions take a replace parameter
We need this to set data on objects safely without worrying that some other thread unsets it by setting it at the same time.
This commit is contained in:
parent
944b2ba1ce
commit
33ccc77902
|
@ -165,9 +165,10 @@ hb_bool_t
|
||||||
hb_blob_set_user_data (hb_blob_t *blob,
|
hb_blob_set_user_data (hb_blob_t *blob,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy)
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace)
|
||||||
{
|
{
|
||||||
return hb_object_set_user_data (blob, key, data, destroy);
|
return hb_object_set_user_data (blob, key, data, destroy, replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
|
|
@ -66,7 +66,8 @@ hb_bool_t
|
||||||
hb_blob_set_user_data (hb_blob_t *blob,
|
hb_blob_set_user_data (hb_blob_t *blob,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy);
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace);
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
|
|
@ -532,9 +532,10 @@ hb_bool_t
|
||||||
hb_buffer_set_user_data (hb_buffer_t *buffer,
|
hb_buffer_set_user_data (hb_buffer_t *buffer,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy)
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace)
|
||||||
{
|
{
|
||||||
return hb_object_set_user_data (buffer, key, data, destroy);
|
return hb_object_set_user_data (buffer, key, data, destroy, replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
|
|
@ -75,7 +75,8 @@ hb_bool_t
|
||||||
hb_buffer_set_user_data (hb_buffer_t *buffer,
|
hb_buffer_set_user_data (hb_buffer_t *buffer,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy);
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace);
|
||||||
|
|
||||||
void *
|
void *
|
||||||
hb_buffer_get_user_data (hb_buffer_t *buffer,
|
hb_buffer_get_user_data (hb_buffer_t *buffer,
|
||||||
|
|
|
@ -301,17 +301,20 @@ static hb_static_mutex_t user_data_lock;
|
||||||
bool
|
bool
|
||||||
hb_user_data_array_t::set (hb_user_data_key_t *key,
|
hb_user_data_array_t::set (hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy)
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace)
|
||||||
{
|
{
|
||||||
if (!key)
|
if (!key)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!data && !destroy) {
|
if (replace) {
|
||||||
items.remove (key, user_data_lock);
|
if (!data && !destroy) {
|
||||||
return true;
|
items.remove (key, user_data_lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
hb_user_data_item_t item = {key, data, destroy};
|
hb_user_data_item_t item = {key, data, destroy};
|
||||||
bool ret = !!items.replace_or_insert (item, user_data_lock);
|
bool ret = !!items.replace_or_insert (item, user_data_lock, replace);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,9 +248,10 @@ hb_bool_t
|
||||||
hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
|
hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy)
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace)
|
||||||
{
|
{
|
||||||
return hb_object_set_user_data (ffuncs, key, data, destroy);
|
return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -667,9 +668,10 @@ hb_bool_t
|
||||||
hb_face_set_user_data (hb_face_t *face,
|
hb_face_set_user_data (hb_face_t *face,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy)
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace)
|
||||||
{
|
{
|
||||||
return hb_object_set_user_data (face, key, data, destroy);
|
return hb_object_set_user_data (face, key, data, destroy, replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -852,9 +854,10 @@ hb_bool_t
|
||||||
hb_font_set_user_data (hb_font_t *font,
|
hb_font_set_user_data (hb_font_t *font,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy)
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace)
|
||||||
{
|
{
|
||||||
return hb_object_set_user_data (font, key, data, destroy);
|
return hb_object_set_user_data (font, key, data, destroy, replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
|
|
@ -65,7 +65,8 @@ hb_bool_t
|
||||||
hb_face_set_user_data (hb_face_t *face,
|
hb_face_set_user_data (hb_face_t *face,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy);
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace);
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -123,7 +124,8 @@ hb_bool_t
|
||||||
hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
|
hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy);
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace);
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -338,7 +340,8 @@ hb_bool_t
|
||||||
hb_font_set_user_data (hb_font_t *font,
|
hb_font_set_user_data (hb_font_t *font,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy);
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace);
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
|
|
@ -122,7 +122,8 @@ struct hb_user_data_array_t {
|
||||||
|
|
||||||
HB_INTERNAL bool set (hb_user_data_key_t *key,
|
HB_INTERNAL bool set (hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy);
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace);
|
||||||
|
|
||||||
HB_INTERNAL void *get (hb_user_data_key_t *key);
|
HB_INTERNAL void *get (hb_user_data_key_t *key);
|
||||||
|
|
||||||
|
@ -178,11 +179,12 @@ struct _hb_object_header_t {
|
||||||
|
|
||||||
inline bool set_user_data (hb_user_data_key_t *key,
|
inline bool set_user_data (hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy_func) {
|
hb_destroy_func_t destroy_func,
|
||||||
|
hb_bool_t replace) {
|
||||||
if (unlikely (!this || this->is_inert ()))
|
if (unlikely (!this || this->is_inert ()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return user_data.set (key, data, destroy_func);
|
return user_data.set (key, data, destroy_func, replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void *get_user_data (hb_user_data_key_t *key) {
|
inline void *get_user_data (hb_user_data_key_t *key) {
|
||||||
|
@ -237,9 +239,10 @@ template <typename Type>
|
||||||
static inline bool hb_object_set_user_data (Type *obj,
|
static inline bool hb_object_set_user_data (Type *obj,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy)
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace)
|
||||||
{
|
{
|
||||||
return obj->header.set_user_data (key, data, destroy);
|
return obj->header.set_user_data (key, data, destroy, replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
|
|
|
@ -343,15 +343,21 @@ struct hb_lockable_set_t
|
||||||
hb_array_t <item_t> items;
|
hb_array_t <item_t> items;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline item_t *replace_or_insert (T v, lock_t &l)
|
inline item_t *replace_or_insert (T v, lock_t &l, bool replace)
|
||||||
{
|
{
|
||||||
l.lock ();
|
l.lock ();
|
||||||
item_t *item = items.find (v);
|
item_t *item = items.find (v);
|
||||||
if (item) {
|
if (item) {
|
||||||
item_t old = *item;
|
if (replace) {
|
||||||
*item = v;
|
item_t old = *item;
|
||||||
l.unlock ();
|
*item = v;
|
||||||
old.finish ();
|
l.unlock ();
|
||||||
|
old.finish ();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
item = NULL;
|
||||||
|
l.unlock ();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
item = items.push ();
|
item = items.push ();
|
||||||
if (likely (item))
|
if (likely (item))
|
||||||
|
|
|
@ -76,7 +76,7 @@ static struct static_shaper_list_t
|
||||||
end = p + strlen (p);
|
end = p + strlen (p);
|
||||||
|
|
||||||
for (unsigned int j = i; j < ARRAY_LENGTH (shapers); j++)
|
for (unsigned int j = i; j < ARRAY_LENGTH (shapers); j++)
|
||||||
if (end - p == strlen (shapers[j].name) &&
|
if (end - p == (int) strlen (shapers[j].name) &&
|
||||||
0 == strncmp (shapers[j].name, p, end - p))
|
0 == strncmp (shapers[j].name, p, end - p))
|
||||||
{
|
{
|
||||||
/* Reorder this shaper to position i */
|
/* Reorder this shaper to position i */
|
||||||
|
|
|
@ -175,9 +175,10 @@ hb_bool_t
|
||||||
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy)
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace)
|
||||||
{
|
{
|
||||||
return hb_object_set_user_data (ufuncs, key, data, destroy);
|
return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
|
|
@ -66,7 +66,8 @@ hb_bool_t
|
||||||
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy);
|
hb_destroy_func_t destroy,
|
||||||
|
hb_bool_t replace);
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
|
|
@ -129,10 +129,15 @@ _hb_uniscribe_face_get_data (hb_face_t *face)
|
||||||
DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed");
|
DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed");
|
||||||
|
|
||||||
if (unlikely (!hb_face_set_user_data (face, &uniscribe_face_data_key, data,
|
if (unlikely (!hb_face_set_user_data (face, &uniscribe_face_data_key, data,
|
||||||
(hb_destroy_func_t) _hb_uniscribe_face_data_destroy)))
|
(hb_destroy_func_t) _hb_uniscribe_face_data_destroy,
|
||||||
|
FALSE)))
|
||||||
{
|
{
|
||||||
_hb_uniscribe_face_data_destroy (data);
|
_hb_uniscribe_face_data_destroy (data);
|
||||||
return &_hb_uniscribe_face_data_nil;
|
data = (hb_uniscribe_face_data_t *) hb_face_get_user_data (face, &uniscribe_face_data_key);
|
||||||
|
if (data)
|
||||||
|
return data;
|
||||||
|
else
|
||||||
|
return &_hb_uniscribe_face_data_nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -183,10 +188,15 @@ _hb_uniscribe_font_get_data (hb_font_t *font)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely (!hb_font_set_user_data (font, &uniscribe_font_data_key, data,
|
if (unlikely (!hb_font_set_user_data (font, &uniscribe_font_data_key, data,
|
||||||
(hb_destroy_func_t) _hb_uniscribe_font_data_destroy)))
|
(hb_destroy_func_t) _hb_uniscribe_font_data_destroy,
|
||||||
|
FALSE)))
|
||||||
{
|
{
|
||||||
_hb_uniscribe_font_data_destroy (data);
|
_hb_uniscribe_font_data_destroy (data);
|
||||||
return &_hb_uniscribe_font_data_nil;
|
data = (hb_uniscribe_font_data_t *) hb_font_get_user_data (font, &uniscribe_font_data_key);
|
||||||
|
if (data)
|
||||||
|
return data;
|
||||||
|
else
|
||||||
|
return &_hb_uniscribe_font_data_nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
|
@ -116,7 +116,7 @@ create_unicode_funcs_inert (void)
|
||||||
typedef void *(*create_func_t) (void);
|
typedef void *(*create_func_t) (void);
|
||||||
typedef void *(*reference_func_t) (void *obj);
|
typedef void *(*reference_func_t) (void *obj);
|
||||||
typedef void (*destroy_func_t) (void *obj);
|
typedef void (*destroy_func_t) (void *obj);
|
||||||
typedef hb_bool_t (*set_user_data_func_t) (void *obj, hb_user_data_key_t *key, void *data, hb_destroy_func_t destroy);
|
typedef hb_bool_t (*set_user_data_func_t) (void *obj, hb_user_data_key_t *key, void *data, hb_destroy_func_t destroy, hb_bool_t replace);
|
||||||
typedef void * (*get_user_data_func_t) (void *obj, hb_user_data_key_t *key);
|
typedef void * (*get_user_data_func_t) (void *obj, hb_user_data_key_t *key);
|
||||||
typedef void (*make_immutable_func_t) (void *obj);
|
typedef void (*make_immutable_func_t) (void *obj);
|
||||||
typedef hb_bool_t (*is_immutable_func_t) (void *obj);
|
typedef hb_bool_t (*is_immutable_func_t) (void *obj);
|
||||||
|
@ -247,7 +247,7 @@ test_object (void)
|
||||||
if (o->is_immutable)
|
if (o->is_immutable)
|
||||||
g_assert (!o->is_immutable (obj));
|
g_assert (!o->is_immutable (obj));
|
||||||
|
|
||||||
g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0));
|
g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
|
||||||
g_assert (o->get_user_data (obj, &key[0]) == &data[0]);
|
g_assert (o->get_user_data (obj, &key[0]) == &data[0]);
|
||||||
|
|
||||||
if (o->is_immutable) {
|
if (o->is_immutable) {
|
||||||
|
@ -256,38 +256,39 @@ test_object (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Should still work even if object is made immutable */
|
/* Should still work even if object is made immutable */
|
||||||
g_assert (o->set_user_data (obj, &key[1], &data[1], free_up1));
|
g_assert (o->set_user_data (obj, &key[1], &data[1], free_up1, TRUE));
|
||||||
g_assert (o->get_user_data (obj, &key[1]) == &data[1]);
|
g_assert (o->get_user_data (obj, &key[1]) == &data[1]);
|
||||||
|
|
||||||
g_assert (!o->set_user_data (obj, NULL, &data[0], free_up0));
|
g_assert (!o->set_user_data (obj, NULL, &data[0], free_up0, TRUE));
|
||||||
g_assert (o->get_user_data (obj, &key[0]) == &data[0]);
|
g_assert (o->get_user_data (obj, &key[0]) == &data[0]);
|
||||||
g_assert (o->set_user_data (obj, &key[0], &data[1], NULL));
|
g_assert (o->set_user_data (obj, &key[0], &data[1], NULL, TRUE));
|
||||||
g_assert (data[0].freed);
|
g_assert (data[0].freed);
|
||||||
g_assert (o->get_user_data (obj, &key[0]) == &data[1]);
|
g_assert (o->get_user_data (obj, &key[0]) == &data[1]);
|
||||||
g_assert (!data[1].freed);
|
g_assert (!data[1].freed);
|
||||||
|
|
||||||
data[0].freed = FALSE;
|
data[0].freed = FALSE;
|
||||||
g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0));
|
g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
|
||||||
g_assert (!data[0].freed);
|
g_assert (!data[0].freed);
|
||||||
g_assert (o->set_user_data (obj, &key[0], NULL, NULL));
|
g_assert (o->set_user_data (obj, &key[0], NULL, NULL, TRUE));
|
||||||
g_assert (data[0].freed);
|
g_assert (data[0].freed);
|
||||||
|
|
||||||
data[0].freed = FALSE;
|
data[0].freed = FALSE;
|
||||||
global_data = 0;
|
global_data = 0;
|
||||||
g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0));
|
g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
|
||||||
|
g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, FALSE));
|
||||||
g_assert_cmpuint (global_data, ==, 0);
|
g_assert_cmpuint (global_data, ==, 0);
|
||||||
g_assert (o->set_user_data (obj, &key[0], NULL, global_free_up));
|
g_assert (o->set_user_data (obj, &key[0], NULL, global_free_up, TRUE));
|
||||||
g_assert_cmpuint (global_data, ==, 0);
|
g_assert_cmpuint (global_data, ==, 0);
|
||||||
g_assert (o->set_user_data (obj, &key[0], NULL, NULL));
|
g_assert (o->set_user_data (obj, &key[0], NULL, NULL, TRUE));
|
||||||
g_assert_cmpuint (global_data, ==, 1);
|
g_assert_cmpuint (global_data, ==, 1);
|
||||||
|
|
||||||
global_data = 0;
|
global_data = 0;
|
||||||
for (j = 2; j < 1000; j++)
|
for (j = 2; j < 1000; j++)
|
||||||
g_assert (o->set_user_data (obj, &key[j], &data[j], global_free_up));
|
g_assert (o->set_user_data (obj, &key[j], &data[j], global_free_up, TRUE));
|
||||||
for (j = 2; j < 1000; j++)
|
for (j = 2; j < 1000; j++)
|
||||||
g_assert (o->get_user_data (obj, &key[j]) == &data[j]);
|
g_assert (o->get_user_data (obj, &key[j]) == &data[j]);
|
||||||
for (j = 100; j < 1000; j++)
|
for (j = 100; j < 1000; j++)
|
||||||
g_assert (o->set_user_data (obj, &key[j], NULL, NULL));
|
g_assert (o->set_user_data (obj, &key[j], NULL, NULL, TRUE));
|
||||||
for (j = 2; j < 100; j++)
|
for (j = 2; j < 100; j++)
|
||||||
g_assert (o->get_user_data (obj, &key[j]) == &data[j]);
|
g_assert (o->get_user_data (obj, &key[j]) == &data[j]);
|
||||||
for (j = 100; j < 1000; j++)
|
for (j = 100; j < 1000; j++)
|
||||||
|
@ -298,8 +299,8 @@ test_object (void)
|
||||||
* Make sure it doesn't deadlock or corrupt memory. */
|
* Make sure it doesn't deadlock or corrupt memory. */
|
||||||
deadlock_test.klass = o;
|
deadlock_test.klass = o;
|
||||||
deadlock_test.object = obj;
|
deadlock_test.object = obj;
|
||||||
g_assert (o->set_user_data (obj, &deadlock_test.key, &deadlock_test, free_deadlock_test));
|
g_assert (o->set_user_data (obj, &deadlock_test.key, &deadlock_test, free_deadlock_test, TRUE));
|
||||||
g_assert (o->set_user_data (obj, &deadlock_test.key, NULL, NULL));
|
g_assert (o->set_user_data (obj, &deadlock_test.key, NULL, NULL, TRUE));
|
||||||
|
|
||||||
g_assert (!data[1].freed);
|
g_assert (!data[1].freed);
|
||||||
o->destroy (obj);
|
o->destroy (obj);
|
||||||
|
@ -321,7 +322,7 @@ test_object (void)
|
||||||
if (o->is_immutable)
|
if (o->is_immutable)
|
||||||
g_assert (o->is_immutable (obj));
|
g_assert (o->is_immutable (obj));
|
||||||
|
|
||||||
g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0));
|
g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
|
||||||
g_assert (!o->get_user_data (obj, &key[0]));
|
g_assert (!o->get_user_data (obj, &key[0]));
|
||||||
|
|
||||||
o->destroy (obj);
|
o->destroy (obj);
|
||||||
|
@ -349,7 +350,7 @@ test_object (void)
|
||||||
if (o->is_immutable)
|
if (o->is_immutable)
|
||||||
g_assert (o->is_immutable (obj));
|
g_assert (o->is_immutable (obj));
|
||||||
|
|
||||||
g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0));
|
g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
|
||||||
g_assert (!o->get_user_data (obj, &key[0]));
|
g_assert (!o->get_user_data (obj, &key[0]));
|
||||||
|
|
||||||
o->destroy (obj);
|
o->destroy (obj);
|
||||||
|
|
Loading…
Reference in New Issue