summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2010-08-09 16:32:45 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2010-08-09 16:35:50 +0200
commit10849f787cd0d1a64a2c0b16663ae3b8743bb5c2 (patch)
tree8047c589655e5b9a63c358ee8ac7d0b57d659ba6
parent43e7b0260857b48f19aa4165699453dd6608bb3b (diff)
downloadconnman-10849f787cd0d1a64a2c0b16663ae3b8743bb5c2.tar.gz
connman-10849f787cd0d1a64a2c0b16663ae3b8743bb5c2.tar.bz2
connman-10849f787cd0d1a64a2c0b16663ae3b8743bb5c2.zip
Fix provider refcounting
The VPN service refcount is bumped at creation time and decreased at destruction time. The openconnect provider bumps the provider refcount at task creation time and decreases it at task destruction time. The service code bumps the provider refcount at service creation time and decreases it at service releasing time.
-rw-r--r--plugins/openconnect.c11
-rw-r--r--src/provider.c3
-rw-r--r--src/service.c5
3 files changed, 9 insertions, 10 deletions
diff --git a/plugins/openconnect.c b/plugins/openconnect.c
index cdd18cfe..11377c3e 100644
--- a/plugins/openconnect.c
+++ b/plugins/openconnect.c
@@ -62,6 +62,7 @@ enum oc_state {
};
struct oc_data {
+ struct connman_provider *provider;
char *if_name;
unsigned flags;
unsigned int watch;
@@ -120,6 +121,7 @@ static void openconnect_died(struct connman_task *task, void *user_data)
kill_tun(data->if_name);
connman_provider_set_data(provider, NULL);
connman_rtnl_remove_watch(data->watch);
+ connman_provider_unref(data->provider);
g_free(data);
oc_exit:
@@ -131,7 +133,6 @@ static void openconnect_died(struct connman_task *task, void *user_data)
CONNMAN_PROVIDER_STATE_IDLE);
connman_provider_set_index(provider, -1);
- connman_provider_unref(provider);
connman_task_destroy(task);
}
@@ -241,6 +242,7 @@ static int oc_connect(struct connman_provider *provider)
if (data == NULL)
return -ENOMEM;
+ data->provider = connman_provider_ref(provider);
data->watch = 0;
data->flags = 0;
data->task = NULL;
@@ -373,8 +375,6 @@ static int oc_connect(struct connman_provider *provider)
goto exist_err;
}
- connman_provider_ref(provider);
-
data->state = OC_STATE_CONNECT;
return -EINPROGRESS;
@@ -382,6 +382,7 @@ static int oc_connect(struct connman_provider *provider)
exist_err:
connman_provider_set_index(provider, -1);
connman_provider_set_data(provider, NULL);
+ connman_provider_unref(data->provider);
g_free(data);
return ret;
@@ -408,8 +409,6 @@ static int oc_disconnect(struct connman_provider *provider)
data->state = OC_STATE_DISCONNECT;
connman_task_stop(data->task);
- connman_provider_unref(provider);
-
return 0;
}
@@ -427,8 +426,6 @@ static int oc_remove(struct connman_provider *provider)
data->watch = 0;
connman_task_stop(data->task);
- connman_provider_unref(provider);
-
g_usleep(G_USEC_PER_SEC);
kill_tun(data->if_name);
return 0;
diff --git a/src/provider.c b/src/provider.c
index 8783a307..47aaa764 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -330,7 +330,7 @@ static void unregister_provider(gpointer data)
DBG("provider %p", provider);
- __connman_provider_disconnect(provider);
+ __connman_service_put(provider->vpn_service);
connman_element_unregister(&provider->element);
connman_provider_unref(provider);
@@ -347,7 +347,6 @@ static void provider_destruct(struct connman_element *element)
g_free(provider->domain);
g_free(provider->identifier);
g_free(provider->dns);
- __connman_service_put(provider->vpn_service);
}
static void __connman_provider_initialize(struct connman_provider *provider)
diff --git a/src/service.c b/src/service.c
index 5914b40e..cc77dd7c 100644
--- a/src/service.c
+++ b/src/service.c
@@ -2011,6 +2011,9 @@ static void service_free(gpointer user_data)
if (service->network != NULL)
connman_network_unref(service->network);
+ if (service->provider != NULL)
+ connman_provider_unref(service->provider);
+
if (service->ipconfig != NULL) {
connman_ipconfig_unref(service->ipconfig);
service->ipconfig = NULL;
@@ -3469,7 +3472,7 @@ __connman_service_create_from_provider(struct connman_provider *provider)
return NULL;
service->type = CONNMAN_SERVICE_TYPE_VPN;
- service->provider = provider;
+ service->provider = connman_provider_ref(provider);
service->autoconnect = FALSE;
service->state = CONNMAN_SERVICE_STATE_IDLE;