Prevent from finalizing twice. 09/11809/1
authorSung-jae Park <nicesj.park@samsung.com>
Tue, 5 Nov 2013 10:04:01 +0000 (19:04 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Tue, 5 Nov 2013 10:04:01 +0000 (19:04 +0900)
If a develop calls provider_fini, and there is a connection with master,
the disconnected event callback will be called.

In that case, the developer can calls provider_fini again from the disconnected callback.
Then the finalizing sequence will be processed twice.

This can cause the serious problem of service providers.

So this patch will check the provider_fini calling status,
And prevent from finalizing twice.

Change-Id: I00b4efd3b52ad1de6a5dee2a40d30609e3ac318e

src/provider.c

index eb5154e..e205d2b 100644 (file)
@@ -938,6 +938,10 @@ EAPI int provider_init(void *disp, const char *name, struct event_handler *table
                return LB_STATUS_ERROR_ALREADY;
        }
 
+       /*!
+        * \note
+        * getenv is not safe in the threads.
+        */
        option = getenv("PROVIDER_DISABLE_PREVENT_OVERWRITE");
        if (option && !strcasecmp(option, "true")) {
                s_info.prevent_overwrite = 1;
@@ -954,17 +958,27 @@ EAPI int provider_init(void *disp, const char *name, struct event_handler *table
 EAPI void *provider_fini(void)
 {
        void *ret;
+       static int provider_fini_called = 0;
+
+       if (provider_fini_called) {
+               ErrPrint("Provider finalize is already called\n");
+               return NULL;
+       }
 
        if (!s_info.name) {
                ErrPrint("Connection is not established (or cleared already)\n");
                return NULL;
        }
 
+       provider_fini_called = 1;
+
        if (s_info.fd >= 0) {
                com_core_packet_client_fini(s_info.fd);
                s_info.fd = -1;
        }
 
+       provider_fini_called = 0;
+
        com_core_del_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
        com_core_del_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL);
 
@@ -975,6 +989,7 @@ EAPI void *provider_fini(void)
 
        ret = s_info.data;
        s_info.data = NULL;
+
        return ret;
 }