libnm-glib: implement GInitable/GAsyncInitable in NMObject

Implement GInitable and GAsyncInitable in NMObject, with
implementations that synchronously or asynchonously load all
properties, and change _nm_object_ensure_inited() to run
g_initable_init().

Update the object/object-array property handling to initialize the
objects after creating them (synchronously or asynchronously,
according to the situation), so that they will have all of their
properties preloaded before they are ever visible to the caller.

Move the non-blocking/non-failable parts of various objects'
constructor() methods to constructed(), and move the blocking/failable
parts to init(), and implement init_async() methods with non-blocking
versions of the blocking methods.

Make nm_device_new() and nm_client_new() call
_nm_object_ensure_inited(), to preserve the behaviour formerly
enforced by their construct() methods, that properties are guaranteed
to be initialized before any signals involving them are emitted.
This commit is contained in:
Dan Winship 2011-12-20 15:15:42 -05:00 committed by Dan Williams
parent ad5daa098c
commit 9fd98ef91b
21 changed files with 637 additions and 421 deletions

View file

@ -43,7 +43,7 @@ libdeprecated_HEADERS = libnm_glib.h
lib_LTLIBRARIES = libnm-glib.la libnm-glib-vpn.la
libnm_glib_la_CFLAGS = \
$(GLIB_CFLAGS) \
$(GIO_CFLAGS) \
$(DBUS_CFLAGS) \
$(GUDEV_CFLAGS)
@ -117,7 +117,7 @@ libnm_glib_la_LIBADD = \
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/marshallers/libmarshallers.la \
$(builddir)/libdeprecated-nm-glib.la \
$(GLIB_LIBS) \
$(GIO_LIBS) \
$(DBUS_LIBS) \
$(GUDEV_LIBS)
@ -129,16 +129,16 @@ libnm_glib_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \
noinst_PROGRAMS = libnm-glib-test
libnm_glib_test_SOURCES = libnm-glib-test.c
libnm_glib_test_CFLAGS = $(GLIB_CFLAGS) $(DBUS_CFLAGS)
libnm_glib_test_LDADD = libnm-glib.la $(top_builddir)/libnm-util/libnm-util.la $(GLIB_LIBS) $(DBUS_LIBS)
libnm_glib_test_CFLAGS = $(GIO_CFLAGS) $(DBUS_CFLAGS)
libnm_glib_test_LDADD = libnm-glib.la $(top_builddir)/libnm-util/libnm-util.la $(GIO_LIBS) $(DBUS_LIBS)
libnm_glib_vpn_la_SOURCES = \
nm-vpn-plugin.c \
nm-vpn-plugin-ui-interface.c \
nm-vpn-plugin-utils.c
libnm_glib_vpn_la_CFLAGS = $(GLIB_CFLAGS) $(DBUS_CFLAGS)
libnm_glib_vpn_la_LIBADD = $(top_builddir)/libnm-util/libnm-util.la $(GLIB_LIBS) $(DBUS_LIBS)
libnm_glib_vpn_la_CFLAGS = $(GIO_CFLAGS) $(DBUS_CFLAGS)
libnm_glib_vpn_la_LIBADD = $(top_builddir)/libnm-util/libnm-util.la $(GIO_LIBS) $(DBUS_LIBS)
libnm_glib_vpn_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib-vpn.ver \
-version-info "2:0:1"
@ -147,7 +147,7 @@ libnm_glib_vpn_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib-vpn.ver \
#####################################################
libnm_glib_test_la_CFLAGS = \
$(GLIB_CFLAGS) \
$(GIO_CFLAGS) \
$(DBUS_CFLAGS) \
$(GUDEV_CFLAGS) \
-DLIBNM_GLIB_TEST
@ -159,7 +159,7 @@ libnm_glib_test_la_SOURCES = \
libnm_glib_test_la_LIBADD = \
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/marshallers/libmarshallers.la \
$(GLIB_LIBS) \
$(GIO_LIBS) \
$(DBUS_LIBS) \
$(GUDEV_LIBS)

View file

