Skip to content
This repository was archived by the owner on Apr 28, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
9b50029
tests: Port gdbus-threading to use g_assert_*() rather than g_assert()
pwithnall Nov 12, 2018
32e254d
tests: Move refcount checks to the end of each test in gdbus-threading
pwithnall Nov 12, 2018
190ef9c
gdbusproxy: Replace home-grown weak ref implementation with GWeakRef
pwithnall Feb 20, 2020
e5d4802
gdbusproxy: Tidy up some memory management code
pwithnall Feb 20, 2020
0d3cae8
gdbusproxy: Simplify a pointer theft
pwithnall Feb 20, 2020
381d29f
gdbusconnection: Drop an unnecessary GMainContext reference
pwithnall Feb 20, 2020
87c18ad
gdbusconnection: Simplify some control flow
pwithnall Feb 20, 2020
07093f6
tests: Take explicit connection and context when ensuring testserver up
pwithnall Feb 20, 2020
28ede9b
tests: Add timeout to assert_connection_has_one_ref()
pwithnall Feb 21, 2020
457b4bb
tests: Wait until unwatching the gdbus-testserver name has completed
pwithnall Feb 21, 2020
9977348
tests: Wait until unsubscribing from a signal has completed
pwithnall Feb 21, 2020
b0c58e5
tests: Use GMainContext instead of GMainLoop in gdbus-threading
pwithnall Feb 21, 2020
b4dbb8e
tests: Use TestSignal rather than NameOwnerChanged to test signals
pwithnall Feb 21, 2020
62ecc92
tests: Mark gdbus-threading as non-flaky any more
pwithnall Feb 21, 2020
3d3f5d1
gdbusconnection: Document main context iteration for unsubscriptions
pwithnall Feb 21, 2020
2c97fb6
tests: Skip g-file-info-filesystem-readonly test if bindfs fails
pwithnall Feb 24, 2020
6d0344f
GThread: Don't g_error() if setting the thread scheduler settings fails
sdroege Feb 20, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions gio/gdbusconnection.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,6 @@ typedef struct
{
GDestroyNotify callback;
gpointer user_data;
GMainContext *context;
} CallDestroyNotifyData;

static gboolean
Expand All @@ -236,8 +235,6 @@ call_destroy_notify_data_in_idle (gpointer user_data)
static void
call_destroy_notify_data_free (CallDestroyNotifyData *data)
{
if (data->context != NULL)
g_main_context_unref (data->context);
g_free (data);
}

Expand All @@ -258,14 +255,11 @@ call_destroy_notify (GMainContext *context,
CallDestroyNotifyData *data;

if (callback == NULL)
goto out;
return;

data = g_new0 (CallDestroyNotifyData, 1);
data->callback = callback;
data->user_data = user_data;
data->context = context;
if (data->context != NULL)
g_main_context_ref (data->context);

idle_source = g_idle_source_new ();
g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
Expand All @@ -274,11 +268,8 @@ call_destroy_notify (GMainContext *context,
data,
(GDestroyNotify) call_destroy_notify_data_free);
g_source_set_name (idle_source, "[gio] call_destroy_notify_data_in_idle");
g_source_attach (idle_source, data->context);
g_source_attach (idle_source, context);
g_source_unref (idle_source);

out:
;
}

