mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-19 15:18:55 +02:00
Merge branch '1515-gdbus-threading' into 'master'
Resolve "gio/gdbus-threading test sometimes fails in CI" Closes #1515 See merge request GNOME/glib!1375
This commit is contained in:
@@ -222,7 +222,6 @@ typedef struct
|
|||||||
{
|
{
|
||||||
GDestroyNotify callback;
|
GDestroyNotify callback;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
GMainContext *context;
|
|
||||||
} CallDestroyNotifyData;
|
} CallDestroyNotifyData;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -236,8 +235,6 @@ call_destroy_notify_data_in_idle (gpointer user_data)
|
|||||||
static void
|
static void
|
||||||
call_destroy_notify_data_free (CallDestroyNotifyData *data)
|
call_destroy_notify_data_free (CallDestroyNotifyData *data)
|
||||||
{
|
{
|
||||||
if (data->context != NULL)
|
|
||||||
g_main_context_unref (data->context);
|
|
||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,14 +255,11 @@ call_destroy_notify (GMainContext *context,
|
|||||||
CallDestroyNotifyData *data;
|
CallDestroyNotifyData *data;
|
||||||
|
|
||||||
if (callback == NULL)
|
if (callback == NULL)
|
||||||
goto out;
|
return;
|
||||||
|
|
||||||
data = g_new0 (CallDestroyNotifyData, 1);
|
data = g_new0 (CallDestroyNotifyData, 1);
|
||||||
data->callback = callback;
|
data->callback = callback;
|
||||||
data->user_data = user_data;
|
data->user_data = user_data;
|
||||||
data->context = context;
|
|
||||||
if (data->context != NULL)
|
|
||||||
g_main_context_ref (data->context);
|
|
||||||
|
|
||||||
idle_source = g_idle_source_new ();
|
idle_source = g_idle_source_new ();
|
||||||
g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
|
g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
|
||||||
@@ -274,11 +268,8 @@ call_destroy_notify (GMainContext *context,
|
|||||||
data,
|
data,
|
||||||
(GDestroyNotify) call_destroy_notify_data_free);
|
(GDestroyNotify) call_destroy_notify_data_free);
|
||||||
g_source_set_name (idle_source, "[gio] call_destroy_notify_data_in_idle");
|
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);
|
g_source_unref (idle_source);
|
||||||
|
|
||||||
out:
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
@@ -3703,6 +3694,14 @@ unsubscribe_id_internal (GDBusConnection *connection,
|
|||||||
*
|
*
|
||||||
* Unsubscribes from signals.
|
* 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
|
* Since: 2.26
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
@@ -889,6 +889,13 @@ g_bus_own_name_on_connection_with_closures (GDBusConnection *connection,
|
|||||||
*
|
*
|
||||||
* Stops owning a name.
|
* 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
|
* Since: 2.26
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
@@ -858,6 +858,13 @@ guint g_bus_watch_name_on_connection_with_closures (
|
|||||||
*
|
*
|
||||||
* Stops watching a name.
|
* 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
|
* Since: 2.26
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
119
gio/gdbusproxy.c
119
gio/gdbusproxy.c
@@ -95,28 +95,19 @@ G_LOCK_DEFINE_STATIC (properties_lock);
|
|||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
G_LOCK_DEFINE_STATIC (signal_subscription_lock);
|
static GWeakRef *
|
||||||
|
weak_ref_new (GObject *object)
|
||||||
typedef struct
|
|
||||||
{
|
{
|
||||||
volatile gint ref_count;
|
GWeakRef *weak_ref = g_new0 (GWeakRef, 1);
|
||||||
GDBusProxy *proxy;
|
g_weak_ref_init (weak_ref, object);
|
||||||
} SignalSubscriptionData;
|
return g_steal_pointer (&weak_ref);
|
||||||
|
|
||||||
static SignalSubscriptionData *
|
|
||||||
signal_subscription_ref (SignalSubscriptionData *data)
|
|
||||||
{
|
|
||||||
g_atomic_int_inc (&data->ref_count);
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
signal_subscription_unref (SignalSubscriptionData *data)
|
weak_ref_free (GWeakRef *weak_ref)
|
||||||
{
|
{
|
||||||
if (g_atomic_int_dec_and_test (&data->ref_count))
|
g_weak_ref_clear (weak_ref);
|
||||||
{
|
g_free (weak_ref);
|
||||||
g_slice_free (SignalSubscriptionData, data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
@@ -152,8 +143,6 @@ struct _GDBusProxyPrivate
|
|||||||
|
|
||||||
/* mutable, protected by properties_lock */
|
/* mutable, protected by properties_lock */
|
||||||
GDBusObject *object;
|
GDBusObject *object;
|
||||||
|
|
||||||
SignalSubscriptionData *signal_subscription_data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@@ -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_INITABLE, initable_iface_init)
|
||||||
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_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
|
static void
|
||||||
g_dbus_proxy_finalize (GObject *object)
|
g_dbus_proxy_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
@@ -346,7 +319,6 @@ g_dbus_proxy_class_init (GDBusProxyClass *klass)
|
|||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
gobject_class->dispose = g_dbus_proxy_dispose;
|
|
||||||
gobject_class->finalize = g_dbus_proxy_finalize;
|
gobject_class->finalize = g_dbus_proxy_finalize;
|
||||||
gobject_class->set_property = g_dbus_proxy_set_property;
|
gobject_class->set_property = g_dbus_proxy_set_property;
|
||||||
gobject_class->get_property = g_dbus_proxy_get_property;
|
gobject_class->get_property = g_dbus_proxy_get_property;
|
||||||
@@ -638,9 +610,6 @@ static void
|
|||||||
g_dbus_proxy_init (GDBusProxy *proxy)
|
g_dbus_proxy_init (GDBusProxy *proxy)
|
||||||
{
|
{
|
||||||
proxy->priv = g_dbus_proxy_get_instance_private (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,
|
proxy->priv->properties = g_hash_table_new_full (g_str_hash,
|
||||||
g_str_equal,
|
g_str_equal,
|
||||||
g_free,
|
g_free,
|
||||||
@@ -868,21 +837,12 @@ on_signal_received (GDBusConnection *connection,
|
|||||||
GVariant *parameters,
|
GVariant *parameters,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
SignalSubscriptionData *data = user_data;
|
GWeakRef *proxy_weak = user_data;
|
||||||
GDBusProxy *proxy;
|
GDBusProxy *proxy;
|
||||||
|
|
||||||
G_LOCK (signal_subscription_lock);
|
proxy = G_DBUS_PROXY (g_weak_ref_get (proxy_weak));
|
||||||
proxy = data->proxy;
|
|
||||||
if (proxy == NULL)
|
if (proxy == NULL)
|
||||||
{
|
return;
|
||||||
G_UNLOCK (signal_subscription_lock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_object_ref (proxy);
|
|
||||||
G_UNLOCK (signal_subscription_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!proxy->priv->initialized)
|
if (!proxy->priv->initialized)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -929,8 +889,7 @@ on_signal_received (GDBusConnection *connection,
|
|||||||
parameters);
|
parameters);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (proxy != NULL)
|
g_clear_object (&proxy);
|
||||||
g_object_unref (proxy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
@@ -1038,7 +997,7 @@ on_properties_changed (GDBusConnection *connection,
|
|||||||
GVariant *parameters,
|
GVariant *parameters,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
SignalSubscriptionData *data = user_data;
|
GWeakRef *proxy_weak = user_data;
|
||||||
gboolean emit_g_signal = FALSE;
|
gboolean emit_g_signal = FALSE;
|
||||||
GDBusProxy *proxy;
|
GDBusProxy *proxy;
|
||||||
const gchar *interface_name_for_signal;
|
const gchar *interface_name_for_signal;
|
||||||
@@ -1052,18 +1011,9 @@ on_properties_changed (GDBusConnection *connection,
|
|||||||
changed_properties = NULL;
|
changed_properties = NULL;
|
||||||
invalidated_properties = NULL;
|
invalidated_properties = NULL;
|
||||||
|
|
||||||
G_LOCK (signal_subscription_lock);
|
proxy = G_DBUS_PROXY (g_weak_ref_get (proxy_weak));
|
||||||
proxy = data->proxy;
|
|
||||||
if (proxy == NULL)
|
if (proxy == NULL)
|
||||||
{
|
return;
|
||||||
G_UNLOCK (signal_subscription_lock);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_object_ref (proxy);
|
|
||||||
G_UNLOCK (signal_subscription_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!proxy->priv->initialized)
|
if (!proxy->priv->initialized)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1150,11 +1100,9 @@ on_properties_changed (GDBusConnection *connection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (changed_properties != NULL)
|
g_clear_pointer (&changed_properties, g_variant_unref);
|
||||||
g_variant_unref (changed_properties);
|
|
||||||
g_free (invalidated_properties);
|
g_free (invalidated_properties);
|
||||||
if (proxy != NULL)
|
g_clear_object (&proxy);
|
||||||
g_object_unref (proxy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
@@ -1258,8 +1206,7 @@ on_name_owner_changed_get_all_cb (GDBusConnection *connection,
|
|||||||
{
|
{
|
||||||
G_LOCK (properties_lock);
|
G_LOCK (properties_lock);
|
||||||
g_free (data->proxy->priv->name_owner);
|
g_free (data->proxy->priv->name_owner);
|
||||||
data->proxy->priv->name_owner = data->name_owner;
|
data->proxy->priv->name_owner = g_steal_pointer (&data->name_owner);
|
||||||
data->name_owner = NULL; /* to avoid an extra copy, we steal the string */
|
|
||||||
g_hash_table_remove_all (data->proxy->priv->properties);
|
g_hash_table_remove_all (data->proxy->priv->properties);
|
||||||
G_UNLOCK (properties_lock);
|
G_UNLOCK (properties_lock);
|
||||||
if (result != NULL)
|
if (result != NULL)
|
||||||
@@ -1289,23 +1236,14 @@ on_name_owner_changed (GDBusConnection *connection,
|
|||||||
GVariant *parameters,
|
GVariant *parameters,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
SignalSubscriptionData *data = user_data;
|
GWeakRef *proxy_weak = user_data;
|
||||||
GDBusProxy *proxy;
|
GDBusProxy *proxy;
|
||||||
const gchar *old_owner;
|
const gchar *old_owner;
|
||||||
const gchar *new_owner;
|
const gchar *new_owner;
|
||||||
|
|
||||||
G_LOCK (signal_subscription_lock);
|
proxy = G_DBUS_PROXY (g_weak_ref_get (proxy_weak));
|
||||||
proxy = data->proxy;
|
|
||||||
if (proxy == NULL)
|
if (proxy == NULL)
|
||||||
{
|
return;
|
||||||
G_UNLOCK (signal_subscription_lock);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_object_ref (proxy);
|
|
||||||
G_UNLOCK (signal_subscription_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we are already trying to load properties, cancel that */
|
/* if we are already trying to load properties, cancel that */
|
||||||
if (proxy->priv->get_all_cancellable != NULL)
|
if (proxy->priv->get_all_cancellable != NULL)
|
||||||
@@ -1415,8 +1353,7 @@ on_name_owner_changed (GDBusConnection *connection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (proxy != NULL)
|
g_clear_object (&proxy);
|
||||||
g_object_unref (proxy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
@@ -1762,8 +1699,8 @@ async_initable_init_first (GAsyncInitable *initable)
|
|||||||
proxy->priv->interface_name,
|
proxy->priv->interface_name,
|
||||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||||
on_properties_changed,
|
on_properties_changed,
|
||||||
signal_subscription_ref (proxy->priv->signal_subscription_data),
|
weak_ref_new (G_OBJECT (proxy)),
|
||||||
(GDestroyNotify) signal_subscription_unref);
|
(GDestroyNotify) weak_ref_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS))
|
if (!(proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS))
|
||||||
@@ -1778,8 +1715,8 @@ async_initable_init_first (GAsyncInitable *initable)
|
|||||||
NULL, /* arg0 */
|
NULL, /* arg0 */
|
||||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||||
on_signal_received,
|
on_signal_received,
|
||||||
signal_subscription_ref (proxy->priv->signal_subscription_data),
|
weak_ref_new (G_OBJECT (proxy)),
|
||||||
(GDestroyNotify) signal_subscription_unref);
|
(GDestroyNotify) weak_ref_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proxy->priv->name != NULL &&
|
if (proxy->priv->name != NULL &&
|
||||||
@@ -1794,8 +1731,8 @@ async_initable_init_first (GAsyncInitable *initable)
|
|||||||
proxy->priv->name, /* arg0 */
|
proxy->priv->name, /* arg0 */
|
||||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||||
on_name_owner_changed,
|
on_name_owner_changed,
|
||||||
signal_subscription_ref (proxy->priv->signal_subscription_data),
|
weak_ref_new (G_OBJECT (proxy)),
|
||||||
(GDestroyNotify) signal_subscription_unref);
|
(GDestroyNotify) weak_ref_free);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <gio/gunixmounts.h>
|
#include <gio/gunixmounts.h>
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
run (GError **error,
|
run (GError **error,
|
||||||
const gchar *argv0,
|
const gchar *argv0,
|
||||||
...)
|
...)
|
||||||
@@ -34,6 +34,8 @@ run (GError **error,
|
|||||||
const gchar *arg;
|
const gchar *arg;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
GSubprocess *subprocess;
|
GSubprocess *subprocess;
|
||||||
|
gchar *command_line = NULL;
|
||||||
|
gboolean success;
|
||||||
|
|
||||||
args = g_ptr_array_new ();
|
args = g_ptr_array_new ();
|
||||||
|
|
||||||
@@ -44,14 +46,20 @@ run (GError **error,
|
|||||||
g_ptr_array_add (args, NULL);
|
g_ptr_array_add (args, NULL);
|
||||||
va_end (ap);
|
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);
|
subprocess = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
|
||||||
g_ptr_array_free (args, TRUE);
|
g_ptr_array_free (args, TRUE);
|
||||||
|
|
||||||
if (subprocess == NULL)
|
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);
|
g_object_unref (subprocess);
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -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
|
/* 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) */
|
* 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);
|
if (!run (&error, bindfs, "-n", "-o", "ro", dir_to_mount, dir_mountpoint, NULL))
|
||||||
g_assert_no_error (error);
|
{
|
||||||
|
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 */
|
/* 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);
|
file_in_mountpoint = g_strdup_printf ("%s/example.txt", dir_mountpoint);
|
||||||
|
@@ -124,14 +124,14 @@ main (int argc,
|
|||||||
g_assert (g_spawn_command_line_async (path, NULL));
|
g_assert (g_spawn_command_line_async (path, NULL));
|
||||||
g_free (path);
|
g_free (path);
|
||||||
|
|
||||||
ensure_gdbus_testserver_up ();
|
|
||||||
|
|
||||||
/* Create the connection in the main thread */
|
/* Create the connection in the main thread */
|
||||||
error = NULL;
|
error = NULL;
|
||||||
c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert (c != NULL);
|
g_assert (c != NULL);
|
||||||
|
|
||||||
|
ensure_gdbus_testserver_up (c, NULL);
|
||||||
|
|
||||||
g_test_add_func ("/gdbus/connection-loss", test_connection_loss);
|
g_test_add_func ("/gdbus/connection-loss", test_connection_loss);
|
||||||
|
|
||||||
ret = g_test_run();
|
ret = g_test_run();
|
||||||
|
@@ -86,49 +86,72 @@ _give_up (gpointer data)
|
|||||||
g_return_val_if_reached (TRUE);
|
g_return_val_if_reached (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
typedef struct
|
||||||
ensure_gdbus_testserver_up (void)
|
|
||||||
{
|
{
|
||||||
guint id;
|
GMainContext *context;
|
||||||
gchar *name_owner;
|
gboolean name_appeared;
|
||||||
GDBusConnection *connection;
|
gboolean unwatch_complete;
|
||||||
GDBusProxy *proxy;
|
} WatchData;
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
connection = g_bus_get_sync (G_BUS_TYPE_SESSION,
|
static void
|
||||||
NULL,
|
name_appeared_cb (GDBusConnection *connection,
|
||||||
&error);
|
const gchar *name,
|
||||||
|
const gchar *name_owner,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
WatchData *data = user_data;
|
||||||
|
|
||||||
g_assert_no_error (error);
|
g_assert (name_owner != NULL);
|
||||||
error = NULL;
|
data->name_appeared = TRUE;
|
||||||
|
g_main_context_wakeup (data->context);
|
||||||
|
}
|
||||||
|
|
||||||
proxy = g_dbus_proxy_new_sync (connection,
|
static void
|
||||||
G_DBUS_PROXY_FLAGS_NONE,
|
watch_free_cb (gpointer user_data)
|
||||||
NULL, /* GDBusInterfaceInfo */
|
{
|
||||||
"com.example.TestService", /* name */
|
WatchData *data = user_data;
|
||||||
"/com/example/TestObject", /* object path */
|
|
||||||
"com.example.Frob", /* interface */
|
|
||||||
NULL, /* GCancellable */
|
|
||||||
&error);
|
|
||||||
g_assert_no_error (error);
|
|
||||||
|
|
||||||
id = g_timeout_add_seconds (60, _give_up,
|
data->unwatch_complete = TRUE;
|
||||||
"waited more than ~ 60s for gdbus-testserver to take its bus name");
|
g_main_context_wakeup (data->context);
|
||||||
|
}
|
||||||
|
|
||||||
while (TRUE)
|
void
|
||||||
{
|
ensure_gdbus_testserver_up (GDBusConnection *connection,
|
||||||
name_owner = g_dbus_proxy_get_name_owner (proxy);
|
GMainContext *context)
|
||||||
|
{
|
||||||
|
GSource *timeout_source = NULL;
|
||||||
|
guint watch_id;
|
||||||
|
WatchData data = { context, FALSE, FALSE };
|
||||||
|
|
||||||
if (name_owner != NULL)
|
g_main_context_push_thread_default (context);
|
||||||
break;
|
|
||||||
|
|
||||||
g_main_context_iteration (NULL, TRUE);
|
watch_id = g_bus_watch_name_on_connection (connection,
|
||||||
}
|
"com.example.TestService",
|
||||||
|
G_BUS_NAME_WATCHER_FLAGS_NONE,
|
||||||
|
name_appeared_cb,
|
||||||
|
NULL,
|
||||||
|
&data,
|
||||||
|
watch_free_cb);
|
||||||
|
|
||||||
g_source_remove (id);
|
timeout_source = g_timeout_source_new_seconds (60);
|
||||||
g_free (name_owner);
|
g_source_set_callback (timeout_source, _give_up,
|
||||||
g_object_unref (proxy);
|
"waited more than ~ 60s for gdbus-testserver to take its bus name",
|
||||||
g_object_unref (connection);
|
NULL);
|
||||||
|
g_source_attach (timeout_source, context);
|
||||||
|
|
||||||
|
while (!data.name_appeared)
|
||||||
|
g_main_context_iteration (context, TRUE);
|
||||||
|
|
||||||
|
g_bus_unwatch_name (watch_id);
|
||||||
|
watch_id = 0;
|
||||||
|
|
||||||
|
while (!data.unwatch_complete)
|
||||||
|
g_main_context_iteration (context, TRUE);
|
||||||
|
|
||||||
|
g_source_destroy (timeout_source);
|
||||||
|
g_source_unref (timeout_source);
|
||||||
|
|
||||||
|
g_main_context_pop_thread_default (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
@@ -114,7 +114,8 @@ GDBusConnection *_g_bus_get_priv (GBusType bus_type,
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
void ensure_gdbus_testserver_up (void);
|
void ensure_gdbus_testserver_up (GDBusConnection *connection,
|
||||||
|
GMainContext *context);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@@ -27,59 +27,77 @@
|
|||||||
/* all tests rely on a global connection */
|
/* all tests rely on a global connection */
|
||||||
static GDBusConnection *c = NULL;
|
static GDBusConnection *c = NULL;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GMainContext *context;
|
||||||
|
gboolean timed_out;
|
||||||
|
} TimeoutData;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
timeout_cb (gpointer user_data)
|
||||||
|
{
|
||||||
|
TimeoutData *data = user_data;
|
||||||
|
|
||||||
|
data->timed_out = TRUE;
|
||||||
|
g_main_context_wakeup (data->context);
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that the given @connection has only one ref, waiting to let any pending
|
||||||
|
* unrefs complete first. This is typically used on the shared connection, to
|
||||||
|
* ensure it’s in a correct state before beginning the next test. */
|
||||||
|
static void
|
||||||
|
assert_connection_has_one_ref (GDBusConnection *connection,
|
||||||
|
GMainContext *context)
|
||||||
|
{
|
||||||
|
GSource *timeout_source = NULL;
|
||||||
|
TimeoutData data = { context, FALSE };
|
||||||
|
|
||||||
|
if (g_atomic_int_get (&G_OBJECT (connection)->ref_count) == 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
timeout_source = g_timeout_source_new_seconds (1);
|
||||||
|
g_source_set_callback (timeout_source, timeout_cb, &data, NULL);
|
||||||
|
g_source_attach (timeout_source, context);
|
||||||
|
|
||||||
|
while (g_atomic_int_get (&G_OBJECT (connection)->ref_count) != 1 && !data.timed_out)
|
||||||
|
{
|
||||||
|
g_debug ("refcount of %p is not right, sleeping", connection);
|
||||||
|
g_main_context_iteration (NULL, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_source_destroy (timeout_source);
|
||||||
|
g_source_unref (timeout_source);
|
||||||
|
|
||||||
|
if (g_atomic_int_get (&G_OBJECT (connection)->ref_count) != 1)
|
||||||
|
g_error ("connection %p had too many refs", connection);
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
/* Ensure that signal and method replies are delivered in the right thread */
|
/* Ensure that signal and method replies are delivered in the right thread */
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GThread *thread;
|
GThread *thread;
|
||||||
GMainLoop *thread_loop;
|
GMainContext *context;
|
||||||
guint signal_count;
|
guint signal_count;
|
||||||
|
gboolean unsubscribe_complete;
|
||||||
|
GAsyncResult *async_result;
|
||||||
} DeliveryData;
|
} DeliveryData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
msg_cb_expect_success (GDBusConnection *connection,
|
async_result_cb (GDBusConnection *connection,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
DeliveryData *data = user_data;
|
DeliveryData *data = user_data;
|
||||||
GError *error;
|
|
||||||
GVariant *result;
|
|
||||||
|
|
||||||
error = NULL;
|
data->async_result = g_object_ref (res);
|
||||||
result = g_dbus_connection_call_finish (connection,
|
|
||||||
res,
|
|
||||||
&error);
|
|
||||||
g_assert_no_error (error);
|
|
||||||
g_assert (result != NULL);
|
|
||||||
g_variant_unref (result);
|
|
||||||
|
|
||||||
g_assert (g_thread_self () == data->thread);
|
g_assert_true (g_thread_self () == data->thread);
|
||||||
|
|
||||||
g_main_loop_quit (data->thread_loop);
|
g_main_context_wakeup (data->context);
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
msg_cb_expect_error_cancelled (GDBusConnection *connection,
|
|
||||||
GAsyncResult *res,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
DeliveryData *data = user_data;
|
|
||||||
GError *error;
|
|
||||||
GVariant *result;
|
|
||||||
|
|
||||||
error = NULL;
|
|
||||||
result = g_dbus_connection_call_finish (connection,
|
|
||||||
res,
|
|
||||||
&error);
|
|
||||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
|
||||||
g_assert (!g_dbus_error_is_remote_error (error));
|
|
||||||
g_error_free (error);
|
|
||||||
g_assert (result == NULL);
|
|
||||||
|
|
||||||
g_assert (g_thread_self () == data->thread);
|
|
||||||
|
|
||||||
g_main_loop_quit (data->thread_loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -93,33 +111,43 @@ signal_handler (GDBusConnection *connection,
|
|||||||
{
|
{
|
||||||
DeliveryData *data = user_data;
|
DeliveryData *data = user_data;
|
||||||
|
|
||||||
g_assert (g_thread_self () == data->thread);
|
g_assert_true (g_thread_self () == data->thread);
|
||||||
|
|
||||||
data->signal_count++;
|
data->signal_count++;
|
||||||
|
|
||||||
g_main_loop_quit (data->thread_loop);
|
g_main_context_wakeup (data->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
signal_data_free_cb (gpointer user_data)
|
||||||
|
{
|
||||||
|
DeliveryData *data = user_data;
|
||||||
|
|
||||||
|
g_assert_true (g_thread_self () == data->thread);
|
||||||
|
|
||||||
|
data->unsubscribe_complete = TRUE;
|
||||||
|
|
||||||
|
g_main_context_wakeup (data->context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
test_delivery_in_thread_func (gpointer _data)
|
test_delivery_in_thread_func (gpointer _data)
|
||||||
{
|
{
|
||||||
GMainLoop *thread_loop;
|
|
||||||
GMainContext *thread_context;
|
GMainContext *thread_context;
|
||||||
DeliveryData data;
|
DeliveryData data;
|
||||||
GCancellable *ca;
|
GCancellable *ca;
|
||||||
guint subscription_id;
|
guint subscription_id;
|
||||||
GDBusConnection *priv_c;
|
GError *error = NULL;
|
||||||
GError *error;
|
GVariant *result_variant = NULL;
|
||||||
|
|
||||||
error = NULL;
|
|
||||||
|
|
||||||
thread_context = g_main_context_new ();
|
thread_context = g_main_context_new ();
|
||||||
thread_loop = g_main_loop_new (thread_context, FALSE);
|
|
||||||
g_main_context_push_thread_default (thread_context);
|
g_main_context_push_thread_default (thread_context);
|
||||||
|
|
||||||
data.thread = g_thread_self ();
|
data.thread = g_thread_self ();
|
||||||
data.thread_loop = thread_loop;
|
data.context = thread_context;
|
||||||
data.signal_count = 0;
|
data.signal_count = 0;
|
||||||
|
data.unsubscribe_complete = FALSE;
|
||||||
|
data.async_result = NULL;
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
@@ -135,9 +163,16 @@ test_delivery_in_thread_func (gpointer _data)
|
|||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
NULL,
|
NULL,
|
||||||
(GAsyncReadyCallback) msg_cb_expect_success,
|
(GAsyncReadyCallback) async_result_cb,
|
||||||
&data);
|
&data);
|
||||||
g_main_loop_run (thread_loop);
|
while (data.async_result == NULL)
|
||||||
|
g_main_context_iteration (thread_context, TRUE);
|
||||||
|
|
||||||
|
result_variant = g_dbus_connection_call_finish (c, data.async_result, &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_assert_nonnull (result_variant);
|
||||||
|
g_clear_pointer (&result_variant, g_variant_unref);
|
||||||
|
g_clear_object (&data.async_result);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that we never actually send a message if the GCancellable
|
* Check that we never actually send a message if the GCancellable
|
||||||
@@ -155,9 +190,18 @@ test_delivery_in_thread_func (gpointer _data)
|
|||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
ca,
|
ca,
|
||||||
(GAsyncReadyCallback) msg_cb_expect_error_cancelled,
|
(GAsyncReadyCallback) async_result_cb,
|
||||||
&data);
|
&data);
|
||||||
g_main_loop_run (thread_loop);
|
while (data.async_result == NULL)
|
||||||
|
g_main_context_iteration (thread_context, TRUE);
|
||||||
|
|
||||||
|
result_variant = g_dbus_connection_call_finish (c, data.async_result, &error);
|
||||||
|
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
||||||
|
g_assert_false (g_dbus_error_is_remote_error (error));
|
||||||
|
g_clear_error (&error);
|
||||||
|
g_assert_null (result_variant);
|
||||||
|
g_clear_object (&data.async_result);
|
||||||
|
|
||||||
g_object_unref (ca);
|
g_object_unref (ca);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -173,47 +217,74 @@ test_delivery_in_thread_func (gpointer _data)
|
|||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
-1,
|
-1,
|
||||||
ca,
|
ca,
|
||||||
(GAsyncReadyCallback) msg_cb_expect_error_cancelled,
|
(GAsyncReadyCallback) async_result_cb,
|
||||||
&data);
|
&data);
|
||||||
g_cancellable_cancel (ca);
|
g_cancellable_cancel (ca);
|
||||||
g_main_loop_run (thread_loop);
|
|
||||||
|
while (data.async_result == NULL)
|
||||||
|
g_main_context_iteration (thread_context, TRUE);
|
||||||
|
|
||||||
|
result_variant = g_dbus_connection_call_finish (c, data.async_result, &error);
|
||||||
|
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
||||||
|
g_assert_false (g_dbus_error_is_remote_error (error));
|
||||||
|
g_clear_error (&error);
|
||||||
|
g_assert_null (result_variant);
|
||||||
|
g_clear_object (&data.async_result);
|
||||||
|
|
||||||
g_object_unref (ca);
|
g_object_unref (ca);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that signals are delivered to the correct thread.
|
* Check that signals are delivered to the correct thread.
|
||||||
*
|
*
|
||||||
* First we subscribe to the signal, then we create a a private
|
* First we subscribe to the signal, then we call EmitSignal(). This should
|
||||||
* connection. This should cause a NameOwnerChanged message from
|
* cause a TestSignal emission from the testserver.
|
||||||
* the message bus.
|
|
||||||
*/
|
*/
|
||||||
subscription_id = g_dbus_connection_signal_subscribe (c,
|
subscription_id = g_dbus_connection_signal_subscribe (c,
|
||||||
"org.freedesktop.DBus", /* sender */
|
"com.example.TestService", /* sender */
|
||||||
"org.freedesktop.DBus", /* interface */
|
"com.example.Frob", /* interface */
|
||||||
"NameOwnerChanged", /* member */
|
"TestSignal", /* member */
|
||||||
"/org/freedesktop/DBus", /* path */
|
"/com/example/TestObject", /* path */
|
||||||
NULL,
|
NULL,
|
||||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||||
signal_handler,
|
signal_handler,
|
||||||
&data,
|
&data,
|
||||||
NULL);
|
signal_data_free_cb);
|
||||||
g_assert (subscription_id != 0);
|
g_assert_cmpuint (subscription_id, !=, 0);
|
||||||
g_assert (data.signal_count == 0);
|
g_assert_cmpuint (data.signal_count, ==, 0);
|
||||||
|
|
||||||
priv_c = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &error);
|
g_dbus_connection_call (c,
|
||||||
|
"com.example.TestService", /* bus_name */
|
||||||
|
"/com/example/TestObject", /* object path */
|
||||||
|
"com.example.Frob", /* interface name */
|
||||||
|
"EmitSignal", /* method name */
|
||||||
|
g_variant_new_parsed ("('hello', @o '/com/example/TestObject')"),
|
||||||
|
NULL,
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
NULL,
|
||||||
|
(GAsyncReadyCallback) async_result_cb,
|
||||||
|
&data);
|
||||||
|
while (data.async_result == NULL || data.signal_count < 1)
|
||||||
|
g_main_context_iteration (thread_context, TRUE);
|
||||||
|
|
||||||
|
result_variant = g_dbus_connection_call_finish (c, data.async_result, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert (priv_c != NULL);
|
g_assert_nonnull (result_variant);
|
||||||
|
g_clear_pointer (&result_variant, g_variant_unref);
|
||||||
|
g_clear_object (&data.async_result);
|
||||||
|
|
||||||
g_main_loop_run (thread_loop);
|
g_assert_cmpuint (data.signal_count, ==, 1);
|
||||||
g_assert (data.signal_count == 1);
|
|
||||||
|
|
||||||
g_object_unref (priv_c);
|
|
||||||
|
|
||||||
g_dbus_connection_signal_unsubscribe (c, subscription_id);
|
g_dbus_connection_signal_unsubscribe (c, subscription_id);
|
||||||
|
subscription_id = 0;
|
||||||
|
|
||||||
|
while (!data.unsubscribe_complete)
|
||||||
|
g_main_context_iteration (thread_context, TRUE);
|
||||||
|
g_assert_true (data.unsubscribe_complete);
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
g_main_context_pop_thread_default (thread_context);
|
g_main_context_pop_thread_default (thread_context);
|
||||||
g_main_loop_unref (thread_loop);
|
|
||||||
g_main_context_unref (thread_context);
|
g_main_context_unref (thread_context);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -229,6 +300,8 @@ test_delivery_in_thread (void)
|
|||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
g_thread_join (thread);
|
g_thread_join (thread);
|
||||||
|
|
||||||
|
assert_connection_has_one_ref (c, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
@@ -257,11 +330,11 @@ sleep_cb (GDBusProxy *proxy,
|
|||||||
res,
|
res,
|
||||||
&error);
|
&error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert (result != NULL);
|
g_assert_nonnull (result);
|
||||||
g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
|
g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
|
||||||
g_variant_unref (result);
|
g_variant_unref (result);
|
||||||
|
|
||||||
g_assert (data->thread == g_thread_self ());
|
g_assert_true (data->thread == g_thread_self ());
|
||||||
|
|
||||||
g_main_loop_quit (data->thread_loop);
|
g_main_loop_quit (data->thread_loop);
|
||||||
|
|
||||||
@@ -317,7 +390,7 @@ test_sleep_in_thread_func (gpointer _data)
|
|||||||
g_printerr ("S");
|
g_printerr ("S");
|
||||||
//g_debug ("done invoking sync (%p)", g_thread_self ());
|
//g_debug ("done invoking sync (%p)", g_thread_self ());
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert (result != NULL);
|
g_assert_nonnull (result);
|
||||||
g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
|
g_assert_cmpstr (g_variant_get_type_string (result), ==, "()");
|
||||||
g_variant_unref (result);
|
g_variant_unref (result);
|
||||||
}
|
}
|
||||||
@@ -441,6 +514,8 @@ test_method_calls_in_thread (void)
|
|||||||
|
|
||||||
if (g_test_verbose ())
|
if (g_test_verbose ())
|
||||||
g_printerr ("\n");
|
g_printerr ("\n");
|
||||||
|
|
||||||
|
assert_connection_has_one_ref (c, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SLEEP_MIN_USEC 1
|
#define SLEEP_MIN_USEC 1
|
||||||
@@ -457,8 +532,8 @@ ensure_connection_works (GDBusConnection *conn)
|
|||||||
"/org/freedesktop/DBus", "org.freedesktop.DBus", "GetId", NULL, NULL, 0, -1,
|
"/org/freedesktop/DBus", "org.freedesktop.DBus", "GetId", NULL, NULL, 0, -1,
|
||||||
NULL, &error);
|
NULL, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert (v != NULL);
|
g_assert_nonnull (v);
|
||||||
g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE ("(s)")));
|
g_assert_true (g_variant_is_of_type (v, G_VARIANT_TYPE ("(s)")));
|
||||||
g_variant_unref (v);
|
g_variant_unref (v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,24 +580,11 @@ test_threaded_singleton (void)
|
|||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
GThread *thread;
|
GThread *thread;
|
||||||
guint j;
|
|
||||||
guint unref_delay, get_delay;
|
guint unref_delay, get_delay;
|
||||||
GDBusConnection *new_conn;
|
GDBusConnection *new_conn;
|
||||||
|
|
||||||
/* We want to be the last ref, so let it finish setting up */
|
/* We want to be the last ref, so let it finish setting up */
|
||||||
for (j = 0; j < 100; j++)
|
assert_connection_has_one_ref (c, NULL);
|
||||||
{
|
|
||||||
guint r = (guint) g_atomic_int_get (&G_OBJECT (c)->ref_count);
|
|
||||||
|
|
||||||
if (r == 1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
g_debug ("run %u: refcount is %u, sleeping", i, r);
|
|
||||||
g_usleep (1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j == 100)
|
|
||||||
g_error ("connection had too many refs");
|
|
||||||
|
|
||||||
if (g_test_verbose () && (i % (n/50)) == 0)
|
if (g_test_verbose () && (i % (n/50)) == 0)
|
||||||
g_printerr ("%u%%\n", ((i * 100) / n));
|
g_printerr ("%u%%\n", ((i * 100) / n));
|
||||||
@@ -586,16 +648,16 @@ main (int argc,
|
|||||||
|
|
||||||
/* this is safe; testserver will exit once the bus goes away */
|
/* this is safe; testserver will exit once the bus goes away */
|
||||||
path = g_test_build_filename (G_TEST_BUILT, "gdbus-testserver", NULL);
|
path = g_test_build_filename (G_TEST_BUILT, "gdbus-testserver", NULL);
|
||||||
g_assert (g_spawn_command_line_async (path, NULL));
|
g_assert_true (g_spawn_command_line_async (path, NULL));
|
||||||
g_free (path);
|
g_free (path);
|
||||||
|
|
||||||
ensure_gdbus_testserver_up ();
|
|
||||||
|
|
||||||
/* Create the connection in the main thread */
|
/* Create the connection in the main thread */
|
||||||
error = NULL;
|
error = NULL;
|
||||||
c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert (c != NULL);
|
g_assert_nonnull (c);
|
||||||
|
|
||||||
|
ensure_gdbus_testserver_up (c, NULL);
|
||||||
|
|
||||||
g_test_add_func ("/gdbus/delivery-in-thread", test_delivery_in_thread);
|
g_test_add_func ("/gdbus/delivery-in-thread", test_delivery_in_thread);
|
||||||
g_test_add_func ("/gdbus/method-calls-in-thread", test_method_calls_in_thread);
|
g_test_add_func ("/gdbus/method-calls-in-thread", test_method_calls_in_thread);
|
||||||
|
@@ -302,7 +302,7 @@ if host_machine.system() != 'windows'
|
|||||||
},
|
},
|
||||||
'gdbus-threading' : {
|
'gdbus-threading' : {
|
||||||
'extra_sources' : extra_sources,
|
'extra_sources' : extra_sources,
|
||||||
'suite' : ['slow', 'flaky'],
|
'suite' : ['slow'],
|
||||||
},
|
},
|
||||||
'gmenumodel' : {
|
'gmenumodel' : {
|
||||||
'extra_sources' : extra_sources,
|
'extra_sources' : extra_sources,
|
||||||
|
Reference in New Issue
Block a user