mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-03 14:42:10 +01:00
Add work-around for Bug 627724
The root problem is with GObject - for now, just work around it in GDBus. Also include a test-case. See https://bugzilla.gnome.org/show_bug.cgi?id=627724 for more information. Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
parent
12029eeb6a
commit
0b74058fa3
@ -229,6 +229,34 @@ _g_socket_read_with_control_messages_finish (GSocket *socket,
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* Work-around for https://bugzilla.gnome.org/show_bug.cgi?id=627724 */
|
||||
|
||||
static GPtrArray *ensured_classes = NULL;
|
||||
|
||||
static void
|
||||
ensure_type (GType gtype)
|
||||
{
|
||||
g_ptr_array_add (ensured_classes, g_type_class_ref (gtype));
|
||||
}
|
||||
|
||||
static void
|
||||
released_required_types (void)
|
||||
{
|
||||
g_ptr_array_foreach (ensured_classes, (GFunc) g_type_class_unref, NULL);
|
||||
g_ptr_array_unref (ensured_classes);
|
||||
ensured_classes = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_required_types (void)
|
||||
{
|
||||
g_assert (ensured_classes == NULL);
|
||||
ensured_classes = g_ptr_array_new ();
|
||||
ensure_type (G_TYPE_SIMPLE_ASYNC_RESULT);
|
||||
ensure_type (G_TYPE_MEMORY_INPUT_STREAM);
|
||||
}
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
G_LOCK_DEFINE_STATIC (shared_thread_lock);
|
||||
|
||||
typedef struct
|
||||
@ -242,7 +270,7 @@ typedef struct
|
||||
static SharedThreadData *shared_thread_data = NULL;
|
||||
|
||||
static gpointer
|
||||
shared_thread_func (gpointer data)
|
||||
gdbus_shared_thread_func (gpointer data)
|
||||
{
|
||||
g_main_context_push_thread_default (shared_thread_data->context);
|
||||
g_main_loop_run (shared_thread_data->loop);
|
||||
@ -268,6 +296,8 @@ invoke_caller (gpointer user_data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
_g_dbus_shared_thread_ref (GDBusSharedThreadFunc func,
|
||||
gpointer user_data)
|
||||
@ -275,9 +305,12 @@ _g_dbus_shared_thread_ref (GDBusSharedThreadFunc func,
|
||||
GError *error;
|
||||
GSource *idle_source;
|
||||
CallerData *data;
|
||||
gboolean release_types;
|
||||
|
||||
G_LOCK (shared_thread_lock);
|
||||
|
||||
release_types = FALSE;
|
||||
|
||||
if (shared_thread_data != NULL)
|
||||
{
|
||||
shared_thread_data->num_users += 1;
|
||||
@ -287,10 +320,14 @@ _g_dbus_shared_thread_ref (GDBusSharedThreadFunc func,
|
||||
shared_thread_data = g_new0 (SharedThreadData, 1);
|
||||
shared_thread_data->num_users = 1;
|
||||
|
||||
/* Work-around for https://bugzilla.gnome.org/show_bug.cgi?id=627724 */
|
||||
ensure_required_types ();
|
||||
release_types = TRUE;
|
||||
|
||||
error = NULL;
|
||||
shared_thread_data->context = g_main_context_new ();
|
||||
shared_thread_data->loop = g_main_loop_new (shared_thread_data->context, FALSE);
|
||||
shared_thread_data->thread = g_thread_create (shared_thread_func,
|
||||
shared_thread_data->thread = g_thread_create (gdbus_shared_thread_func,
|
||||
NULL,
|
||||
TRUE,
|
||||
&error);
|
||||
@ -316,6 +353,9 @@ _g_dbus_shared_thread_ref (GDBusSharedThreadFunc func,
|
||||
while (!data->done)
|
||||
g_thread_yield ();
|
||||
|
||||
if (release_types)
|
||||
released_required_types ();
|
||||
|
||||
g_free (data);
|
||||
|
||||
G_UNLOCK (shared_thread_lock);
|
||||
|
@ -57,6 +57,7 @@ TEST_PROGS += \
|
||||
gdbus-peer \
|
||||
gdbus-exit-on-close \
|
||||
gdbus-non-socket \
|
||||
gdbus-bz627724 \
|
||||
application \
|
||||
testapps \
|
||||
appinfo \
|
||||
@ -217,6 +218,9 @@ endif
|
||||
gdbus_addresses_SOURCES = gdbus-addresses.c
|
||||
gdbus_addresses_LDADD = $(progs_ldadd)
|
||||
|
||||
gdbus_bz627724_SOURCES = gdbus-bz627724.c gdbus-sessionbus.c gdbus-sessionbus.h gdbus-tests.h gdbus-tests.c
|
||||
gdbus_bz627724_LDADD = $(progs_ldadd)
|
||||
|
||||
gdbus_connection_SOURCES = gdbus-connection.c gdbus-sessionbus.c gdbus-sessionbus.h gdbus-tests.h gdbus-tests.c
|
||||
gdbus_connection_LDADD = $(progs_ldadd)
|
||||
|
||||
|
94
gio/tests/gdbus-bz627724.c
Normal file
94
gio/tests/gdbus-bz627724.c
Normal file
@ -0,0 +1,94 @@
|
||||
/* GLib testing framework examples and tests
|
||||
*
|
||||
* Copyright (C) 2008-2010 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.
|
||||
*
|
||||
* Author: David Zeuthen <davidz@redhat.com>
|
||||
*/
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gdbus-tests.h"
|
||||
|
||||
static GDBusConnection *the_connection = NULL;
|
||||
|
||||
#define MY_TYPE_OBJECT (my_object_get_type ())
|
||||
#define MY_OBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MY_TYPE_OBJECT, MyObject))
|
||||
#define MY_IS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MY_TYPE_OBJECT))
|
||||
|
||||
typedef struct {
|
||||
GObject parent_instance;
|
||||
} MyObject;
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent_class;
|
||||
} MyObjectClass;
|
||||
|
||||
GType my_object_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_TYPE (MyObject, my_object, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
my_object_init (MyObject *object)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
my_object_class_init (MyObjectClass *klass)
|
||||
{
|
||||
GError *error;
|
||||
error = NULL;
|
||||
the_connection = g_bus_get_sync (G_BUS_TYPE_SESSION,
|
||||
NULL, /* GCancellable* */
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (G_IS_DBUS_CONNECTION (the_connection));
|
||||
}
|
||||
|
||||
static void
|
||||
test_bz627724 (void)
|
||||
{
|
||||
MyObject *object;
|
||||
|
||||
session_bus_up ();
|
||||
g_assert (the_connection == NULL);
|
||||
object = g_object_new (MY_TYPE_OBJECT, NULL);
|
||||
g_assert (the_connection != NULL);
|
||||
g_object_unref (the_connection);
|
||||
g_object_unref (object);
|
||||
session_bus_down ();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
/* all the tests use a session bus with a well-known address that we can bring up and down
|
||||
* using session_bus_up() and session_bus_down().
|
||||
*/
|
||||
g_unsetenv ("DISPLAY");
|
||||
g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE);
|
||||
|
||||
g_test_add_func ("/gdbus/bz627724", test_bz627724);
|
||||
return g_test_run();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user