/* ---------------------------------------------------------------------------------------------------- */
Expand Down Expand Up @@ -3703,6 +3694,14 @@ unsubscribe_id_internal (GDBusConnection *connection,
*
* Unsubscribes from signals.
*
* Note that there may still be D-Bus traffic to process (relating to this
* signal subscription) in the current thread-default #GMainContext after this
* function has returned. You should continue to iterate the #GMainContext
* until the #GDestroyNotify function passed to
* g_dbus_connection_signal_subscribe() is called, in order to avoid memory
* leaks through callbacks queued on the #GMainContext after it’s stopped being
* iterated.
*
* Since: 2.26
*/
void
Expand Down
7 changes: 7 additions & 0 deletions gio/gdbusnameowning.c
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,13 @@ g_bus_own_name_on_connection_with_closures (GDBusConnection *connection,
*
* Stops owning a name.
*
* Note that there may still be D-Bus traffic to process (relating to owning
* and unowning the name) in the current thread-default #GMainContext after
* this function has returned. You should continue to iterate the #GMainContext
* until the #GDestroyNotify function passed to g_bus_own_name() is called, in
* order to avoid memory leaks through callbacks queued on the #GMainContext
* after it’s stopped being iterated.
*
* Since: 2.26
*/
void
Expand Down
7 changes: 7 additions & 0 deletions gio/gdbusnamewatching.c
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,13 @@ guint g_bus_watch_name_on_connection_with_closures (
*
* Stops watching a name.
*
* Note that there may still be D-Bus traffic to process (relating to watching
* and unwatching the name) in the current thread-default #GMainContext after
* this function has returned. You should continue to iterate the #GMainContext
* until the #GDestroyNotify function passed to g_bus_watch_name() is called, in
* order to avoid memory leaks through callbacks queued on the #GMainContext
* after it’s stopped being iterated.
*
* Since: 2.26
*/
void
Expand Down
119 changes: 28 additions & 91 deletions gio/gdbusproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,28 +95,19 @@ G_LOCK_DEFINE_STATIC (properties_lock);

/* ---------------------------------------------------------------------------------------------------- */

G_LOCK_DEFINE_STATIC (signal_subscription_lock);

typedef struct
{
volatile gint ref_count;
GDBusProxy *proxy;
} SignalSubscriptionData;

static SignalSubscriptionData *
signal_subscription_ref (SignalSubscriptionData *data)
static GWeakRef *
weak_ref_new (GObject *object)
{
g_atomic_int_inc (&data->ref_count);
return data;
GWeakRef *weak_ref = g_new0 (GWeakRef, 1);
g_weak_ref_init (weak_ref, object);
return g_steal_pointer (&weak_ref);
}

static void
signal_subscription_unref (SignalSubscriptionData *data)
weak_ref_free (GWeakRef *weak_ref)
{
if (g_atomic_int_dec_and_test (&data->ref_count))
{
g_slice_free (SignalSubscriptionData, data);
}
g_weak_ref_clear (weak_ref);
g_free (weak_ref);
}

/* ---------------------------------------------------------------------------------------------------- */
Expand Down Expand Up @@ -152,8 +143,6 @@ struct _GDBusProxyPrivate

/* mutable, protected by properties_lock */
GDBusObject *object;

SignalSubscriptionData *signal_subscription_data;
};

enum
Expand Down Expand Up @@ -189,22 +178,6 @@ G_DEFINE_TYPE_WITH_CODE (GDBusProxy, g_dbus_proxy, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init))

static void
g_dbus_proxy_dispose (GObject *object)
{
GDBusProxy *proxy = G_DBUS_PROXY (object);
G_LOCK (signal_subscription_lock);
if (proxy->priv->signal_subscription_data != NULL)
{
proxy->priv->signal_subscription_data->proxy = NULL;
signal_subscription_unref (proxy->priv->signal_subscription_data);
proxy->priv->signal_subscription_data = NULL;
}
G_UNLOCK (signal_subscription_lock);

G_OBJECT_CLASS (g_dbus_proxy_parent_class)->dispose (object);
}

static void
g_dbus_proxy_finalize (GObject *object)
{
Expand Down Expand Up @@ -346,7 +319,6 @@ g_dbus_proxy_class_init (GDBusProxyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

gobject_class->dispose = g_dbus_proxy_dispose;
gobject_class->finalize = g_dbus_proxy_finalize;
gobject_class->set_property = g_dbus_proxy_set_property;
gobject_class->get_property = g_dbus_proxy_get_property;
Expand Down Expand Up @@ -638,9 +610,6 @@ static void
g_dbus_proxy_init (GDBusProxy *proxy)
{
proxy->priv = g_dbus_proxy_get_instance_private (proxy);
proxy->priv->signal_subscription_data = g_slice_new0 (SignalSubscriptionData);
proxy->priv->signal_subscription_data->ref_count = 1;
proxy->priv->signal_subscription_data->proxy = proxy;
proxy->priv->properties = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
Expand Down Expand Up @@ -868,21 +837,12 @@ on_signal_received (GDBusConnection *connection,
GVariant *parameters,
gpointer user_data)
{
SignalSubscriptionData *data = user_data;
GWeakRef *proxy_weak = user_data;
GDBusProxy *proxy;

G_LOCK (signal_subscription_lock);
proxy = data->proxy;
proxy = G_DBUS_PROXY (g_weak_ref_get (proxy_weak));
if (proxy == NULL)
{
G_UNLOCK (signal_subscription_lock);
return;
}
else
{
g_object_ref (proxy);
G_UNLOCK (signal_subscription_lock);
}
return;

if (!proxy->priv->initialized)
goto out;
Expand Down Expand Up @@ -929,8 +889,7 @@ on_signal_received (GDBusConnection *connection,
parameters);

out:
if (proxy != NULL)
g_object_unref (proxy);
g_clear_object (&proxy);
}

/* ---------------------------------------------------------------------------------------------------- */
Expand Down Expand Up @@ -1038,7 +997,7 @@ on_properties_changed (GDBusConnection *connection,
GVariant *parameters,
gpointer user_data)
{
SignalSubscriptionData *data = user_data;
GWeakRef *proxy_weak = user_data;
gboolean emit_g_signal = FALSE;
GDBusProxy *proxy;
const gchar *interface_name_for_signal;
Expand All @@ -1052,18 +1011,9 @@ on_properties_changed (GDBusConnection *connection,
changed_properties = NULL;
invalidated_properties = NULL;

G_LOCK (signal_subscription_lock);
proxy = data->proxy;
proxy = G_DBUS_PROXY (g_weak_ref_get (proxy_weak));
if (proxy == NULL)
{
G_UNLOCK (signal_subscription_lock);
goto out;
}
else
{
g_object_ref (proxy);
G_UNLOCK (signal_subscription_lock);
}
return;

if (!proxy->priv->initialized)
goto out;
Expand Down Expand Up @@ -1150,11 +1100,9 @@ on_properties_changed (GDBusConnection *connection,
}

out:
if (changed_properties != NULL)
g_variant_unref (changed_properties);
g_clear_pointer (&changed_properties, g_variant_unref);
g_free (invalidated_properties);
if (proxy != NULL)
g_object_unref (proxy);
g_clear_object (&proxy);
}

/* ---------------------------------------------------------------------------------------------------- */
Expand Down Expand Up @@ -1258,8 +1206,7 @@ on_name_owner_changed_get_all_cb (GDBusConnection *connection,
{
G_LOCK (properties_lock);
g_free (data->proxy->priv->name_owner);
data->proxy->priv->name_owner = data->name_owner;
data->name_owner = NULL; /* to avoid an extra copy, we steal the string */
data->proxy->priv->name_owner = g_steal_pointer (&data->name_owner);
g_hash_table_remove_all (data->proxy->priv->properties);
G_UNLOCK (properties_lock);
if (result != NULL)
Expand Down Expand Up @@ -1289,23 +1236,14 @@ on_name_owner_changed (GDBusConnection *connection,
GVariant *parameters,
gpointer user_data)
{
SignalSubscriptionData *data = user_data;
GWeakRef *proxy_weak = user_data;
GDBusProxy *proxy;
const gchar *old_owner;
const gchar *new_owner;

G_LOCK (signal_subscription_lock);
proxy = data->proxy;
proxy = G_DBUS_PROXY (g_weak_ref_get (proxy_weak));
if (proxy == NULL)
{
G_UNLOCK (signal_subscription_lock);
goto out;
}
else
{
g_object_ref (proxy);
G_UNLOCK (signal_subscription_lock);
}
return;

/* if we are already trying to load properties, cancel that */
if (proxy->priv->get_all_cancellable != NULL)
Expand Down Expand Up @@ -1415,8 +1353,7 @@ on_name_owner_changed (GDBusConnection *connection,
}

out:
if (proxy != NULL)
g_object_unref (proxy);
g_clear_object (&proxy);
}

/* ---------------------------------------------------------------------------------------------------- */
Expand Down Expand Up @@ -1762,8 +1699,8 @@ async_initable_init_first (GAsyncInitable *initable)
proxy->priv->interface_name,
G_DBUS_SIGNAL_FLAGS_NONE,
on_properties_changed,
signal_subscription_ref (proxy->priv->signal_subscription_data),
(GDestroyNotify) signal_subscription_unref);
weak_ref_new (G_OBJECT (proxy)),
(GDestroyNotify) weak_ref_free);
}

if (!(proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS))
Expand All @@ -1778,8 +1715,8 @@ async_initable_init_first (GAsyncInitable *initable)
NULL, /* arg0 */
G_DBUS_SIGNAL_FLAGS_NONE,
on_signal_received,
signal_subscription_ref (proxy->priv->signal_subscription_data),
(GDestroyNotify) signal_subscription_unref);
weak_ref_new (G_OBJECT (proxy)),
(GDestroyNotify) weak_ref_free);
}

if (proxy->priv->name != NULL &&
Expand All @@ -1794,8 +1731,8 @@ async_initable_init_first (GAsyncInitable *initable)
proxy->priv->name, /* arg0 */
G_DBUS_SIGNAL_FLAGS_NONE,
on_name_owner_changed,
signal_subscription_ref (proxy->priv->signal_subscription_data),
(GDestroyNotify) signal_subscription_unref);
weak_ref_new (G_OBJECT (proxy)),
(GDestroyNotify) weak_ref_free);
}
}

