Fix provider refcounting
authorSamuel Ortiz <sameo@linux.intel.com>
Mon, 9 Aug 2010 14:32:45 +0000 (16:32 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Mon, 9 Aug 2010 14:35:50 +0000 (16:35 +0200)
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.

plugins/openconnect.c
src/provider.c
src/service.c

index cdd18cfec3505a9778b2ca3f7e6fe86bbc984dc4..11377c3e21c5f792ba8a2ec475e149c9f3367d3c 100644 (file)
@@ -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;
index 8783a307a30b249d2eb38144e8d3f709a1e8d6a1..47aaa76445449472d99c720c164607ae95b292bb 100644 (file)
@@ -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)
index 5914b40e3ff9538085f96a3a214e0084a13cbf7b..cc77dd7c7122a72129fcbbbda4205dd319baa289 100644 (file)
@@ -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;