mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-01 21:33:09 +02:00
Merge branch 'wip/chergert/separate-gweakref-from-gweaknotify-gdata' into 'main'
gobject: Separate GWeakRef from GWeakNotify See merge request GNOME/glib!3316
This commit is contained in:
commit
83eb8fc359
@ -260,6 +260,7 @@ G_LOCK_DEFINE_STATIC (weak_refs_mutex);
|
|||||||
G_LOCK_DEFINE_STATIC (toggle_refs_mutex);
|
G_LOCK_DEFINE_STATIC (toggle_refs_mutex);
|
||||||
static GQuark quark_closure_array = 0;
|
static GQuark quark_closure_array = 0;
|
||||||
static GQuark quark_weak_refs = 0;
|
static GQuark quark_weak_refs = 0;
|
||||||
|
static GQuark quark_weak_notifies = 0;
|
||||||
static GQuark quark_toggle_refs = 0;
|
static GQuark quark_toggle_refs = 0;
|
||||||
static GQuark quark_notify_queue;
|
static GQuark quark_notify_queue;
|
||||||
#ifndef HAVE_OPTIONAL_FLAGS
|
#ifndef HAVE_OPTIONAL_FLAGS
|
||||||
@ -523,6 +524,7 @@ g_object_do_class_init (GObjectClass *class)
|
|||||||
quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
|
quark_closure_array = g_quark_from_static_string ("GObject-closure-array");
|
||||||
|
|
||||||
quark_weak_refs = g_quark_from_static_string ("GObject-weak-references");
|
quark_weak_refs = g_quark_from_static_string ("GObject-weak-references");
|
||||||
|
quark_weak_notifies = g_quark_from_static_string ("GObject-weak-notifies");
|
||||||
quark_weak_locations = g_quark_from_static_string ("GObject-weak-locations");
|
quark_weak_locations = g_quark_from_static_string ("GObject-weak-locations");
|
||||||
quark_toggle_refs = g_quark_from_static_string ("GObject-toggle-references");
|
quark_toggle_refs = g_quark_from_static_string ("GObject-toggle-references");
|
||||||
quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue");
|
quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue");
|
||||||
@ -1359,9 +1361,16 @@ static void
|
|||||||
g_object_real_dispose (GObject *object)
|
g_object_real_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
g_signal_handlers_destroy (object);
|
g_signal_handlers_destroy (object);
|
||||||
g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
|
|
||||||
|
/* GWeakRef and weak_pointer do not call into user code. Clear those first
|
||||||
|
* so that user code can rely on the state of their weak pointers.
|
||||||
|
*/
|
||||||
g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
|
g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
|
||||||
g_datalist_id_set_data (&object->qdata, quark_weak_locations, NULL);
|
g_datalist_id_set_data (&object->qdata, quark_weak_locations, NULL);
|
||||||
|
|
||||||
|
/* GWeakNotify and GClosure can call into user code */
|
||||||
|
g_datalist_id_set_data (&object->qdata, quark_weak_notifies, NULL);
|
||||||
|
g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
@ -3316,7 +3325,7 @@ g_object_weak_ref (GObject *object,
|
|||||||
g_return_if_fail (g_atomic_int_get (&object->ref_count) >= 1);
|
g_return_if_fail (g_atomic_int_get (&object->ref_count) >= 1);
|
||||||
|
|
||||||
G_LOCK (weak_refs_mutex);
|
G_LOCK (weak_refs_mutex);
|
||||||
wstack = g_datalist_id_remove_no_notify (&object->qdata, quark_weak_refs);
|
wstack = g_datalist_id_remove_no_notify (&object->qdata, quark_weak_notifies);
|
||||||
if (wstack)
|
if (wstack)
|
||||||
{
|
{
|
||||||
i = wstack->n_weak_refs++;
|
i = wstack->n_weak_refs++;
|
||||||
@ -3331,7 +3340,7 @@ g_object_weak_ref (GObject *object,
|
|||||||
}
|
}
|
||||||
wstack->weak_refs[i].notify = notify;
|
wstack->weak_refs[i].notify = notify;
|
||||||
wstack->weak_refs[i].data = data;
|
wstack->weak_refs[i].data = data;
|
||||||
g_datalist_id_set_data_full (&object->qdata, quark_weak_refs, wstack, weak_refs_notify);
|
g_datalist_id_set_data_full (&object->qdata, quark_weak_notifies, wstack, weak_refs_notify);
|
||||||
G_UNLOCK (weak_refs_mutex);
|
G_UNLOCK (weak_refs_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3355,7 +3364,7 @@ g_object_weak_unref (GObject *object,
|
|||||||
g_return_if_fail (notify != NULL);
|
g_return_if_fail (notify != NULL);
|
||||||
|
|
||||||
G_LOCK (weak_refs_mutex);
|
G_LOCK (weak_refs_mutex);
|
||||||
wstack = g_datalist_id_get_data (&object->qdata, quark_weak_refs);
|
wstack = g_datalist_id_get_data (&object->qdata, quark_weak_notifies);
|
||||||
if (wstack)
|
if (wstack)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
@ -3927,6 +3936,7 @@ g_object_unref (gpointer _object)
|
|||||||
g_signal_handlers_destroy (object);
|
g_signal_handlers_destroy (object);
|
||||||
g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
|
g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
|
||||||
g_datalist_id_set_data (&object->qdata, quark_weak_locations, NULL);
|
g_datalist_id_set_data (&object->qdata, quark_weak_locations, NULL);
|
||||||
|
g_datalist_id_set_data (&object->qdata, quark_weak_notifies, NULL);
|
||||||
|
|
||||||
/* decrement the last reference */
|
/* decrement the last reference */
|
||||||
old_ref = g_atomic_int_add (&object->ref_count, -1);
|
old_ref = g_atomic_int_add (&object->ref_count, -1);
|
||||||
|
@ -2045,6 +2045,44 @@ test_emitv (void)
|
|||||||
g_array_unref (values);
|
g_array_unref (values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GWeakRef wr;
|
||||||
|
gulong handler;
|
||||||
|
} TestWeakRefDisconnect;
|
||||||
|
|
||||||
|
static void
|
||||||
|
weak_ref_disconnect_notify (gpointer data,
|
||||||
|
GObject *where_object_was)
|
||||||
|
{
|
||||||
|
TestWeakRefDisconnect *state = data;
|
||||||
|
g_assert_null (g_weak_ref_get (&state->wr));
|
||||||
|
state->handler = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_weak_ref_disconnect (void)
|
||||||
|
{
|
||||||
|
TestWeakRefDisconnect state;
|
||||||
|
GObject *test;
|
||||||
|
|
||||||
|
test = g_object_new (test_get_type (), NULL);
|
||||||
|
g_weak_ref_init (&state.wr, test);
|
||||||
|
state.handler = g_signal_connect_data (test,
|
||||||
|
"simple",
|
||||||
|
G_CALLBACK (dont_reach),
|
||||||
|
&state,
|
||||||
|
(GClosureNotify) weak_ref_disconnect_notify,
|
||||||
|
0);
|
||||||
|
g_assert_cmpint (state.handler, >, 0);
|
||||||
|
|
||||||
|
g_object_unref (test);
|
||||||
|
|
||||||
|
g_assert_cmpint (state.handler, ==, 0);
|
||||||
|
g_assert_null (g_weak_ref_get (&state.wr));
|
||||||
|
g_weak_ref_clear (&state.wr);
|
||||||
|
}
|
||||||
|
|
||||||
/* --- */
|
/* --- */
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -2083,6 +2121,7 @@ main (int argc,
|
|||||||
g_test_add_data_func ("/gobject/signals/invalid-name/first-char", "7zip", test_signals_invalid_name);
|
g_test_add_data_func ("/gobject/signals/invalid-name/first-char", "7zip", test_signals_invalid_name);
|
||||||
g_test_add_data_func ("/gobject/signals/invalid-name/empty", "", test_signals_invalid_name);
|
g_test_add_data_func ("/gobject/signals/invalid-name/empty", "", test_signals_invalid_name);
|
||||||
g_test_add_func ("/gobject/signals/is-valid-name", test_signal_is_valid_name);
|
g_test_add_func ("/gobject/signals/is-valid-name", test_signal_is_valid_name);
|
||||||
|
g_test_add_func ("/gobject/signals/weak-ref-disconnect", test_weak_ref_disconnect);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user