@ -533,30 +533,21 @@ register_properties (NMAccessPoint *ap)
property_info);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
NMObject *object;
NMAccessPointPrivate *priv;
object = (NMObject *) G_OBJECT_CLASS (nm_access_point_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_access_point_parent_class)->constructed (object);
priv = NM_ACCESS_POINT_GET_PRIVATE (object);
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object),
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
NM_DBUS_SERVICE,
nm_object_get_path (object),
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE_ACCESS_POINT);
register_properties (NM_ACCESS_POINT (object));
return G_OBJECT (object);
}
@ -568,7 +559,7 @@ nm_access_point_class_init (NMAccessPointClass *ap_class)
g_type_class_add_private (ap_class, sizeof (NMAccessPointPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;

View file

@ -445,30 +445,21 @@ register_properties (NMActiveConnection *connection)
property_info);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
NMObject *object;
NMActiveConnectionPrivate *priv;
object = (NMObject *) G_OBJECT_CLASS (nm_active_connection_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object);
priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object);
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object),
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
NM_DBUS_SERVICE,
nm_object_get_path (object),
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE_ACTIVE_CONNECTION);
register_properties (NM_ACTIVE_CONNECTION (object));
return G_OBJECT (object);
}
@ -480,7 +471,7 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class)
g_type_class_add_private (ap_class, sizeof (NMActiveConnectionPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;

View file

@ -39,7 +39,15 @@
void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled);
G_DEFINE_TYPE (NMClient, nm_client, NM_TYPE_OBJECT)
static void nm_client_initable_iface_init (GInitableIface *iface);
static void nm_client_async_initable_iface_init (GAsyncInitableIface *iface);
static GInitableIface *nm_client_parent_initable_iface;
static GAsyncInitableIface *nm_client_parent_async_initable_iface;
G_DEFINE_TYPE_WITH_CODE (NMClient, nm_client, NM_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_client_initable_iface_init);
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_client_async_initable_iface_init);
)
#define NM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CLIENT, NMClientPrivate))
@ -372,19 +380,21 @@ update_permissions (NMClient *self, GHashTable *permissions)
g_list_free (keys);
}
static void
get_permissions_sync (NMClient *self)
static gboolean
get_permissions_sync (NMClient *self, GError **error)
{
gboolean success;
GHashTable *permissions = NULL;
success = dbus_g_proxy_call_with_timeout (NM_CLIENT_GET_PRIVATE (self)->client_proxy,
"GetPermissions", 3000, NULL,
"GetPermissions", 3000, error,
G_TYPE_INVALID,
DBUS_TYPE_G_MAP_OF_STRING, &permissions, G_TYPE_INVALID);
update_permissions (self, success ? permissions : NULL);
if (permissions)
g_hash_table_destroy (permissions);
return success;
}
static void
@ -1191,6 +1201,7 @@ nm_client_new (void)
{
DBusGConnection *connection;
GError *err = NULL;
NMClient *client;
#ifdef LIBNM_GLIB_TEST
connection = dbus_g_bus_get (DBUS_BUS_SESSION, &err);
@ -1203,34 +1214,28 @@ nm_client_new (void)
return NULL;
}
return (NMClient *) g_object_new (NM_TYPE_CLIENT,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, NM_DBUS_PATH,
NULL);
client = g_object_new (NM_TYPE_CLIENT,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, NM_DBUS_PATH,
NULL);
_nm_object_ensure_inited (NM_OBJECT (client));
return client;
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
NMObject *object;
DBusGConnection *connection;
NMClientPrivate *priv;
GError *err = NULL;
object = (NMObject *) G_OBJECT_CLASS (nm_client_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_client_parent_class)->constructed (object);
priv = NM_CLIENT_GET_PRIVATE (object);
connection = nm_object_get_connection (object);
connection = nm_object_get_connection (NM_OBJECT (object));
priv->client_proxy = dbus_g_proxy_new_for_name (connection,
NM_DBUS_SERVICE,
nm_object_get_path (object),
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE);
register_properties (NM_CLIENT (object));
@ -1242,7 +1247,6 @@ constructor (GType type,
G_CALLBACK (client_recheck_permissions),
object,
NULL);
get_permissions_sync (NM_CLIENT (object));
priv->bus_proxy = dbus_g_proxy_new_for_name (connection,
DBUS_SERVICE_DBUS,
@ -1257,38 +1261,136 @@ constructor (GType type,
G_CALLBACK (proxy_name_owner_changed),
object, NULL);
if (!dbus_g_proxy_call (priv->bus_proxy,
"NameHasOwner", &err,
G_TYPE_STRING, NM_DBUS_SERVICE,
G_TYPE_INVALID,
G_TYPE_BOOLEAN, &priv->manager_running,
G_TYPE_INVALID)) {
g_warning ("Error on NameHasOwner DBUS call: %s", err->message);
g_error_free (err);
}
if (priv->manager_running) {
update_wireless_status (NM_CLIENT (object), FALSE);
update_wwan_status (NM_CLIENT (object), FALSE);
update_wimax_status (NM_CLIENT (object), FALSE);
nm_client_get_state (NM_CLIENT (object));
}
g_signal_connect (G_OBJECT (object), "notify::" NM_CLIENT_WIRELESS_ENABLED,
g_signal_connect (object, "notify::" NM_CLIENT_WIRELESS_ENABLED,
G_CALLBACK (wireless_enabled_cb), NULL);
g_signal_connect (object, "notify::" NM_CLIENT_ACTIVE_CONNECTIONS,
G_CALLBACK (active_connections_changed_cb), NULL);
}
/* Get initial devices from NM. It is important to do it early. Else,
* a 'lazy' call won't find removed device.
* Solves this case: DeviceRemoved signal is received, we get devices
* from NM, but the removed object path is not there any more, and
* NMClient doesn't have the device either.
*/
nm_client_get_devices (NM_CLIENT (object));
static gboolean
init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
{
NMClient *client = NM_CLIENT (initable);
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
return G_OBJECT (object);
if (!nm_client_parent_initable_iface->init (initable, cancellable, error))
return FALSE;
if (!dbus_g_proxy_call (priv->bus_proxy,
"NameHasOwner", error,
G_TYPE_STRING, NM_DBUS_SERVICE,
G_TYPE_INVALID,
G_TYPE_BOOLEAN, &priv->manager_running,
G_TYPE_INVALID))
return FALSE;
if (priv->manager_running && !get_permissions_sync (client, error))
return FALSE;
return TRUE;
}
typedef struct {
NMClient *client;
GSimpleAsyncResult *result;
gboolean properties_pending;
gboolean permissions_pending;
} NMClientInitData;
static void
init_async_complete (NMClientInitData *init_data)
{
if (init_data->properties_pending || init_data->permissions_pending)
return;
g_simple_async_result_complete (init_data->result);
g_object_unref (init_data->result);
g_slice_free (NMClientInitData, init_data);
}
static void
init_async_got_permissions (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
{
NMClientInitData *init_data = user_data;
GHashTable *permissions;
GError *error = NULL;
dbus_g_proxy_end_call (proxy, call, &error,
DBUS_TYPE_G_MAP_OF_STRING, &permissions,
G_TYPE_INVALID);
update_permissions (init_data->client, error ? NULL : permissions);
g_clear_error (&error);
init_data->permissions_pending = FALSE;
init_async_complete (init_data);
}
static void
init_async_got_properties (GObject *source, GAsyncResult *result, gpointer user_data)
{
NMClientInitData *init_data = user_data;
GError *error = NULL;
if (!nm_client_parent_async_initable_iface->init_finish (G_ASYNC_INITABLE (source), result, &error))
g_simple_async_result_take_error (init_data->result, error);
init_data->properties_pending = FALSE;
init_async_complete (init_data);
}
static void
init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call,
gpointer user_data)
{
NMClientInitData *init_data = user_data;
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (init_data->client);
GError *error = NULL;
if (!dbus_g_proxy_end_call (proxy, call, &error,
G_TYPE_BOOLEAN, &priv->manager_running,
G_TYPE_INVALID)) {
g_simple_async_result_take_error (init_data->result, error);
init_async_complete (init_data);
return;
}
if (!priv->manager_running) {
g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE);
init_async_complete (init_data);
return;
}
nm_client_parent_async_initable_iface->init_async (G_ASYNC_INITABLE (init_data->client),
G_PRIORITY_DEFAULT, NULL, /* FIXME cancellable */
init_async_got_properties, init_data);
init_data->properties_pending = TRUE;
dbus_g_proxy_begin_call (priv->client_proxy, "GetPermissions",
init_async_got_permissions, init_data, NULL,
G_TYPE_INVALID);
init_data->permissions_pending = TRUE;
}
static void
init_async (GAsyncInitable *initable, int io_priority,
GCancellable *cancellable, GAsyncReadyCallback callback,
gpointer user_data)
{
NMClientInitData *init_data;
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (initable);
init_data = g_slice_new0 (NMClientInitData);
init_data->client = NM_CLIENT (initable);
init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback,
user_data, init_async);
/* Check if NM is running */
dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner",
init_async_got_manager_running,
init_data, NULL,
G_TYPE_STRING, NM_DBUS_SERVICE,
G_TYPE_INVALID);
}
static void
@ -1427,7 +1529,7 @@ nm_client_class_init (NMClientClass *client_class)
g_type_class_add_private (client_class, sizeof (NMClientPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->dispose = dispose;
@ -1631,3 +1733,18 @@ nm_client_class_init (NMClientClass *client_class)
G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
}
static void
nm_client_initable_iface_init (GInitableIface *iface)
{
nm_client_parent_initable_iface = g_type_interface_peek_parent (iface);
iface->init = init_sync;
}
static void
nm_client_async_initable_iface_init (GAsyncInitableIface *iface)
{
nm_client_parent_async_initable_iface = g_type_interface_peek_parent (iface);
iface->init_async = init_async;
}

View file

@ -216,28 +216,19 @@ register_properties (NMDeviceBt *device)
property_info);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
GObject *object;
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object);
object = G_OBJECT_CLASS (nm_device_bt_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (object) {
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object);
G_OBJECT_CLASS (nm_device_bt_parent_class)->constructed (object);
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
NM_DBUS_SERVICE,
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE_DEVICE_BLUETOOTH);
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
NM_DBUS_SERVICE,
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE_DEVICE_BLUETOOTH);
register_properties (NM_DEVICE_BT (object));
}
return object;
register_properties (NM_DEVICE_BT (object));
}
static void
@ -300,7 +291,7 @@ nm_device_bt_class_init (NMDeviceBtClass *bt_class)
g_type_class_add_private (bt_class, sizeof (NMDeviceBtPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->dispose = dispose;
object_class->finalize = finalize;
object_class->get_property = get_property;

View file

@ -75,13 +75,17 @@ enum {
GObject *
nm_device_ethernet_new (DBusGConnection *connection, const char *path)
{
GObject *device;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (path != NULL, NULL);
return g_object_new (NM_TYPE_DEVICE_ETHERNET,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
device = g_object_new (NM_TYPE_DEVICE_ETHERNET,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
_nm_object_ensure_inited (NM_OBJECT (device));
return device;
}
/**
@ -224,19 +228,12 @@ register_properties (NMDeviceEthernet *device)
property_info);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
GObject *object;
NMDeviceEthernetPrivate *priv;
object = G_OBJECT_CLASS (nm_device_ethernet_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_device_ethernet_parent_class)->constructed (object);
priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object);
@ -246,8 +243,6 @@ constructor (GType type,
NM_DBUS_INTERFACE_DEVICE_WIRED);
register_properties (NM_DEVICE_ETHERNET (object));
return object;
}
static void
@ -314,7 +309,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class)
g_type_class_add_private (eth_class, sizeof (NMDeviceEthernetPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->dispose = dispose;
object_class->finalize = finalize;
object_class->get_property = get_property;

View file

@ -68,13 +68,17 @@ enum {
GObject *
nm_device_infiniband_new (DBusGConnection *connection, const char *path)
{
GObject *device;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (path != NULL, NULL);
return g_object_new (NM_TYPE_DEVICE_INFINIBAND,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
device = g_object_new (NM_TYPE_DEVICE_INFINIBAND,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
_nm_object_ensure_inited (NM_OBJECT (device));
return device;
}
/**
@ -168,19 +172,12 @@ register_properties (NMDeviceInfiniband *device)
property_info);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
GObject *object;
NMDeviceInfinibandPrivate *priv;
object = G_OBJECT_CLASS (nm_device_infiniband_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_device_infiniband_parent_class)->constructed (object);
priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (object);
@ -190,8 +187,6 @@ constructor (GType type,
NM_DBUS_INTERFACE_DEVICE_INFINIBAND);
register_properties (NM_DEVICE_INFINIBAND (object));
return object;
}
static void
@ -247,7 +242,7 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *eth_class)
g_type_class_add_private (eth_class, sizeof (NMDeviceInfinibandPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->dispose = dispose;
object_class->finalize = finalize;
object_class->get_property = get_property;

View file

@ -147,29 +147,21 @@ register_properties (NMDeviceModem *device)
property_info);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
GObject *object;
NMDeviceModemPrivate *priv;
object = G_OBJECT_CLASS (nm_device_modem_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (object) {
priv = NM_DEVICE_MODEM_GET_PRIVATE (object);
G_OBJECT_CLASS (nm_device_modem_parent_class)->constructed (object);
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
NM_DBUS_SERVICE,
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE_DEVICE_MODEM);
priv = NM_DEVICE_MODEM_GET_PRIVATE (object);
register_properties (NM_DEVICE_MODEM (object));
}
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
NM_DBUS_SERVICE,
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE_DEVICE_MODEM);
return object;
register_properties (NM_DEVICE_MODEM (object));
}
static void
@ -224,7 +216,7 @@ nm_device_modem_class_init (NMDeviceModemClass *modem_class)
g_type_class_add_private (modem_class, sizeof (NMDeviceModemPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->dispose = dispose;
device_class->connection_valid = connection_valid;

View file

@ -97,13 +97,17 @@ static guint signals[LAST_SIGNAL] = { 0 };
GObject *
nm_device_wifi_new (DBusGConnection *connection, const char *path)
{
GObject *device;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (path != NULL, NULL);
return g_object_new (NM_TYPE_DEVICE_WIFI,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
device = g_object_new (NM_TYPE_DEVICE_WIFI,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
_nm_object_ensure_inited (NM_OBJECT (device));
return device;
}
/**
@ -538,19 +542,12 @@ register_properties (NMDeviceWifi *device)
access_point_removed);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
GObject *object;
NMDeviceWifiPrivate *priv;
object = G_OBJECT_CLASS (nm_device_wifi_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_device_wifi_parent_class)->constructed (object);
priv = NM_DEVICE_WIFI_GET_PRIVATE (object);
@ -565,15 +562,6 @@ constructor (GType type,
"notify::" NM_DEVICE_STATE,
G_CALLBACK (state_changed_cb),
NULL);
/* Get initial access points to prevent possible errors on
* AccessPointRemoved signal processing. We could make D-Bus
* GetAccessPoints() call on a removed WiFi device object (when
* AccessPointRemoved was triggered by removing the device).
*/
nm_device_wifi_get_access_points (NM_DEVICE_WIFI (object));
return object;
}
static void
@ -614,7 +602,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class)
g_type_class_add_private (wifi_class, sizeof (NMDeviceWifiPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;

View file

@ -97,13 +97,17 @@ static guint signals[LAST_SIGNAL] = { 0 };
GObject *
nm_device_wimax_new (DBusGConnection *connection, const char *path)
{
GObject *device;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (path != NULL, NULL);
return g_object_new (NM_TYPE_DEVICE_WIMAX,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
device = g_object_new (NM_TYPE_DEVICE_WIMAX,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
_nm_object_ensure_inited (NM_OBJECT (device));
return device;
}
/**
@ -525,19 +529,12 @@ register_properties (NMDeviceWimax *wimax)
nsp_removed);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
GObject *object;
NMDeviceWimaxPrivate *priv;
object = G_OBJECT_CLASS (nm_device_wimax_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_device_wimax_parent_class)->constructed (object);
priv = NM_DEVICE_WIMAX_GET_PRIVATE (object);
@ -552,8 +549,6 @@ constructor (GType type,
"notify::" NM_DEVICE_STATE,
G_CALLBACK (state_changed_cb),
NULL);
return object;
}
static void
@ -586,7 +581,7 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
g_type_class_add_private (wimax_class, sizeof (NMDeviceWimaxPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->dispose = dispose;
device_class->connection_valid = connection_valid;

View file

@ -163,83 +163,21 @@ device_state_changed (DBusGProxy *proxy,
}
static void
get_all_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
constructed (GObject *object)
{
NMObject *self = NM_OBJECT (user_data);
GHashTable *props = NULL;
GError *error = NULL;
if (!dbus_g_proxy_end_call (proxy, call, &error,
DBUS_TYPE_G_MAP_OF_VARIANT, &props,
G_TYPE_INVALID)) {
if (!(error->domain == DBUS_GERROR && error->code == DBUS_GERROR_NO_REPLY)) {
g_warning ("%s: couldn't retrieve device properties: (%d) %s.",
__func__,
error ? error->code : -1,
(error && error->message) ? error->message : "(unknown)");
}
g_clear_error (&error);
g_object_unref (proxy);
return;
}
g_object_unref (proxy);
_nm_object_process_properties_changed (NM_OBJECT (self), props);
g_hash_table_destroy (props);
}
static void
initialize_properties (NMObject *object)
{
DBusGProxy *props_proxy;
/* D-Bus properties proxy */
props_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object),
NM_DBUS_SERVICE,
nm_object_get_path (object),
"org.freedesktop.DBus.Properties");
g_assert (props_proxy);
/* Get properties */
dbus_g_proxy_begin_call (props_proxy, "GetAll",
get_all_cb,
object,
NULL,
G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE,
G_TYPE_INVALID);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
{
NMObject *object;
NMDevicePrivate *priv;
object = (NMObject *) G_OBJECT_CLASS (nm_device_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_device_parent_class)->constructed (object);
priv = NM_DEVICE_GET_PRIVATE (object);
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object),
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
NM_DBUS_SERVICE,
nm_object_get_path (object),
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE_DEVICE);
register_properties (NM_DEVICE (object));
/* Get initial properties, so that we have all properties set even if
* no PropertiesChanged signal is received.
* It has to be called after register_for_property_changed().
*/
initialize_properties (object);
dbus_g_object_register_marshaller (_nm_marshal_VOID__UINT_UINT_UINT,
G_TYPE_NONE,
G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT,
@ -254,8 +192,6 @@ constructor (GType type,
G_CALLBACK (device_state_changed),
NM_DEVICE (object),
NULL);
return G_OBJECT (object);
}
static void
@ -393,7 +329,7 @@ nm_device_class_init (NMDeviceClass *device_class)
g_type_class_add_private (device_class, sizeof (NMDevicePrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->set_property = set_property;
object_class->dispose = dispose;
@ -704,6 +640,7 @@ GObject *
nm_device_new (DBusGConnection *connection, const char *path)
{
GType dtype;
NMDevice *device = NULL;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (path != NULL, NULL);
@ -712,10 +649,12 @@ nm_device_new (DBusGConnection *connection, const char *path)
if (dtype == G_TYPE_INVALID)
return NULL;
return g_object_new (dtype,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
device = (NMDevice *) g_object_new (dtype,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
_nm_object_ensure_inited (NM_OBJECT (device));
return G_OBJECT (device);
}
typedef struct {

View file

@ -90,34 +90,25 @@ register_properties (NMDHCP4Config *config)
property_info);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
NMObject *object;
DBusGConnection *connection;
NMDHCP4ConfigPrivate *priv;
object = (NMObject *) G_OBJECT_CLASS (nm_dhcp4_config_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_dhcp4_config_parent_class)->constructed (object);
priv = NM_DHCP4_CONFIG_GET_PRIVATE (object);
priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
connection = nm_object_get_connection (object);
connection = nm_object_get_connection (NM_OBJECT (object));
priv->proxy = dbus_g_proxy_new_for_name (connection,
NM_DBUS_SERVICE,
nm_object_get_path (object),
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE_DHCP4_CONFIG);
register_properties (NM_DHCP4_CONFIG (object));
return G_OBJECT (object);
}
static void
@ -159,7 +150,7 @@ nm_dhcp4_config_class_init (NMDHCP4ConfigClass *config_class)
g_type_class_add_private (config_class, sizeof (NMDHCP4ConfigPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->finalize = finalize;

View file

@ -90,34 +90,25 @@ register_properties (NMDHCP6Config *config)
property_info);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
NMObject *object;
DBusGConnection *connection;
NMDHCP6ConfigPrivate *priv;
object = (NMObject *) G_OBJECT_CLASS (nm_dhcp6_config_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_dhcp6_config_parent_class)->constructed (object);
priv = NM_DHCP6_CONFIG_GET_PRIVATE (object);
priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
connection = nm_object_get_connection (object);
connection = nm_object_get_connection (NM_OBJECT (object));
priv->proxy = dbus_g_proxy_new_for_name (connection,
NM_DBUS_SERVICE,
nm_object_get_path (object),
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE_DHCP6_CONFIG);
register_properties (NM_DHCP6_CONFIG (object));
return G_OBJECT (object);
}
static void
@ -159,7 +150,7 @@ nm_dhcp6_config_class_init (NMDHCP6ConfigClass *config_class)
g_type_class_add_private (config_class, sizeof (NMDHCP6ConfigPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->finalize = finalize;

View file

@ -132,32 +132,23 @@ register_properties (NMIP4Config *config)
property_info);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
NMObject *object;
DBusGConnection *connection;
NMIP4ConfigPrivate *priv;
object = (NMObject *) G_OBJECT_CLASS (nm_ip4_config_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_ip4_config_parent_class)->constructed (object);
priv = NM_IP4_CONFIG_GET_PRIVATE (object);
connection = nm_object_get_connection (object);
connection = nm_object_get_connection (NM_OBJECT (object));
priv->proxy = dbus_g_proxy_new_for_name (connection,
NM_DBUS_SERVICE,
nm_object_get_path (object),
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE_IP4_CONFIG);
register_properties (NM_IP4_CONFIG (object));
return G_OBJECT (object);
}
static void
@ -226,7 +217,7 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class)
g_type_class_add_private (config_class, sizeof (NMIP4ConfigPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->finalize = finalize;

View file

@ -216,20 +216,13 @@ nm_ip6_config_get_routes (NMIP6Config *config)
return NM_IP6_CONFIG_GET_PRIVATE (config)->routes;
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
GObject *object;
DBusGConnection *connection;
NMIP6ConfigPrivate *priv;
object = G_OBJECT_CLASS (nm_ip6_config_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_ip6_config_parent_class)->constructed (object);
priv = NM_IP6_CONFIG_GET_PRIVATE (object);
connection = nm_object_get_connection (NM_OBJECT (object));
@ -240,8 +233,6 @@ constructor (GType type,
NM_DBUS_INTERFACE_IP6_CONFIG);
register_properties (NM_IP6_CONFIG (object));
return object;
}
static void
@ -309,7 +300,7 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class)
g_type_class_add_private (config_class, sizeof (NMIP6ConfigPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->finalize = finalize;

View file

@ -23,8 +23,7 @@
#ifndef NM_OBJECT_PRIVATE_H
#define NM_OBJECT_PRIVATE_H
#include <glib.h>
#include <glib-object.h>
#include <gio/gio.h>
#include "nm-object.h"
void _nm_object_ensure_inited (NMObject *object);
@ -47,7 +46,12 @@ void _nm_object_register_properties (NMObject *object,
gboolean _nm_object_reload_properties (NMObject *object, GError **error);
void _nm_object_process_properties_changed (NMObject *self, GHashTable *properties);
void _nm_object_reload_properties_async (NMObject *object,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean _nm_object_reload_properties_finish (NMObject *object,
GAsyncResult *result,
GError **error);
typedef void (*NMPseudoPropertyChangedFunc) (NMObject *self, NMObject *changed);
void _nm_object_register_pseudo_property (NMObject *object,

View file

@ -34,7 +34,13 @@
#define DEBUG 0
G_DEFINE_ABSTRACT_TYPE (NMObject, nm_object, G_TYPE_OBJECT)
static void nm_object_initable_iface_init (GInitableIface *iface);
static void nm_object_async_initable_iface_init (GAsyncInitableIface *iface);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMObject, nm_object, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_object_initable_iface_init);
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_object_async_initable_iface_init);
)
#define NM_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_OBJECT, NMObjectPrivate))
@ -47,6 +53,8 @@ typedef struct {
gpointer field;
} PropertyInfo;
static void reload_complete (NMObject *object);
typedef struct {
PropertyInfo pi;
@ -70,6 +78,10 @@ typedef struct {
GSList *notify_props;
guint32 notify_id;
gboolean inited, disposed;
GSList *reload_results;
guint reload_remaining;
GError *reload_error;
} NMObjectPrivate;
enum {
@ -96,8 +108,6 @@ constructor (GType type,
object = G_OBJECT_CLASS (nm_object_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
priv = NM_OBJECT_GET_PRIVATE (object);
@ -107,16 +117,77 @@ constructor (GType type,
return NULL;
}
priv->properties_proxy = dbus_g_proxy_new_for_name (priv->connection,
NM_DBUS_SERVICE,
priv->path,
"org.freedesktop.DBus.Properties");
_nm_object_cache_add (NM_OBJECT (object));
return object;
}
static void
constructed (GObject *object)
{
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
if (G_OBJECT_CLASS (nm_object_parent_class)->constructed)
G_OBJECT_CLASS (nm_object_parent_class)->constructed (object);
priv->properties_proxy = dbus_g_proxy_new_for_name (priv->connection,
NM_DBUS_SERVICE,
priv->path,
"org.freedesktop.DBus.Properties");
}
static gboolean
init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
{
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (initable);
priv->inited = TRUE;
return _nm_object_reload_properties (NM_OBJECT (initable), error);
}
static void
init_async_got_properties (GObject *object, GAsyncResult *result, gpointer user_data)
{
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
GSimpleAsyncResult *simple = user_data;
GError *error = NULL;
priv->inited = TRUE;
if (_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error))
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
else
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
init_async (GAsyncInitable *initable, int io_priority,
GCancellable *cancellable, GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *simple;
simple = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async);
_nm_object_reload_properties_async (NM_OBJECT (initable), init_async_got_properties, simple);
}
static gboolean
init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error)
{
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
/* This is needed for now because of bug 667375; it can go away
* when we depend on glib >= 2.38
*/
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
else
return g_simple_async_result_get_op_res_gboolean (simple);
}
static void
dispose (GObject *object)
{
@ -219,6 +290,7 @@ nm_object_class_init (NMObjectClass *nm_object_class)
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->dispose = dispose;
@ -253,6 +325,19 @@ nm_object_class_init (NMObjectClass *nm_object_class)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
static void
nm_object_initable_iface_init (GInitableIface *iface)
{
iface->init = init_sync;
}
static void
nm_object_async_initable_iface_init (GAsyncInitableIface *iface)
{
iface->init_async = init_async;
iface->init_finish = init_finish;
}
/**
* nm_object_get_connection:
* @object: a #NMObject
@ -352,15 +437,25 @@ static GObject *
_nm_object_create (GType type, DBusGConnection *connection, const char *path)
{
NMObjectTypeFunc type_func;
GObject *object;
GError *error = NULL;
type_func = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type));
if (type_func)
type = type_func (connection, path);
return g_object_new (type,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
object = g_object_new (type,
NM_OBJECT_DBUS_CONNECTION, connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
if (!g_initable_init (G_INITABLE (object), NULL, &error)) {
g_object_unref (object);
object = NULL;
g_warning ("Could not create object for %s: %s", path, error->message);
g_error_free (error);
}
return object;
}
typedef void (*NMObjectCreateCallbackFunc) (GObject *, gpointer);
@ -371,6 +466,33 @@ typedef struct {
gpointer user_data;
} NMObjectTypeAsyncData;
static void
create_async_complete (GObject *object, NMObjectTypeAsyncData *async_data)
{
async_data->callback (object, async_data->user_data);
g_free (async_data->path);
g_slice_free (NMObjectTypeAsyncData, async_data);
}
static void
async_inited (GObject *source, GAsyncResult *result, gpointer user_data)
{
NMObjectTypeAsyncData *async_data = user_data;
GObject *object = G_OBJECT (source);
GError *error = NULL;
if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error)) {
g_warning ("Could not create object for %s: %s",
nm_object_get_path (NM_OBJECT (object)), error->message);
g_error_free (error);
g_object_unref (object);
object = NULL;
}
create_async_complete (object, async_data);
}
static void
async_got_type (GType type, gpointer user_data)
{
@ -382,13 +504,13 @@ async_got_type (GType type, gpointer user_data)
NM_OBJECT_DBUS_CONNECTION, async_data->connection,
NM_OBJECT_DBUS_PATH, async_data->path,
NULL);
} else
object = NULL;
} else {
create_async_complete (NULL, async_data);
return;
}
async_data->callback (object, async_data->user_data);
g_free (async_data->path);
g_slice_free (NMObjectTypeAsyncData, async_data);
g_async_initable_init_async (G_ASYNC_INITABLE (object), G_PRIORITY_DEFAULT,
NULL, async_inited, async_data);
}
static void
@ -396,6 +518,7 @@ _nm_object_create_async (GType type, DBusGConnection *connection, const char *pa
NMObjectCreateCallbackFunc callback, gpointer user_data)
{
NMObjectTypeAsyncFunc type_async_func;
NMObjectTypeFunc type_func;
NMObjectTypeAsyncData *async_data;
async_data = g_slice_new (NMObjectTypeAsyncData);
@ -405,10 +528,16 @@ _nm_object_create_async (GType type, DBusGConnection *connection, const char *pa
async_data->user_data = user_data;
type_async_func = g_hash_table_lookup (type_async_funcs, GSIZE_TO_POINTER (type));
if (type_async_func)
if (type_async_func) {
type_async_func (connection, path, async_got_type, async_data);
else
async_got_type (type, async_data);
return;
}
type_func = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type));
if (type_func)
type = type_func (connection, path);
async_got_type (type, async_data);
}
/* Stolen from dbus-glib */
@ -449,6 +578,7 @@ object_created (GObject *obj, gpointer user_data)
{
ObjectCreatedData *odata = user_data;
NMObject *self = odata->self;
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
PropertyInfo *pi = odata->pi;
/* We assume that on error, the creator_func printed something */
@ -478,6 +608,9 @@ object_created (GObject *obj, gpointer user_data)
if (odata->property_name)
_nm_object_queue_notify (self, odata->property_name);
if (priv->reload_results && --priv->reload_remaining == 0)
reload_complete (self);
g_object_unref (self);
g_free (odata->objects);
g_slice_free (ObjectCreatedData, odata);
@ -514,12 +647,14 @@ handle_object_property (NMObject *self, const char *property_name, GValue *value
obj = _nm_object_create (pi->object_type, priv->connection, path);
object_created (obj, odata);
return obj != NULL;
} else {
_nm_object_create_async (pi->object_type, priv->connection, path,
object_created, odata);
/* Assume success */
return TRUE;
}
if (priv->reload_results)
priv->reload_remaining++;
_nm_object_create_async (pi->object_type, priv->connection, path,
object_created, odata);
/* Assume success */
return TRUE;
}
static gboolean
@ -532,6 +667,7 @@ handle_object_array_property (NMObject *self, const char *property_name, GValue
GPtrArray **array = pi->field;
const char *path;
ObjectCreatedData *odata;
gboolean add_to_reload = (priv->reload_results != NULL);
int i;
paths = g_value_get_boxed (value);
@ -554,13 +690,19 @@ handle_object_array_property (NMObject *self, const char *property_name, GValue
obj = G_OBJECT (_nm_object_cache_get (path));
if (obj) {
object_created (obj, odata);
continue;
} else if (synchronously) {
obj = _nm_object_create (pi->object_type, priv->connection, path);
object_created (obj, odata);
} else {
_nm_object_create_async (pi->object_type, priv->connection, path,
object_created, odata);
continue;
}
if (add_to_reload) {
priv->reload_remaining++;
add_to_reload = FALSE;
}
_nm_object_create_async (pi->object_type, priv->connection, path,
object_created, odata);
}
if (!synchronously) {
@ -636,8 +778,8 @@ out:
g_free (prop_name);
}
void
_nm_object_process_properties_changed (NMObject *self, GHashTable *properties)
static void
process_properties_changed (NMObject *self, GHashTable *properties)
{
GHashTableIter iter;
gpointer name, value;
@ -652,7 +794,7 @@ properties_changed_proxy (DBusGProxy *proxy,
GHashTable *properties,
gpointer user_data)
{
_nm_object_process_properties_changed (NM_OBJECT (user_data), properties);
process_properties_changed (NM_OBJECT (user_data), properties);
}
#define HANDLE_TYPE(ucase, lcase, getter) \
@ -773,8 +915,6 @@ _nm_object_reload_properties (NMObject *object, GError **error)
if (!priv->property_interfaces)
return TRUE;
priv->inited = TRUE;
for (p = priv->property_interfaces; p; p = p->next) {
if (!dbus_g_proxy_call (priv->properties_proxy, "GetAll", error,
G_TYPE_STRING, p->data,
@ -783,7 +923,7 @@ _nm_object_reload_properties (NMObject *object, GError **error)
G_TYPE_INVALID))
return FALSE;
_nm_object_process_properties_changed (object, props);
process_properties_changed (object, props);
g_hash_table_destroy (props);
}
@ -803,11 +943,14 @@ _nm_object_ensure_inited (NMObject *object)
GError *error = NULL;
if (!priv->inited) {
if (!_nm_object_reload_properties (object, &error)) {
if (!g_initable_init (G_INITABLE (object), NULL, &error)) {
g_warning ("Could not initialize %s %s: %s",
G_OBJECT_TYPE_NAME (object), priv->path,
error->message);
g_error_free (error);
/* Only warn once */
priv->inited = TRUE;
}
}
}
@ -1026,3 +1169,148 @@ _nm_object_reload_pseudo_property (NMObject *object,
handle_object_array_property (object, NULL, &value, &ppi->pi, TRUE);
g_value_unset (&value);
}
static void
reload_complete (NMObject *object)
{
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
GSimpleAsyncResult *simple;
GSList *results, *iter;
GError *error;
results = priv->reload_results;
priv->reload_results = NULL;
error = priv->reload_error;
priv->reload_error = NULL;
for (iter = results; iter; iter = iter->next) {
simple = results->data;
if (error)
g_simple_async_result_set_from_error (simple, error);
else
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
g_slist_free (results);
g_clear_error (&error);
}
static void
reload_got_properties (DBusGProxy *proxy, DBusGProxyCall *call,
gpointer user_data)
{
NMObject *object = user_data;
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
GHashTable *props = NULL;
GError *error = NULL;
if (dbus_g_proxy_end_call (proxy, call, &error,
DBUS_TYPE_G_MAP_OF_VARIANT, &props,
G_TYPE_INVALID)) {
process_properties_changed (object, props);
g_hash_table_destroy (props);
} else {
if (priv->reload_error)
g_error_free (error);
else
priv->reload_error = error;
}
if (--priv->reload_remaining == 0)
reload_complete (object);
}
static void
reload_got_pseudo_property (DBusGProxy *proxy, DBusGProxyCall *call,
gpointer user_data)
{
PseudoPropertyInfo *ppi = user_data;
NMObject *object = ppi->self;
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
GPtrArray *temp;
GValue value = { 0, };
GError *error = NULL;
if (dbus_g_proxy_end_call (proxy, call, &error,
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &temp,
G_TYPE_INVALID)) {
g_value_init (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH);
g_value_take_boxed (&value, temp);
handle_object_array_property (object, NULL, &value, &ppi->pi, FALSE);
g_value_unset (&value);
} else {
if (priv->reload_error)
g_error_free (error);
else
priv->reload_error = error;
}
if (--priv->reload_remaining == 0)
reload_complete (object);
}
void
_nm_object_reload_properties_async (NMObject *object, GAsyncReadyCallback callback, gpointer user_data)
{
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
GSimpleAsyncResult *simple;
GSList *p;
simple = g_simple_async_result_new (G_OBJECT (object), callback,
user_data, _nm_object_reload_properties_async);
if (!priv->property_interfaces && !priv->pseudo_properties) {
g_simple_async_result_complete_in_idle (simple);
return;
}
priv->reload_results = g_slist_prepend (priv->reload_results, simple);
/* If there was already a reload happening, we don't need to
* re-read the properties again, we just need to wait for the
* existing reload to finish.
*/
if (priv->reload_results->next)
return;
for (p = priv->property_interfaces; p; p = p->next) {
priv->reload_remaining++;
dbus_g_proxy_begin_call (priv->properties_proxy, "GetAll",
reload_got_properties, object, NULL,
G_TYPE_STRING, p->data,
G_TYPE_INVALID);
}
if (priv->pseudo_properties) {
GHashTableIter iter;
gpointer key, value;
PseudoPropertyInfo *ppi;
g_hash_table_iter_init (&iter, priv->pseudo_properties);
while (g_hash_table_iter_next (&iter, &key, &value)) {
ppi = value;
priv->reload_remaining++;
dbus_g_proxy_begin_call (ppi->proxy, ppi->get_method,
reload_got_pseudo_property, ppi, NULL,
G_TYPE_INVALID);
}
}
}
gboolean
_nm_object_reload_properties_finish (NMObject *object, GAsyncResult *result, GError **error)
{
GSimpleAsyncResult *simple;
g_return_val_if_fail (NM_IS_OBJECT (object), FALSE);
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (object), _nm_object_reload_properties_async), FALSE);
simple = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
return g_simple_async_result_get_op_res_gboolean (simple);
}

View file

@ -382,18 +382,11 @@ nm_remote_connection_new (DBusGConnection *bus,
NULL);
}
static GObject *
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
GObject *object;
NMRemoteConnectionPrivate *priv;
object = G_OBJECT_CLASS (nm_remote_connection_parent_class)->constructor (type, n_construct_params, construct_params);
if (!object)
return NULL;
priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object);
g_assert (priv->bus);
g_assert (nm_connection_get_path (NM_CONNECTION (object)));
@ -414,7 +407,6 @@ constructor (GType type,
dbus_g_proxy_begin_call (priv->proxy, "GetSettings",
init_get_settings_cb, object, NULL,
G_TYPE_INVALID);
return object;
}
static void
@ -486,7 +478,7 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class)
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->constructor = constructor;
object_class->constructed = constructed;
/* Properties */
g_object_class_install_property

View file

@ -754,19 +754,12 @@ nm_remote_settings_init (NMRemoteSettings *self)
priv->pending = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
}
static GObject *
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
GObject *object;
NMRemoteSettingsPrivate *priv;
GError *error = NULL;
object = G_OBJECT_CLASS (nm_remote_settings_parent_class)->constructor (type, n_construct_params, construct_params);
if (!object)
return NULL;
priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object);
/* D-Bus proxy for clearing connections on NameOwnerChanged */
@ -847,7 +840,6 @@ constructor (GType type,
G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS,
G_TYPE_INVALID);
return object;
}
static void
@ -937,7 +929,7 @@ nm_remote_settings_class_init (NMRemoteSettingsClass *class)
g_type_class_add_private (class, sizeof (NMRemoteSettingsPrivate));
/* Virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->dispose = dispose;

View file

@ -164,25 +164,18 @@ register_properties (NMVPNConnection *connection)
property_info);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
NMObject *object;
NMVPNConnectionPrivate *priv;
object = (NMObject *) G_OBJECT_CLASS (nm_vpn_connection_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->constructed (object);
priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object),
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
NM_DBUS_SERVICE,
nm_object_get_path (object),
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE_VPN_CONNECTION);
dbus_g_object_register_marshaller (_nm_marshal_VOID__UINT_UINT,
@ -197,8 +190,6 @@ constructor (GType type,
NULL);
register_properties (NM_VPN_CONNECTION (object));
return G_OBJECT (object);
}
static void
@ -241,7 +232,7 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->finalize = finalize;

View file

@ -279,30 +279,21 @@ register_properties (NMWimaxNsp *nsp)
property_info);
}
static GObject*
constructor (GType type,
guint n_construct_params,
GObjectConstructParam *construct_params)
static void
constructed (GObject *object)
{
NMObject *object;
NMWimaxNspPrivate *priv;
object = (NMObject *) G_OBJECT_CLASS (nm_wimax_nsp_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
G_OBJECT_CLASS (nm_wimax_nsp_parent_class)->constructed (object);
priv = NM_WIMAX_NSP_GET_PRIVATE (object);
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object),
priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
NM_DBUS_SERVICE,
nm_object_get_path (object),
nm_object_get_path (NM_OBJECT (object)),
NM_DBUS_INTERFACE_WIMAX_NSP);
register_properties (NM_WIMAX_NSP (object));
return G_OBJECT (object);
}
@ -314,7 +305,7 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class)
g_type_class_add_private (nsp_class, sizeof (NMWimaxNspPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;