libnm-glib: ensure bindings-created objects work as expected (rh #802536)

Bindings (like GObject Introspection) almost always create objects
using g_object_new() by default and don't use our helper functions
like nm_client_new().  Thus we need to make sure that if the
object is created in that way, any property accesses or functions
that return properties ensure that the object is fully initialized,
which is what the _new() functions were supposed to do.  In one
case in NMClient that was missing (getting active connections)
and wasn't happening at all in NMRemoteSettings, which are our two
entry points into libnm-glib.

This allows this python+GI sequence to return the expected active
connection list:

from gi.repository import NMClient
nmclient = NMClient.Client(dbus_path='/org/freedesktop/NetworkManager')
active = nmclient.get_active_connections()
print(active)

where previously it returned an empty list because the NMClient
wasn't fully initialized by the time nm_client_get_active_connections()
was called.
This commit is contained in:
Dan Williams 2012-03-21 12:37:39 -05:00
parent 43f449824a
commit 762df85234
2 changed files with 66 additions and 42 deletions

View file

@ -18,7 +18,7 @@
* Boston, MA 02110-1301 USA.
*
* Copyright (C) 2007 - 2008 Novell, Inc.
* Copyright (C) 2007 - 2011 Red Hat, Inc.
* Copyright (C) 2007 - 2012 Red Hat, Inc.
*/
#include <dbus/dbus-glib.h>
@ -347,6 +347,7 @@ nm_client_get_devices (NMClient *client)
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
_nm_object_ensure_inited (NM_OBJECT (client));
return handle_ptr_array_return (NM_CLIENT_GET_PRIVATE (client)->devices);
}
@ -701,11 +702,12 @@ nm_client_get_active_connections (NMClient *client)
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
_nm_object_ensure_inited (NM_OBJECT (client));
priv = NM_CLIENT_GET_PRIVATE (client);
if (!priv->manager_running)
return NULL;
_nm_object_ensure_inited (NM_OBJECT (client));
return handle_ptr_array_return (priv->active_connections);
}
@ -897,11 +899,9 @@ nm_client_get_version (NMClient *client)
priv = NM_CLIENT_GET_PRIVATE (client);
if (!priv->manager_running)
return NULL;
_nm_object_ensure_inited (NM_OBJECT (client));
return priv->version;
return priv->manager_running ? priv->version : NULL;
}
/**
@ -915,17 +915,11 @@ nm_client_get_version (NMClient *client)
NMState
nm_client_get_state (NMClient *client)
{
NMClientPrivate *priv;
g_return_val_if_fail (NM_IS_CLIENT (client), NM_STATE_UNKNOWN);
priv = NM_CLIENT_GET_PRIVATE (client);
if (!priv->manager_running)
return NM_STATE_UNKNOWN;
_nm_object_ensure_inited (NM_OBJECT (client));
return priv->state;
return NM_CLIENT_GET_PRIVATE (client)->state;
}
/**
@ -1102,6 +1096,8 @@ proxy_name_owner_changed (DBusGProxy *proxy,
priv->wwan_hw_enabled = FALSE;
priv->wimax_enabled = FALSE;
priv->wimax_hw_enabled = FALSE;
g_free (priv->version);
priv->version = NULL;
} else {
_nm_object_suppress_property_updates (NM_OBJECT (client), FALSE);
_nm_object_reload_properties_async (NM_OBJECT (client), updated_properties, client);

View file

@ -18,7 +18,7 @@
* Boston, MA 02110-1301 USA.
*
* Copyright (C) 2008 Novell, Inc.
* Copyright (C) 2009 - 2011 Red Hat, Inc.
* Copyright (C) 2009 - 2012 Red Hat, Inc.
*/
#include <string.h>
@ -43,6 +43,7 @@ G_DEFINE_TYPE_WITH_CODE (NMRemoteSettings, nm_remote_settings, G_TYPE_OBJECT,
typedef struct {
DBusGConnection *bus;
gboolean inited;
DBusGProxy *proxy;
GHashTable *connections;
@ -104,6 +105,29 @@ nm_remote_settings_error_quark (void)
/**********************************************************************/
static void
_nm_remote_settings_ensure_inited (NMRemoteSettings *self)
{
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
GError *error;
if (!priv->inited) {
if (!g_initable_init (G_INITABLE (self), NULL, &error)) {
/* Don't warn when the call times out because the settings service can't
* be activated or whatever.
*/
if (!g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NO_REPLY)) {
g_warning ("%s: (NMRemoteSettings) error initializing: %s\n",
__func__, error->message);
}
g_error_free (error);
}
priv->inited = TRUE;
}
}
/**********************************************************************/
typedef struct {
NMRemoteSettings *self;
NMRemoteSettingsAddConnectionFunc callback;
@ -161,11 +185,17 @@ add_connection_info_complete (NMRemoteSettings *self,
NMRemoteConnection *
nm_remote_settings_get_connection_by_path (NMRemoteSettings *settings, const char *path)
{
NMRemoteSettingsPrivate *priv;
g_return_val_if_fail (settings != NULL, NULL);
g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL);
g_return_val_if_fail (path != NULL, NULL);
return g_hash_table_lookup (NM_REMOTE_SETTINGS_GET_PRIVATE (settings)->connections, path);
priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
_nm_remote_settings_ensure_inited (settings);
return priv->service_running ? g_hash_table_lookup (priv->connections, path) : NULL;
}
/**
@ -181,6 +211,7 @@ nm_remote_settings_get_connection_by_path (NMRemoteSettings *settings, const cha
NMRemoteConnection *
nm_remote_settings_get_connection_by_uuid (NMRemoteSettings *settings, const char *uuid)
{
NMRemoteSettingsPrivate *priv;
GHashTableIter iter;
NMRemoteConnection *candidate;
@ -188,10 +219,16 @@ nm_remote_settings_get_connection_by_uuid (NMRemoteSettings *settings, const cha
g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL);
g_return_val_if_fail (uuid != NULL, NULL);
g_hash_table_iter_init (&iter, NM_REMOTE_SETTINGS_GET_PRIVATE (settings)->connections);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) {
if (g_strcmp0 (uuid, nm_connection_get_uuid (NM_CONNECTION (candidate))) == 0)
return candidate;
priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
_nm_remote_settings_ensure_inited (settings);
if (priv->service_running) {
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) {
if (g_strcmp0 (uuid, nm_connection_get_uuid (NM_CONNECTION (candidate))) == 0)
return candidate;
}
}
return NULL;
@ -440,9 +477,13 @@ nm_remote_settings_list_connections (NMRemoteSettings *settings)
priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, &value))
list = g_slist_prepend (list, NM_REMOTE_CONNECTION (value));
_nm_remote_settings_ensure_inited (settings);
if (priv->service_running) {
g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, NULL, &value))
list = g_slist_prepend (list, NM_REMOTE_CONNECTION (value));
}
return list;
}
@ -495,7 +536,9 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings,
g_return_val_if_fail (callback != NULL, FALSE);
priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
_nm_remote_settings_ensure_inited (settings);
info = g_malloc0 (sizeof (AddConnectionInfo));
info->self = settings;
info->callback = callback;
@ -599,6 +642,8 @@ nm_remote_settings_save_hostname (NMRemoteSettings *settings,
priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
_nm_remote_settings_ensure_inited (settings);
info = g_malloc0 (sizeof (SaveHostnameInfo));
info->settings = settings;
info->callback = callback;
@ -683,24 +728,7 @@ properties_changed_cb (DBusGProxy *proxy,
NMRemoteSettings *
nm_remote_settings_new (DBusGConnection *bus)
{
NMRemoteSettings *settings;
GError *error = NULL;
settings = g_object_new (NM_TYPE_REMOTE_SETTINGS,
NM_REMOTE_SETTINGS_BUS, bus,
NULL);
if (!g_initable_init (G_INITABLE (settings), NULL, &error)) {
/* Don't warn when the call times out because the settings service can't
* be activated or whatever.
*/
if (!g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NO_REPLY)) {
g_warning ("%s: (NMRemoteSettings) error initializing: %s\n",
__func__, error->message);
}
g_error_free (error);
}
return settings;
return g_object_new (NM_TYPE_REMOTE_SETTINGS, NM_REMOTE_SETTINGS_BUS, bus, NULL);
}
static void