2007-09-14 Dan Williams <dcbw@redhat.com>
Implement deferred activation handling in the NMActRequest class. When a client wants to activate a device but must create the NMConnection details on the fly, there likely hasn't been enough time yet for NM to receive the new connection signal and grab all the connection details. So the activation is deferred (and bounded by a timer) for a while, and if the connection appears within the window, it is activated. * src/nm-activation-request.c src/nm-activation-request.h - (nm_act_request_class_init): two new signals to support deferred activation, to allow the listener to handle both timeout and success - (nm_act_request_new_deferred): new function, starts the deferred activation timeout handler and listens to the NMManager for new-connection signals to notice when the connection comes in git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2811 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
@@ -22,6 +22,8 @@
|
||||
|
||||
#include "nm-activation-request.h"
|
||||
#include "nm-marshal.h"
|
||||
#include "nm-manager.h"
|
||||
#include "nm-utils.h"
|
||||
|
||||
G_DEFINE_TYPE (NMActRequest, nm_act_request, G_TYPE_OBJECT)
|
||||
|
||||
@@ -29,6 +31,8 @@ G_DEFINE_TYPE (NMActRequest, nm_act_request, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
CONNECTION_SECRETS_UPDATED,
|
||||
DEFERRED_ACTIVATION_TIMEOUT,
|
||||
DEFERRED_ACTIVATION_START,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@@ -41,6 +45,11 @@ static void connection_secrets_updated_cb (NMConnection *connection,
|
||||
NMActRequest *self);
|
||||
|
||||
typedef struct {
|
||||
char *deferred_service_name;
|
||||
char *deferred_connection_path;
|
||||
gulong deferred_connection_id;
|
||||
guint32 deferred_timeout_id;
|
||||
|
||||
NMConnection *connection;
|
||||
char *specific_object;
|
||||
gboolean user_requested;
|
||||
@@ -53,15 +62,53 @@ nm_act_request_init (NMActRequest *req)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clear_deferred_stuff (NMActRequest *req)
|
||||
{
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
|
||||
|
||||
g_free (priv->deferred_service_name);
|
||||
priv->deferred_service_name = NULL;
|
||||
g_free (priv->deferred_connection_path);
|
||||
priv->deferred_connection_path = NULL;
|
||||
|
||||
if (priv->deferred_connection_id) {
|
||||
NMManager *manager = nm_manager_get ();
|
||||
g_signal_handler_disconnect (manager, priv->deferred_connection_id);
|
||||
g_object_unref (manager);
|
||||
priv->deferred_connection_id = 0;
|
||||
}
|
||||
|
||||
if (priv->deferred_timeout_id) {
|
||||
g_source_remove (priv->deferred_timeout_id);
|
||||
priv->deferred_timeout_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
|
||||
|
||||
clear_deferred_stuff (NM_ACT_REQUEST (object));
|
||||
|
||||
if (priv->secrets_updated_id) {
|
||||
g_signal_handler_disconnect (priv->connection,
|
||||
priv->secrets_updated_id);
|
||||
priv->secrets_updated_id = 0;
|
||||
}
|
||||
|
||||
if (priv->connection)
|
||||
g_object_unref (priv->connection);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
|
||||
|
||||
g_signal_handler_disconnect (priv->connection,
|
||||
priv->secrets_updated_id);
|
||||
g_object_unref (priv->connection);
|
||||
|
||||
g_free (priv->deferred_service_name);
|
||||
g_free (priv->deferred_connection_path);
|
||||
g_free (priv->specific_object);
|
||||
|
||||
G_OBJECT_CLASS (nm_act_request_parent_class)->finalize (object);
|
||||
@@ -74,6 +121,7 @@ nm_act_request_class_init (NMActRequestClass *req_class)
|
||||
|
||||
g_type_class_add_private (req_class, sizeof (NMActRequestPrivate));
|
||||
|
||||
object_class->dispose = dispose;
|
||||
object_class->finalize = finalize;
|
||||
|
||||
/* Signals */
|
||||
@@ -81,11 +129,31 @@ nm_act_request_class_init (NMActRequestClass *req_class)
|
||||
g_signal_new ("connection-secrets-updated",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMConnectionClass, secrets_updated),
|
||||
G_STRUCT_OFFSET (NMActRequestClass, connection_secrets_updated),
|
||||
NULL, NULL,
|
||||
nm_marshal_VOID__OBJECT_STRING,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_OBJECT, G_TYPE_STRING);
|
||||
|
||||
signals[DEFERRED_ACTIVATION_TIMEOUT] =
|
||||
g_signal_new ("deferred-activation-timeout",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMActRequestClass, deferred_activation_timeout),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0,
|
||||
G_TYPE_NONE);
|
||||
|
||||
signals[DEFERRED_ACTIVATION_START] =
|
||||
g_signal_new ("deferred-activation-start",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMActRequestClass, deferred_activation_start),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0,
|
||||
G_TYPE_NONE);
|
||||
}
|
||||
|
||||
NMActRequest *
|
||||
@@ -97,7 +165,7 @@ nm_act_request_new (NMConnection *connection,
|
||||
NMActRequestPrivate *priv;
|
||||
gulong id;
|
||||
|
||||
g_return_val_if_fail (connection != NULL, NULL);
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
||||
|
||||
obj = g_object_new (NM_TYPE_ACT_REQUEST, NULL);
|
||||
if (!obj)
|
||||
@@ -119,6 +187,101 @@ nm_act_request_new (NMConnection *connection,
|
||||
return NM_ACT_REQUEST (obj);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
deferred_timeout_cb (gpointer data)
|
||||
{
|
||||
NMActRequest *self = NM_ACT_REQUEST (data);
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
|
||||
|
||||
priv->deferred_timeout_id = 0;
|
||||
clear_deferred_stuff (self);
|
||||
|
||||
g_signal_emit (self, signals[DEFERRED_ACTIVATION_TIMEOUT], 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
connection_added_cb (NMManager *manager,
|
||||
NMConnection *connection,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMActRequest *self;
|
||||
NMActRequestPrivate *priv;
|
||||
const char *service_name;
|
||||
const char *path;
|
||||
gulong id;
|
||||
|
||||
g_return_if_fail (NM_IS_ACT_REQUEST (user_data));
|
||||
g_return_if_fail (NM_IS_CONNECTION (connection));
|
||||
g_return_if_fail (NM_IS_MANAGER (manager));
|
||||
|
||||
self = NM_ACT_REQUEST (user_data);
|
||||
|
||||
service_name = nm_manager_get_connection_service_name (manager, connection);
|
||||
path = nm_manager_get_connection_dbus_path (manager, connection);
|
||||
if (!service_name || !path) {
|
||||
nm_warning ("Couldn't get connection service name or path (%s, %s)",
|
||||
service_name, path);
|
||||
return;
|
||||
}
|
||||
|
||||
priv = NM_ACT_REQUEST_GET_PRIVATE (self);
|
||||
if ( strcmp (service_name, priv->deferred_service_name)
|
||||
|| strcmp (path, priv->deferred_connection_path))
|
||||
return;
|
||||
|
||||
clear_deferred_stuff (self);
|
||||
|
||||
priv->connection = g_object_ref (connection);
|
||||
id = g_signal_connect (priv->connection,
|
||||
"secrets-updated",
|
||||
G_CALLBACK (connection_secrets_updated_cb),
|
||||
self);
|
||||
priv->secrets_updated_id = id;
|
||||
|
||||
g_signal_emit (self, signals[DEFERRED_ACTIVATION_START], 0);
|
||||
}
|
||||
|
||||
NMActRequest *
|
||||
nm_act_request_new_deferred (const char *service_name,
|
||||
const char *connection_path,
|
||||
const char *specific_object,
|
||||
gboolean user_requested)
|
||||
{
|
||||
GObject *obj;
|
||||
NMManager *manager;
|
||||
NMActRequestPrivate *priv;
|
||||
gulong id;
|
||||
|
||||
g_return_val_if_fail (service_name != NULL, NULL);
|
||||
g_return_val_if_fail (connection_path != NULL, NULL);
|
||||
|
||||
obj = g_object_new (NM_TYPE_ACT_REQUEST, NULL);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
priv = NM_ACT_REQUEST_GET_PRIVATE (obj);
|
||||
|
||||
priv->deferred_service_name = g_strdup (service_name);
|
||||
priv->deferred_connection_path = g_strdup (connection_path);
|
||||
priv->user_requested = user_requested;
|
||||
if (specific_object)
|
||||
priv->specific_object = g_strdup (specific_object);
|
||||
|
||||
id = g_timeout_add (5000, deferred_timeout_cb, NM_ACT_REQUEST (obj));
|
||||
priv->deferred_timeout_id = id;
|
||||
|
||||
manager = nm_manager_get ();
|
||||
id = g_signal_connect (manager,
|
||||
"connection-added",
|
||||
G_CALLBACK (connection_added_cb),
|
||||
NM_ACT_REQUEST (obj));
|
||||
priv->deferred_connection_id = id;
|
||||
g_object_unref (manager);
|
||||
|
||||
return NM_ACT_REQUEST (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
connection_secrets_updated_cb (NMConnection *connection,
|
||||
const char *setting_name,
|
||||
|
Reference in New Issue
Block a user