Expand Down
24 changes: 19 additions & 5 deletions gio/tests/g-file-info-filesystem-readonly.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include <gio/gio.h>
#include <gio/gunixmounts.h>

static void
static gboolean
run (GError **error,
const gchar *argv0,
...)
Expand All @@ -34,6 +34,8 @@ run (GError **error,
const gchar *arg;
va_list ap;
GSubprocess *subprocess;
gchar *command_line = NULL;
gboolean success;

args = g_ptr_array_new ();

Expand All @@ -44,14 +46,20 @@ run (GError **error,
g_ptr_array_add (args, NULL);
va_end (ap);

command_line = g_strjoinv (" ", (gchar **) args->pdata);
g_test_message ("Running command `%s`", command_line);
g_free (command_line);

subprocess = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
g_ptr_array_free (args, TRUE);

if (subprocess == NULL)
return;
return FALSE;

g_subprocess_wait_check (subprocess, NULL, error);
success = g_subprocess_wait_check (subprocess, NULL, error);
g_object_unref (subprocess);

return success;
}

static void
Expand Down Expand Up @@ -135,8 +143,14 @@ test_filesystem_readonly (gconstpointer with_mount_monitor)

/* Use bindfs, which does not need root privileges, to mount the contents of one dir
* into another dir (and do the mount as readonly as per passed '-o ro' option) */
run (&error, bindfs, "-n", "-o", "ro", dir_to_mount, dir_mountpoint, NULL);
g_assert_no_error (error);
if (!run (&error, bindfs, "-n", "-o", "ro", dir_to_mount, dir_mountpoint, NULL))
{
gchar *skip_message = g_strdup_printf ("Failed to run bindfs to set up test: %s", error->message);
g_test_skip (skip_message);
g_free (skip_message);
g_clear_error (&error);
return;
}

/* Let's check now, that the file is in indeed in a readonly filesystem */
file_in_mountpoint = g_strdup_printf ("%s/example.txt", dir_mountpoint);
Expand Down
Loading