summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-01-15 15:23:39 +0100
committerThomas Haller <thaller@redhat.com>2018-01-16 14:39:09 +0100
commite428252935693869d5a61b03c0c8e2e688fde9f2 (patch)
treeeb6cfe571b9f8dbc8dd46005bbd455f53b2a7f44
parente89e5edcf80906a45b63793ed3fe262e41c07a75 (diff)
downloadNetworkManager-e428252935693869d5a61b03c0c8e2e688fde9f2.tar.gz
libnm: add nm_vpn_service_plugin_shutdown() API
Otherwise, the only way to disconnect the NMVpnServicePlugin instance is by completely unrefing it. However, often it is not so easy to ensure that nobody else is still keeping the instance alive, after the point where we no longer want to handle D-Bus requests. nm_vpn_service_plugin_shutdown() to the rescue.
-rw-r--r--libnm/libnm.ver1
-rw-r--r--libnm/nm-vpn-service-plugin.c94
-rw-r--r--libnm/nm-vpn-service-plugin.h3
3 files changed, 65 insertions, 33 deletions
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 29dfba7b58..992070ba83 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1352,4 +1352,5 @@ global:
nm_setting_ip_tunnel_get_flags;
nm_setting_vpn_get_data_keys;
nm_setting_vpn_get_secret_keys;
+ nm_vpn_service_plugin_shutdown;
} libnm_1_10_0;
diff --git a/libnm/nm-vpn-service-plugin.c b/libnm/nm-vpn-service-plugin.c
index d36fb43bfb..055b1f0e15 100644
--- a/libnm/nm-vpn-service-plugin.c
+++ b/libnm/nm-vpn-service-plugin.c
@@ -151,7 +151,8 @@ nm_vpn_service_plugin_set_state (NMVpnServicePlugin *plugin,
if (priv->state != state) {
priv->state = state;
g_signal_emit (plugin, signals[STATE_CHANGED], 0, state);
- nmdbus_vpn_plugin_emit_state_changed (priv->dbus_vpn_service_plugin, state);
+ if (priv->dbus_vpn_service_plugin)
+ nmdbus_vpn_plugin_emit_state_changed (priv->dbus_vpn_service_plugin, state);
}
}
@@ -166,7 +167,8 @@ nm_vpn_service_plugin_set_login_banner (NMVpnServicePlugin *plugin,
priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin);
g_signal_emit (plugin, signals[LOGIN_BANNER], 0, banner);
- nmdbus_vpn_plugin_emit_login_banner (priv->dbus_vpn_service_plugin, banner);
+ if (priv->dbus_vpn_service_plugin)
+ nmdbus_vpn_plugin_emit_login_banner (priv->dbus_vpn_service_plugin, banner);
}
static void
@@ -176,7 +178,8 @@ _emit_failure (NMVpnServicePlugin *plugin,
NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin);
g_signal_emit (plugin, signals[FAILURE], 0, reason);
- nmdbus_vpn_plugin_emit_failure (priv->dbus_vpn_service_plugin, reason);
+ if (priv->dbus_vpn_service_plugin)
+ nmdbus_vpn_plugin_emit_failure (priv->dbus_vpn_service_plugin, reason);
}
void
@@ -241,6 +244,51 @@ nm_vpn_service_plugin_emit_quit (NMVpnServicePlugin *plugin)
g_signal_emit (plugin, signals[QUIT], 0);
}
+/**
+ * nm_vpn_service_plugin_shutdown:
+ * @plugin: the #NMVpnServicePlugin instance
+ *
+ * Shutdown the @plugin and disconnect from D-Bus. After this,
+ * the plugin instance is dead and should no longer be used.
+ * It ensures to get no more requests from D-Bus. In principle,
+ * you don't need to shutdown the plugin, disposing the instance
+ * has the same effect. However, this gives a way to deactivate
+ * the plugin before giving up the last reference.
+ *
+ * Since: 1.12
+ */
+void
+nm_vpn_service_plugin_shutdown (NMVpnServicePlugin *plugin)
+{
+ NMVpnServicePluginPrivate *priv;
+ NMVpnServiceState state;
+ GError *error = NULL;
+
+ g_return_if_fail (NM_IS_VPN_SERVICE_PLUGIN (plugin));
+
+ priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin);
+
+ nm_clear_g_source (&priv->fail_stop_id);
+ nm_clear_g_source (&priv->quit_timer);
+ nm_clear_g_source (&priv->connect_timer);
+
+ state = nm_vpn_service_plugin_get_state (plugin);
+ if (state == NM_VPN_SERVICE_STATE_STARTED ||
+ state == NM_VPN_SERVICE_STATE_STARTING) {
+ nm_vpn_service_plugin_disconnect (plugin, &error);
+
+ if (error) {
+ g_warning ("Error disconnecting VPN connection: %s", error->message);
+ g_error_free (error);
+ }
+ }
+
+ if (priv->dbus_vpn_service_plugin) {
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (priv->dbus_vpn_service_plugin));
+ g_clear_object (&priv->dbus_vpn_service_plugin);
+ }
+}
+
static gboolean
connect_timer_expired (gpointer data)
{
@@ -336,7 +384,8 @@ nm_vpn_service_plugin_set_config (NMVpnServicePlugin *plugin,
G_VARIANT_TYPE ("u"));
g_signal_emit (plugin, signals[CONFIG], 0, config);
- nmdbus_vpn_plugin_emit_config (priv->dbus_vpn_service_plugin, config);
+ if (priv->dbus_vpn_service_plugin)
+ nmdbus_vpn_plugin_emit_config (priv->dbus_vpn_service_plugin, config);
}
void
@@ -387,7 +436,8 @@ nm_vpn_service_plugin_set_ip4_config (NMVpnServicePlugin *plugin,
combined_config = g_variant_builder_end (&builder);
g_variant_ref_sink (combined_config);
g_signal_emit (plugin, signals[IP4_CONFIG], 0, combined_config);
- nmdbus_vpn_plugin_emit_ip4_config (priv->dbus_vpn_service_plugin, combined_config);
+ if (priv->dbus_vpn_service_plugin)
+ nmdbus_vpn_plugin_emit_ip4_config (priv->dbus_vpn_service_plugin, combined_config);
g_variant_unref (combined_config);
if ( priv->has_ip4 == priv->got_ip4
@@ -408,7 +458,8 @@ nm_vpn_service_plugin_set_ip6_config (NMVpnServicePlugin *plugin,
priv->got_ip6 = TRUE;
g_signal_emit (plugin, signals[IP6_CONFIG], 0, ip6_config);
- nmdbus_vpn_plugin_emit_ip6_config (priv->dbus_vpn_service_plugin, ip6_config);
+ if (priv->dbus_vpn_service_plugin)
+ nmdbus_vpn_plugin_emit_ip6_config (priv->dbus_vpn_service_plugin, ip6_config);
g_variant_unref (ip6_config);
@@ -698,7 +749,8 @@ nm_vpn_service_plugin_secrets_required (NMVpnServicePlugin *plugin,
nm_clear_g_source (&priv->connect_timer);
g_signal_emit (plugin, signals[SECRETS_REQUIRED], 0, message, hints);
- nmdbus_vpn_plugin_emit_secrets_required (priv->dbus_vpn_service_plugin, message, hints);
+ if (priv->dbus_vpn_service_plugin)
+ nmdbus_vpn_plugin_emit_secrets_required (priv->dbus_vpn_service_plugin, message, hints);
}
/*****************************************************************************/
@@ -1026,7 +1078,7 @@ set_property (GObject *object, guint prop_id,
break;
case PROP_STATE:
nm_vpn_service_plugin_set_state (NM_VPN_SERVICE_PLUGIN (object),
- (NMVpnServiceState) g_value_get_enum (value));
+ (NMVpnServiceState) g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1059,31 +1111,7 @@ get_property (GObject *object, guint prop_id,
static void
dispose (GObject *object)
{
- NMVpnServicePlugin *plugin = NM_VPN_SERVICE_PLUGIN (object);
- NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin);
- NMVpnServiceState state;
- GError *err = NULL;
-
- nm_clear_g_source (&priv->fail_stop_id);
- nm_clear_g_source (&priv->quit_timer);
- nm_clear_g_source (&priv->connect_timer);
-
- state = nm_vpn_service_plugin_get_state (plugin);
-
- if (state == NM_VPN_SERVICE_STATE_STARTED ||
- state == NM_VPN_SERVICE_STATE_STARTING)
- nm_vpn_service_plugin_disconnect (plugin, &err);
-
- if (err) {
- g_warning ("Error disconnecting VPN connection: %s", err->message);
- g_error_free (err);
- }
-
- if (priv->dbus_vpn_service_plugin) {
- g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (priv->dbus_vpn_service_plugin));
- g_clear_object (&priv->dbus_vpn_service_plugin);
- }
-
+ nm_vpn_service_plugin_shutdown (NM_VPN_SERVICE_PLUGIN (object));
G_OBJECT_CLASS (nm_vpn_service_plugin_parent_class)->dispose (object);
}
diff --git a/libnm/nm-vpn-service-plugin.h b/libnm/nm-vpn-service-plugin.h
index 329345ea19..71e031b08a 100644
--- a/libnm/nm-vpn-service-plugin.h
+++ b/libnm/nm-vpn-service-plugin.h
@@ -150,6 +150,9 @@ NM_AVAILABLE_IN_1_2
gboolean nm_vpn_service_plugin_disconnect (NMVpnServicePlugin *plugin,
GError **err);
+NM_AVAILABLE_IN_1_12
+void nm_vpn_service_plugin_shutdown (NMVpnServicePlugin *plugin);
+
/* Utility functions */
NM_AVAILABLE_IN_1_2