Use Mutex insted of thread scope variables. 98/279898/1
authorAnjali Nijhara <a.nijhara@samsung.com>
Thu, 18 Aug 2022 05:19:47 +0000 (10:49 +0530)
committerAnjali Nijhara <a.nijhara@samsung.com>
Thu, 18 Aug 2022 05:19:47 +0000 (10:49 +0530)
Change-Id: Ia615d623e42ea0684b38d64bb9317628ff605706

packaging/capi-network-nsd.spec
src/dns-sd/dns-sd-util.h
src/dns-sd/dns-sd.c
src/ssdp/ssdp-util.h
src/ssdp/ssdp.c

index ac19fdb..bad8279 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-network-nsd
 Summary:    A Network Service Discovery libraries in Native API
-Version:    0.1.1
+Version:    0.1.2
 Release:    2
 Group:      System/Network
 License:    Apache-2.0
index f65d4dd..4ef9f77 100644 (file)
 
 #endif /* USE_DLOG */
 
+#define DNSSD_LOCK \
+       do { \
+               _dnssd_lock(); \
+       } while(0)
+
+#define DNSSD_UNLOCK \
+       do { \
+               _dnssd_unlock(); \
+       } while(0)
+
 #define NETWORK_SERVICE_DISCOVERY_FEATURE "http://tizen.org/feature/network.service_discovery.dnssd"
 
 #define CHECK_FEATURE_SUPPORTED(feature_name)\
@@ -134,4 +144,7 @@ typedef struct _resolve_reply_data {
        char *service_name;
 } resolve_reply_data;
 
+void _dnssd_lock(void);
+void _dnssd_unlock(void);
+
 #endif /* __TIZEN_NET_DNSSD_UTIL_H__ */
index 0d4a959..c455f1a 100644 (file)
@@ -14,6 +14,8 @@
 * limitations under the License.
 */
 
+#define _GNU_SOURCE
+#include <pthread.h>
 #include <net/if.h>
 #include <dlog.h>
 #include <glib.h>
@@ -42,6 +44,7 @@
        do {\
                if (__dnssd_is_init() == false) {\
                        DNSSD_LOGE("Not initialized");\
+                       DNSSD_UNLOCK;\
                        __DNSSD_LOG_FUNC_EXIT__;\
                        return DNSSD_ERROR_NOT_INITIALIZED;\
                } \
        do {\
                if (__dnssd_check_permission() == false) {\
                        DNSSD_LOGE("Permission denied");\
+                       DNSSD_UNLOCK;\
                        __DNSSD_LOG_FUNC_EXIT__;\
                        return DNSSD_ERROR_PERMISSION_DENIED;\
                } \
        } while (0)
 
-static __thread GSList *dnssd_handle_list = NULL;
-static __thread GSList *resolve_handle_list = NULL;
-static __thread bool g_is_init = false;
-static __thread GDBusConnection *netconfig_bus = NULL;
+static GSList *dnssd_handle_list = NULL;
+static GSList *resolve_handle_list = NULL;
+static bool g_is_init = false;
+static GDBusConnection *netconfig_bus = NULL;
+
+static pthread_mutex_t dnssd_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 
 //LCOV_EXCL_START
 static const char *dnssd_error_to_string(DNSServiceErrorType dnssd_service_error)
@@ -412,9 +418,11 @@ EXPORT_API int dnssd_initialize(void)
        int res = 0;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
 
        if (__dnssd_is_init() == true) {
                DNSSD_LOGE("Already initialized");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_OPERATION;
        }
@@ -422,12 +430,14 @@ EXPORT_API int dnssd_initialize(void)
        res = __connect_netconfig_gdbus();
        if (res != DNSSD_ERROR_NONE) {
                DNSSD_LOGE("Failed to launch mdnsresponder");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return res;
        }
 
        __dnssd_set_initialized(true);
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -437,6 +447,7 @@ EXPORT_API int dnssd_deinitialize(void)
        __DNSSD_LOG_FUNC_ENTER__;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
 
        CHECK_INITIALIZED();
 
@@ -444,6 +455,7 @@ EXPORT_API int dnssd_deinitialize(void)
 
        __disconnect_netconfig_gdbus();
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -457,12 +469,14 @@ EXPORT_API int dnssd_create_local_service(const char *service_type,
        unsigned int handler;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
 
        CHECK_INITIALIZED();
 
        if (dnssd_service == NULL || service_type == NULL ||
                        __dnssd_get_struct_from_handle(*dnssd_service) != NULL) {
                DNSSD_LOGE("Invalid Parameter");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -470,6 +484,7 @@ EXPORT_API int dnssd_create_local_service(const char *service_type,
        local_handle = (dnssd_handle_s *)g_try_malloc0(REG_SIZE);
        if (local_handle == NULL) {
                DNSSD_LOGE("Failed to Allocate Memory");        //LCOV_EXCL_LINE
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;                                        //LCOV_EXCL_LINE
                return DNSSD_ERROR_OUT_OF_MEMORY;                       //LCOV_EXCL_LINE
        }
@@ -491,6 +506,7 @@ EXPORT_API int dnssd_create_local_service(const char *service_type,
 
        dnssd_handle_list = g_slist_prepend(dnssd_handle_list, local_handle);
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -499,8 +515,6 @@ static int __get_valid_registered_handle(dnssd_service_h dnssd_service, dnssd_ha
 {
        dnssd_handle_s *local_handle;
 
-       CHECK_INITIALIZED();
-
        local_handle = __dnssd_get_struct_from_handle(dnssd_service);
        if (local_handle == NULL) {
                DNSSD_LOGD("Service Handler not found");
@@ -526,10 +540,15 @@ EXPORT_API int dnssd_destroy_local_service(dnssd_service_h dnssd_service)
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
+
+       CHECK_INITIALIZED();
 
        res = __get_valid_registered_handle(dnssd_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        DNSSD_LOGD("Destroy handle: [%p]->[%u]", local_handle, dnssd_service);
 
@@ -541,6 +560,7 @@ EXPORT_API int dnssd_destroy_local_service(dnssd_service_h dnssd_service)
        local_handle = NULL;
 
        DNSSD_LOGD("g_slist length [%d]", g_slist_length(dnssd_handle_list));
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -554,13 +574,19 @@ EXPORT_API int dnssd_service_set_name(dnssd_service_h local_service,
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
+
+       CHECK_INITIALIZED();
 
        res = __get_valid_registered_handle(local_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        if (service_name == NULL) {
                DNSSD_LOGD("Service name is NULL");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -571,6 +597,7 @@ EXPORT_API int dnssd_service_set_name(dnssd_service_h local_service,
 
        DNSSD_LOGD("Successfully set service name %s", service_name);
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -583,13 +610,19 @@ EXPORT_API int dnssd_service_set_port(dnssd_service_h local_service, int port)
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
+
+       CHECK_INITIALIZED();
 
        res = __get_valid_registered_handle(local_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        if (port < 0 || port > 65535) {
                DNSSD_LOGD("Invalid port range");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -599,6 +632,7 @@ EXPORT_API int dnssd_service_set_port(dnssd_service_h local_service, int port)
 
        DNSSD_LOGD("Successfully set port %d", port);
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -612,13 +646,19 @@ EXPORT_API int dnssd_service_set_interface(dnssd_service_h local_service, const
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
+
+       CHECK_INITIALIZED();
 
        res = __get_valid_registered_handle(local_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        if ((if_index = if_nametoindex(interface)) == 0) {
                DNSSD_LOGE("Invalid interface name");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -629,6 +669,7 @@ EXPORT_API int dnssd_service_set_interface(dnssd_service_h local_service, const
 
        DNSSD_LOGD("Successfully set interface %s with index %u", interface, if_index);
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -645,19 +686,26 @@ EXPORT_API int dnssd_service_add_txt_record(dnssd_service_h local_service,
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
+
+       CHECK_INITIALIZED();
 
        res = __get_valid_registered_handle(local_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        if (key == NULL) {
                DNSSD_LOGE("key is NULL");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
 
        if (length > 255) {
                DNSSD_LOGE("Invalid length");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -678,12 +726,14 @@ EXPORT_API int dnssd_service_add_txt_record(dnssd_service_h local_service,
        if (ret != kDNSServiceErr_NoError) {
                DNSSD_LOGE("Failed to add value to key, error[%s]",     //LCOV_EXCL_LINE
                                dnssd_error_to_string(ret));                            //LCOV_EXCL_LINE
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_OPERATION_FAILED;
        } else {
                DNSSD_LOGD("Succeeded to add value to key");
        }
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -700,13 +750,19 @@ EXPORT_API int dnssd_service_remove_txt_record(dnssd_service_h local_service,
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
+
+       CHECK_INITIALIZED();
 
        res = __get_valid_registered_handle(local_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        if (key == NULL) {
                DNSSD_LOGE("key is NULL");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -718,6 +774,7 @@ EXPORT_API int dnssd_service_remove_txt_record(dnssd_service_h local_service,
        if (ret != kDNSServiceErr_NoError) {
                DNSSD_LOGE("Failed to remove value from key, error[%s]",
                                dnssd_error_to_string(ret));
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_OPERATION_FAILED;
        } else {
@@ -733,6 +790,7 @@ EXPORT_API int dnssd_service_remove_txt_record(dnssd_service_h local_service,
                reg->is_txt_ref = 0;
        }
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -747,10 +805,15 @@ EXPORT_API int dnssd_service_set_record(dnssd_service_h local_service, unsigned
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
+
+       CHECK_INITIALIZED();
 
        res = __get_valid_registered_handle(local_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        reg = GET_REG_DATA_P(local_handle);
        DNSSD_LOGD("Record Type %d Record len %d", type, length);
@@ -768,12 +831,14 @@ EXPORT_API int dnssd_service_set_record(dnssd_service_h local_service, unsigned
        if (ret != kDNSServiceErr_NoError) {
                DNSSD_LOGE("Failed to Add Record for DNS Service, error[%s]",   //LCOV_EXCL_LINE
                                dnssd_error_to_string(ret));                                                    //LCOV_EXCL_LINE
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;                                                                                //LCOV_EXCL_LINE
                return DNSSD_ERROR_OPERATION_FAILED;                                                    //LCOV_EXCL_LINE
        }
 
        DNSSD_LOGD("Successfully added record for DNS Service");
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -791,15 +856,21 @@ EXPORT_API int dnssd_service_unset_record(dnssd_service_h local_service,
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
+
+       CHECK_INITIALIZED();
 
        res = __get_valid_registered_handle(local_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        reg = GET_REG_DATA_P(local_handle);
 
        if (reg->record_ref == NULL) {
                DNSSD_LOGE("Invalid DNS SD Client");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -815,6 +886,7 @@ EXPORT_API int dnssd_service_unset_record(dnssd_service_h local_service,
        if (ret != kDNSServiceErr_NoError) {
                DNSSD_LOGE("Failed to Remove Record for DNS Service, error[%s]",        //LCOV_EXCL_LINE
                                dnssd_error_to_string(ret));                                                            //LCOV_EXCL_LINE
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;                                                                                        //LCOV_EXCL_LINE
                return DNSSD_ERROR_OPERATION_FAILED;    //LCOV_EXCL_LINE
        }
@@ -823,6 +895,7 @@ EXPORT_API int dnssd_service_unset_record(dnssd_service_h local_service,
 
        DNSSD_LOGD("Successfully removed record for DNS Service");
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -831,9 +904,11 @@ static void __dnssd_register_reply_cb(DNSServiceRef sd_ref, unsigned int flags,
                DNSServiceErrorType error_code, const char *service_name,
                const char *service_type, const char *domain, void *user_data)
 {
+       DNSSD_LOCK;
        dnssd_handle_s *dnssd_handle;
        dnssd_register_data_s *reg = NULL;
        GSList *list;
+
        dnssd_registered_cb callback;
        void *data;
 
@@ -867,6 +942,56 @@ static void __dnssd_register_reply_cb(DNSServiceRef sd_ref, unsigned int flags,
                        break;
                }
        }
+       DNSSD_UNLOCK;
+}
+
+static int __get_valid_handle(dnssd_service_h dnssd_service, dnssd_handle_s **handle)
+{
+       dnssd_handle_s *local_handle;
+
+       local_handle = __dnssd_get_struct_from_handle(dnssd_service);
+       if (local_handle == NULL) {
+               DNSSD_LOGD("Service Handler not found");
+               __DNSSD_LOG_FUNC_EXIT__;
+               return DNSSD_ERROR_SERVICE_NOT_FOUND;
+       }
+
+       *handle = local_handle;
+
+       return DNSSD_ERROR_NONE;
+}
+
+static int __dnssd_service_get_all_txt_record(dnssd_service_h dnssd_service,
+               unsigned short *length, void **value)
+{
+       __DNSSD_LOG_FUNC_ENTER__;
+       TXTRecordRef *txt_record;
+       dnssd_handle_s *local_handle = NULL;
+       int res;
+
+       res = __get_valid_handle(dnssd_service, &local_handle);
+       if (res != DNSSD_ERROR_NONE)
+               return res;
+
+       if (local_handle->op_type == DNSSD_TYPE_FOUND) {
+
+               dnssd_found_data_s *found = NULL;
+               found = GET_FOUND_DATA_P(local_handle);
+
+               *value = g_strndup(found->txt_record, found->txt_len);
+               *length = found->txt_len;
+       } else {
+
+               dnssd_register_data_s *reg = NULL;
+               reg = GET_REG_DATA_P(local_handle);
+               txt_record = &(reg->txt_ref);
+
+               *length = TXTRecordGetLength(txt_record);
+               *value = g_strndup(TXTRecordGetBytesPtr(txt_record), *length);
+       }
+
+       __DNSSD_LOG_FUNC_EXIT__;
+       return DNSSD_ERROR_NONE;
 }
 
 EXPORT_API int dnssd_register_local_service(dnssd_service_h local_service,
@@ -881,15 +1006,21 @@ EXPORT_API int dnssd_register_local_service(dnssd_service_h local_service,
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
 
        CHECK_PERMISSION();
 
+       CHECK_INITIALIZED();
+
        res = __get_valid_registered_handle(local_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        if (register_cb == NULL) {
                DNSSD_LOGE("No callback provided");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -905,7 +1036,7 @@ EXPORT_API int dnssd_register_local_service(dnssd_service_h local_service,
        DNSSD_LOGD("Domain/Interface/Flags : %s/%d/0x%x", local_handle->domain,
                        reg->if_index, local_handle->flags);
 
-       dnssd_service_get_all_txt_record(local_service, &length, &data);
+       __dnssd_service_get_all_txt_record(local_service, &length, &data);
 
        ret = DNSServiceRegister(&(local_handle->sd_ref), local_handle->flags,
                        reg->if_index, reg->service_name,
@@ -917,6 +1048,7 @@ EXPORT_API int dnssd_register_local_service(dnssd_service_h local_service,
        if (ret != kDNSServiceErr_NoError) {
                DNSSD_LOGE("Failed to register for dns service, error[%s]",     //LCOV_EXCL_LINE
                                dnssd_error_to_string(ret));    //LCOV_EXCL_LINE
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;        //LCOV_EXCL_LINE
                return DNSSD_ERROR_OPERATION_FAILED;    //LCOV_EXCL_LINE
        }
@@ -926,6 +1058,7 @@ EXPORT_API int dnssd_register_local_service(dnssd_service_h local_service,
        __dnssd_handle_add_event_handler(&(local_handle->watch_id), local_handle);
 
        DNSSD_LOGD("Succeeded to register for dns service");
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -939,13 +1072,19 @@ EXPORT_API int dnssd_deregister_local_service(dnssd_service_h local_service)
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
+
+       CHECK_INITIALIZED();
 
        res = __get_valid_registered_handle(local_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        if (local_handle->sd_ref == NULL) {
                DNSSD_LOGE("Invalid DNS SD Client");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -969,6 +1108,7 @@ EXPORT_API int dnssd_deregister_local_service(dnssd_service_h local_service)
        DNSServiceRefDeallocate(local_handle->sd_ref);
        local_handle->sd_ref = NULL;
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -976,6 +1116,7 @@ EXPORT_API int dnssd_deregister_local_service(dnssd_service_h local_service)
 //LCOV_EXCL_START
 static gboolean __remove_service_getaddrinfo_socket(gpointer user_data)
 {
+       DNSSD_LOCK;
        DNSSD_LOGD("Remove DNSServiceGetAddrInfo socket");
        dnssd_handle_s *local_handle = user_data;
        if (local_handle->watch_id > 0)
@@ -983,6 +1124,7 @@ static gboolean __remove_service_getaddrinfo_socket(gpointer user_data)
        DNSServiceRefDeallocate(local_handle->sd_ref);
        local_handle->watch_id = 0;
        local_handle->sd_ref = NULL;
+       DNSSD_UNLOCK;
        return FALSE;
 }
 
@@ -992,6 +1134,7 @@ static void __dnssd_getaddrinfo_reply_cb(DNSServiceRef sd_ref,
                const struct sockaddr *address, unsigned int ttl,
                void *user_data)
 {
+       DNSSD_LOCK;
        dnssd_handle_s *dnssd_handle = NULL;
        dnssd_handle_s *local_handle = NULL;
        dnssd_browse_data_s *browse = NULL;
@@ -1001,6 +1144,7 @@ static void __dnssd_getaddrinfo_reply_cb(DNSServiceRef sd_ref,
 
        if (user_data == NULL) {
                DNSSD_LOGD("Invalid found handle");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return;
        }
@@ -1017,6 +1161,7 @@ static void __dnssd_getaddrinfo_reply_cb(DNSServiceRef sd_ref,
        dnssd_handle = __dnssd_get_struct_from_handle(found->browse_handler);
        if (dnssd_handle == NULL) {
                DNSSD_LOGD("Invalid browse handle");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return;
        }
@@ -1045,6 +1190,7 @@ static void __dnssd_getaddrinfo_reply_cb(DNSServiceRef sd_ref,
        if (flags & kDNSServiceFlagsMoreComing) {
                DNSSD_LOGD("More results are queued, No need to send callback to "
                                "application at this stage");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return;
        }
@@ -1061,6 +1207,7 @@ static void __dnssd_getaddrinfo_reply_cb(DNSServiceRef sd_ref,
        }
        g_idle_add_full(G_PRIORITY_HIGH, __remove_service_getaddrinfo_socket,
                                        local_handle, NULL);
+       DNSSD_UNLOCK;
 }
 
 static int __dnssd_getaddrinfo(dnssd_handle_s *dnssd_handle, unsigned int flags,
@@ -1149,6 +1296,7 @@ static int __dnssd_getaddrinfo(dnssd_handle_s *dnssd_handle, unsigned int flags,
 
 static gboolean __remove_service_resolve_socket(gpointer user_data)
 {
+       DNSSD_LOCK;
        DNSSD_LOGD("Remove DNSServiceResolve socket");
        resolve_reply_data *resolve_data = user_data;
        if (resolve_data->watch_id > 0)
@@ -1156,6 +1304,7 @@ static gboolean __remove_service_resolve_socket(gpointer user_data)
        DNSServiceRefDeallocate(resolve_data->sd_ref);
        resolve_data->watch_id = 0;
        resolve_data->sd_ref = NULL;
+       DNSSD_UNLOCK;
        return FALSE;
 }
 
@@ -1165,11 +1314,13 @@ static void __dnssd_resolve_reply_cb(DNSServiceRef sd_ref, unsigned int flags,
                unsigned short port, unsigned short txt_len,
                const unsigned char *txt_record, void *user_data)
 {
+       DNSSD_LOCK;
        resolve_reply_data *resolve_data = user_data;
        DNSSD_LOGD("Received Resolve Reply");
 
        if (flags & kDNSServiceFlagsMoreComing) {
                DNSSD_LOGD("More results are queued");
+               DNSSD_UNLOCK;
                return;
        }
 
@@ -1180,6 +1331,7 @@ static void __dnssd_resolve_reply_cb(DNSServiceRef sd_ref, unsigned int flags,
 
        g_idle_add_full(G_PRIORITY_HIGH, __remove_service_resolve_socket,
                                        resolve_data, NULL);
+       DNSSD_UNLOCK;
 }
 
 static int __dnssd_resolve_dns_service(dnssd_handle_s *dnssd_handle,
@@ -1259,6 +1411,7 @@ static void __dnssd_browse_reply_cb(DNSServiceRef sd_ref, unsigned int flags,
                const char *domain, void *user_data)
 {
        __DNSSD_LOG_FUNC_ENTER__;
+       DNSSD_LOCK;
        dnssd_handle_s *dnssd_handle;
        GSList *list;
        void *data;
@@ -1269,6 +1422,7 @@ static void __dnssd_browse_reply_cb(DNSServiceRef sd_ref, unsigned int flags,
                DNSSD_LOGE("Failed to browse, error code %s",
                                dnssd_error_to_string(error_code));
                __DNSSD_LOG_FUNC_EXIT__;
+               DNSSD_UNLOCK;
                return;
        }
 
@@ -1317,6 +1471,7 @@ static void __dnssd_browse_reply_cb(DNSServiceRef sd_ref, unsigned int flags,
                        DNSSD_LOGD("Finished executing Browse Callback");
                }
        }
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
 }
 
@@ -1331,6 +1486,7 @@ EXPORT_API int dnssd_start_browsing_service(const char *service_type,
        unsigned int handler;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
 
        CHECK_PERMISSION();
 
@@ -1339,6 +1495,7 @@ EXPORT_API int dnssd_start_browsing_service(const char *service_type,
        if (found_cb == NULL || dnssd_service == NULL || service_type == NULL ||
                        __dnssd_get_struct_from_handle(*dnssd_service) != NULL) {
                DNSSD_LOGE("Invalid Parameter");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -1346,6 +1503,7 @@ EXPORT_API int dnssd_start_browsing_service(const char *service_type,
        local_handle = (dnssd_handle_s *)g_try_malloc0(BROWSE_SIZE);
        if (local_handle == NULL) {
                DNSSD_LOGE("Failed to Allocate Memory");        //LCOV_EXCL_LINE
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;        //LCOV_EXCL_LINE
                return DNSSD_ERROR_OUT_OF_MEMORY;       //LCOV_EXCL_LINE
        }
@@ -1372,6 +1530,7 @@ EXPORT_API int dnssd_start_browsing_service(const char *service_type,
                                dnssd_error_to_string(ret));    //LCOV_EXCL_LINE
                g_free(local_handle->service_type);     //LCOV_EXCL_LINE
                g_free(local_handle);   //LCOV_EXCL_LINE
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;        //LCOV_EXCL_LINE
                return DNSSD_ERROR_OPERATION_FAILED;    //LCOV_EXCL_LINE
        }
@@ -1382,6 +1541,7 @@ EXPORT_API int dnssd_start_browsing_service(const char *service_type,
        __dnssd_handle_add_event_handler(&(local_handle->watch_id), local_handle);
 
        DNSSD_LOGD("Succeeded to browse for dns service");
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -1398,6 +1558,7 @@ EXPORT_API int dnssd_start_browsing_service_on_interface(const char *service_typ
        unsigned int if_index;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
 
        CHECK_PERMISSION();
 
@@ -1406,6 +1567,7 @@ EXPORT_API int dnssd_start_browsing_service_on_interface(const char *service_typ
        if (found_cb == NULL || dnssd_service == NULL || service_type == NULL ||
                        __dnssd_get_struct_from_handle(*dnssd_service) != NULL) {
                DNSSD_LOGE("Invalid Parameter");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -1413,6 +1575,7 @@ EXPORT_API int dnssd_start_browsing_service_on_interface(const char *service_typ
        local_handle = (dnssd_handle_s *)g_try_malloc0(BROWSE_SIZE);
        if (local_handle == NULL) {
                DNSSD_LOGE("Failed to Allocate Memory");        //LCOV_EXCL_LINE
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;        //LCOV_EXCL_LINE
                return DNSSD_ERROR_OUT_OF_MEMORY;       //LCOV_EXCL_LINE
        }
@@ -1420,6 +1583,7 @@ EXPORT_API int dnssd_start_browsing_service_on_interface(const char *service_typ
        if ((if_index = if_nametoindex(interface)) == 0) {
                DNSSD_LOGE("Invalid interface name");
                g_free(local_handle);
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -1447,6 +1611,7 @@ EXPORT_API int dnssd_start_browsing_service_on_interface(const char *service_typ
                                dnssd_error_to_string(ret));    //LCOV_EXCL_LINE
                g_free(local_handle->service_type);     //LCOV_EXCL_LINE
                g_free(local_handle);   //LCOV_EXCL_LINE
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;        //LCOV_EXCL_LINE
                return DNSSD_ERROR_OPERATION_FAILED;    //LCOV_EXCL_LINE
        }
@@ -1457,6 +1622,7 @@ EXPORT_API int dnssd_start_browsing_service_on_interface(const char *service_typ
        __dnssd_handle_add_event_handler(&(local_handle->watch_id), local_handle);
 
        DNSSD_LOGD("Succeeded to browse for dns service");
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -1579,37 +1745,23 @@ EXPORT_API int dnssd_stop_browsing_service(dnssd_browser_h dnssd_service)
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
 
        res = __get_valid_browsing_handle(dnssd_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        __remove_related_handles(local_handle);
        __destroy_browsing_handle(local_handle);
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
 //LCOV_EXCL_STOP
 
-static int __get_valid_handle(dnssd_service_h dnssd_service, dnssd_handle_s **handle)
-{
-       dnssd_handle_s *local_handle;
-
-       CHECK_INITIALIZED();
-
-       local_handle = __dnssd_get_struct_from_handle(dnssd_service);
-       if (local_handle == NULL) {
-               DNSSD_LOGD("Service Handler not found");
-               __DNSSD_LOG_FUNC_EXIT__;
-               return DNSSD_ERROR_SERVICE_NOT_FOUND;
-       }
-
-       *handle = local_handle;
-
-       return DNSSD_ERROR_NONE;
-}
-
 EXPORT_API int dnssd_service_get_type(dnssd_service_h dnssd_service, char **service_type)
 {
        __DNSSD_LOG_FUNC_ENTER__;
@@ -1617,13 +1769,19 @@ EXPORT_API int dnssd_service_get_type(dnssd_service_h dnssd_service, char **serv
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
+
+       CHECK_INITIALIZED();
 
        res = __get_valid_handle(dnssd_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        if (service_type == NULL) {
                DNSSD_LOGE("Invalid Parameter");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -1631,6 +1789,7 @@ EXPORT_API int dnssd_service_get_type(dnssd_service_h dnssd_service, char **serv
        *service_type = g_strdup(local_handle->service_type);
        DNSSD_LOGD("Service Type %s", *service_type);
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -1642,13 +1801,19 @@ EXPORT_API int dnssd_service_get_name(dnssd_service_h dnssd_service, char **serv
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
+
+       CHECK_INITIALIZED();
 
        res = __get_valid_handle(dnssd_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        if (service_name == NULL) {
                DNSSD_LOGE("Invalid Parameter");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -1664,12 +1829,14 @@ EXPORT_API int dnssd_service_get_name(dnssd_service_h dnssd_service, char **serv
        } else {
                *service_name = NULL;
                DNSSD_LOGD("Invalid DNS SD service");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
 
        DNSSD_LOGD("Service Name %s", *service_name);
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -1684,19 +1851,26 @@ EXPORT_API int dnssd_service_get_ip(dnssd_service_h dnssd_service, char **ip_v4_
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
 
        if (ip_v4_address == NULL && ip_v6_address == NULL) {
                DNSSD_LOGE("Invalid Parameter");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
 
+       CHECK_INITIALIZED();
+
        res = __get_valid_handle(dnssd_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        if (local_handle->op_type != DNSSD_TYPE_FOUND) {
                DNSSD_LOGD("Invalid DNS SD Service");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -1722,6 +1896,7 @@ EXPORT_API int dnssd_service_get_ip(dnssd_service_h dnssd_service, char **ip_v4_
                                addr[14], addr[15]);
        }
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -1733,13 +1908,19 @@ EXPORT_API int dnssd_service_get_port(dnssd_service_h dnssd_service, int *port)
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
+
+       CHECK_INITIALIZED();
 
        res = __get_valid_handle(dnssd_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
                return res;
+       }
 
        if (port == NULL) {
                DNSSD_LOGE("Invalid Parameter");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
@@ -1755,11 +1936,13 @@ EXPORT_API int dnssd_service_get_port(dnssd_service_h dnssd_service, int *port)
        } else {
                *port = 0;
                DNSSD_LOGD("Invalid DNS SD service");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
        DNSSD_LOGD("Port %d", *port);
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
@@ -1768,39 +1951,38 @@ EXPORT_API int dnssd_service_get_all_txt_record(dnssd_service_h dnssd_service,
                unsigned short *length, void **value)
 {
        __DNSSD_LOG_FUNC_ENTER__;
-       TXTRecordRef *txt_record;
-       dnssd_handle_s *local_handle;
        int res;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       DNSSD_LOCK;
 
-       res = __get_valid_handle(dnssd_service, &local_handle);
-       if (res != DNSSD_ERROR_NONE)
-               return res;
+       CHECK_INITIALIZED();
 
        if (value == NULL || length == NULL) {
                DNSSD_LOGE("Invalid Parameter");
+               DNSSD_UNLOCK;
                __DNSSD_LOG_FUNC_EXIT__;
                return DNSSD_ERROR_INVALID_PARAMETER;
        }
 
-       if (local_handle->op_type == DNSSD_TYPE_FOUND) {
-
-               dnssd_found_data_s *found = NULL;
-               found = GET_FOUND_DATA_P(local_handle);
-
-               *value = g_strndup(found->txt_record, found->txt_len);
-               *length = found->txt_len;
-       } else {
-
-               dnssd_register_data_s *reg = NULL;
-               reg = GET_REG_DATA_P(local_handle);
-               txt_record = &(reg->txt_ref);
-
-               *length = TXTRecordGetLength(txt_record);
-               *value = g_strndup(TXTRecordGetBytesPtr(txt_record), *length);
+       res = __dnssd_service_get_all_txt_record(dnssd_service, length, value);
+       if (res != DNSSD_ERROR_NONE) {
+               DNSSD_UNLOCK;
+               __DNSSD_LOG_FUNC_EXIT__;
+               return res;
        }
 
+       DNSSD_UNLOCK;
        __DNSSD_LOG_FUNC_EXIT__;
        return DNSSD_ERROR_NONE;
 }
+
+void _dnssd_lock(void)
+{
+       pthread_mutex_lock(&dnssd_mutex);
+}
+
+void _dnssd_unlock(void)
+{
+       pthread_mutex_unlock(&dnssd_mutex);
+}
index 405091b..deccda1 100644 (file)
 
 #endif /* USE_DLOG */
 
+#define SSDP_LOCK \
+       do { \
+               _ssdp_lock(); \
+       } while(0)
+
+#define SSDP_UNLOCK \
+       do { \
+               _ssdp_unlock(); \
+       } while(0)
+
 #define NETWORK_SERVICE_DISCOVERY_FEATURE "http://tizen.org/feature/network.service_discovery.ssdp"
 
 #define CHECK_FEATURE_SUPPORTED(feature_name)\
@@ -69,4 +79,7 @@
 
 #define GLIST_ITER_END() }
 
+void _ssdp_lock(void);
+void _ssdp_unlock(void);
+
 #endif
index 19ad4bb..f6fadc1 100644 (file)
@@ -17,7 +17,8 @@
 /*****************************************************************************
  * Standard headers
  *****************************************************************************/
-
+#define _GNU_SOURCE
+#include <pthread.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -82,11 +83,13 @@ typedef struct {
 /*****************************************************************************
  * Global Variables
  *****************************************************************************/
-static __thread gboolean g_is_gssdp_init;
-static __thread GSSDPClient *g_gssdp_client = NULL;
+static gboolean g_is_gssdp_init;
+static GSSDPClient *g_gssdp_client = NULL;
+
+static GList *g_ssdp_local_services = NULL;
+static GHashTable *g_found_ssdp_services = NULL;
 
-static __thread GList *g_ssdp_local_services = NULL;
-static __thread GHashTable *g_found_ssdp_services = NULL;
+static pthread_mutex_t ssdp_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 /*****************************************************************************
  * Local Functions Definition
  *****************************************************************************/
@@ -316,6 +319,7 @@ __ssdp_res_available_cb(GSSDPResourceBrowser *resource_browser,
                                const char *usn, GList *urls, gpointer user_data)
 {
        __SSDP_LOG_FUNC_ENTER__;
+       SSDP_LOCK;
        ssdp_service_s *browser = NULL;
        ssdp_service_s *found_service = NULL;
        char *temp_url = NULL;
@@ -326,6 +330,7 @@ __ssdp_res_available_cb(GSSDPResourceBrowser *resource_browser,
        browser = (ssdp_service_s *)user_data;
        if (browser == NULL) {
                SSDP_LOGE("Service not found");
+               SSDP_UNLOCK;
                return;
        }
 
@@ -337,6 +342,7 @@ __ssdp_res_available_cb(GSSDPResourceBrowser *resource_browser,
        temp_url = g_try_malloc0(url_len + 1);
        if (!temp_url) {
                SSDP_LOGE("Failed to get memory for url");
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return;
        }
@@ -352,6 +358,7 @@ __ssdp_res_available_cb(GSSDPResourceBrowser *resource_browser,
                        g_strcmp0(found_service->usn, usn) == 0) {
                SSDP_LOGD("Duplicated service!");
                g_free(temp_url);
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return;
        }
@@ -360,6 +367,7 @@ __ssdp_res_available_cb(GSSDPResourceBrowser *resource_browser,
        if (!found_service) {
                SSDP_LOGE("Failed to get memory for ssdp service structure");
                g_free(temp_url);
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return;
        }
@@ -383,6 +391,7 @@ __ssdp_res_available_cb(GSSDPResourceBrowser *resource_browser,
                                found_service->service_handler, browser->cb_user_data);
        }
 
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return;
 
@@ -395,18 +404,21 @@ __ssdp_res_unavailable_cb(GSSDPResourceBrowser *resource_browser,
                const char *usn, GList *urls, gpointer user_data)
 {
        __SSDP_LOG_FUNC_ENTER__;
+       SSDP_LOCK;
        ssdp_service_s *browser = NULL;
        ssdp_service_s *found_service = NULL;
 
        browser = (ssdp_service_s *)user_data;
        if (browser == NULL) {
                SSDP_LOGE("Browser not found");
+               SSDP_UNLOCK;
                return;
        }
 
        found_service = g_hash_table_lookup(g_found_ssdp_services, usn);
        if (found_service == NULL) {
                SSDP_LOGD("No service matched!");
+               SSDP_UNLOCK;
                return;
        }
 
@@ -425,6 +437,7 @@ __ssdp_res_unavailable_cb(GSSDPResourceBrowser *resource_browser,
 
        SSDP_LOGD("Hash tbl size [%d]", g_hash_table_size(g_found_ssdp_services));
 
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return;
 }
@@ -436,11 +449,13 @@ EXPORT_API int ssdp_initialize()
        int status = SSDP_ERROR_NONE;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        GError *gerror = NULL;
 
        if (g_is_gssdp_init) {
                SSDP_LOGE("gssdp already initialized");
+               SSDP_UNLOCK;
                return SSDP_ERROR_NONE;
        }
 
@@ -449,12 +464,14 @@ EXPORT_API int ssdp_initialize()
                SSDP_LOGE("Error creating the GSSDP client: %s\n",
                                gerror->message);
                g_error_free(gerror); //LCOV_EXCL_LINE
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_OPERATION_FAILED;
        }
 
        if (g_gssdp_client == NULL) {
                SSDP_LOGE("failed to create client\n");
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_OPERATION_FAILED;
        }
@@ -462,7 +479,7 @@ EXPORT_API int ssdp_initialize()
        g_found_ssdp_services = g_hash_table_new(g_str_hash, g_str_equal);
 
        g_is_gssdp_init = TRUE;
-
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
@@ -473,9 +490,11 @@ EXPORT_API int ssdp_deinitialize()
        int status = SSDP_ERROR_NONE;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        if (!g_is_gssdp_init) {
                SSDP_LOGE("gssdp not initialized");
+               SSDP_UNLOCK;
                return SSDP_ERROR_NOT_INITIALIZED;
        }
 
@@ -491,6 +510,7 @@ EXPORT_API int ssdp_deinitialize()
        g_gssdp_client = NULL;
        g_is_gssdp_init = FALSE;
 
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
@@ -502,20 +522,24 @@ EXPORT_API int ssdp_create_local_service(const char *target, ssdp_service_h *ssd
        ssdp_service_s *service = NULL;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        if (!g_is_gssdp_init) {
                SSDP_LOGE("gssdp not initialized");
+               SSDP_UNLOCK;
                return SSDP_ERROR_NOT_INITIALIZED;      //LCOV_EXCL_LINE
        }
 
        if (target == NULL) {
                SSDP_LOGE("target is NULL");
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
 
        if (ssdp_service == NULL) {
                SSDP_LOGE("ssdp_service is NULL");
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
@@ -523,6 +547,7 @@ EXPORT_API int ssdp_create_local_service(const char *target, ssdp_service_h *ssd
        service = (ssdp_service_s*)g_try_malloc0(sizeof(ssdp_service_s));
        if (!service) {
                SSDP_LOGE("Failed to get memory for gssdp service structure");
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_OUT_OF_MEMORY;        //LCOV_EXCL_LINE
        }
@@ -531,6 +556,7 @@ EXPORT_API int ssdp_create_local_service(const char *target, ssdp_service_h *ssd
        if (!service->target) {
                SSDP_LOGE("Failed to get memory for gssdp service type");
                g_free(service);        //LCOV_EXCL_LINE
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_OUT_OF_MEMORY;        //LCOV_EXCL_LINE
        }
@@ -541,6 +567,7 @@ EXPORT_API int ssdp_create_local_service(const char *target, ssdp_service_h *ssd
        service->origin = SSDP_SERVICE_STATE_NOT_REGISTERED;
        g_ssdp_local_services = g_list_append(g_ssdp_local_services, service);
 
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
@@ -552,9 +579,11 @@ EXPORT_API int ssdp_destroy_local_service(ssdp_service_h ssdp_service)
        ssdp_service_s *service = NULL;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        if (ssdp_service == 0) {
                SSDP_LOGE("Invalid parameter");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
 
@@ -562,12 +591,15 @@ EXPORT_API int ssdp_destroy_local_service(ssdp_service_h ssdp_service)
 
        if (!g_is_gssdp_init) {
                SSDP_LOGE("gssdp not initialized");
+               SSDP_UNLOCK;
                return SSDP_ERROR_NOT_INITIALIZED;      //LCOV_EXCL_LINE
        }
 
        service = __ssdp_find_local_service(g_ssdp_local_services, ssdp_service);
-       if (service == NULL)
+       if (service == NULL) {
+               SSDP_UNLOCK;
                return SSDP_ERROR_SERVICE_NOT_FOUND;
+       }
 
        if (service->resource_group != NULL)
                service->resource_group = NULL; //LCOV_EXCL_LINE
@@ -581,6 +613,7 @@ EXPORT_API int ssdp_destroy_local_service(ssdp_service_h ssdp_service)
        g_free(service->url);
        g_free(service);
 
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
@@ -592,9 +625,11 @@ EXPORT_API int ssdp_service_set_usn(ssdp_service_h local_service, const char* us
        ssdp_service_s *service = NULL;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        if (local_service == 0 || usn == NULL) {
                SSDP_LOGE("Invalid parameter");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
        SSDP_LOGD("SSDP service ID [%u]", local_service);
@@ -602,29 +637,33 @@ EXPORT_API int ssdp_service_set_usn(ssdp_service_h local_service, const char* us
 
        if (!g_is_gssdp_init) {
                SSDP_LOGE("gssdp not initialized");
+               SSDP_UNLOCK;
                return SSDP_ERROR_NOT_INITIALIZED;      //LCOV_EXCL_LINE
        }
 
        service = __ssdp_find_local_service(g_ssdp_local_services, local_service);
        if (service == NULL) {
                SSDP_LOGE("Service not found");
+               SSDP_UNLOCK;
                return SSDP_ERROR_SERVICE_NOT_FOUND;
        }
 
        if (service->origin == SSDP_SERVICE_STATE_REGISTERED) {
                SSDP_LOGE("Already registered");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
 
        if (__ssdp_find_local_service_with_usn(g_ssdp_local_services, usn) != NULL) {
                SSDP_LOGE("Duplicate USN");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
 
        g_free(service->usn);
        service->usn = g_strndup(usn, strlen(usn));
 
-
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
@@ -636,9 +675,11 @@ EXPORT_API int ssdp_service_set_url(ssdp_service_h local_service, const char *ur
        ssdp_service_s *service = NULL;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        if (local_service == 0 || url == NULL) {
                SSDP_LOGE("Invalid parameter");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
        SSDP_LOGD("SSDP service ID [%u]", local_service);
@@ -646,28 +687,33 @@ EXPORT_API int ssdp_service_set_url(ssdp_service_h local_service, const char *ur
 
        if (!g_is_gssdp_init) {
                SSDP_LOGE("gssdp not initialized");
+               SSDP_UNLOCK;
                return SSDP_ERROR_NOT_INITIALIZED;      //LCOV_EXCL_LINE
        }
 
        service = __ssdp_find_local_service(g_ssdp_local_services, local_service);
        if (service == NULL) {
                SSDP_LOGE("Service not found");
+               SSDP_UNLOCK;
                return SSDP_ERROR_SERVICE_NOT_FOUND;
        }
 
        if (service->origin == SSDP_SERVICE_STATE_REGISTERED) {
                SSDP_LOGE("Already registered");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
 
        if (__ssdp_find_local_service_with_url(g_ssdp_local_services, url) != NULL) {
                SSDP_LOGE("Duplicate URL");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
 
        g_free(service->url);
        service->url = g_strndup(url, strlen(url));
 
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
@@ -680,36 +726,43 @@ EXPORT_API int ssdp_service_get_target(ssdp_service_h ssdp_service, char **targe
        char *target_local = NULL;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        if (ssdp_service == 0 || !target) {
                SSDP_LOGE("Invalid parameter");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
        SSDP_LOGD("SSDP service ID [%u]", ssdp_service);
 
        if (!g_is_gssdp_init) {
                SSDP_LOGE("gssdp not initialized");
+               SSDP_UNLOCK;
                return SSDP_ERROR_NOT_INITIALIZED;      //LCOV_EXCL_LINE
        }
 
        service = __ssdp_find_local_service(g_ssdp_local_services, ssdp_service);
-       if (service == NULL)
+       if (service == NULL) {
                service = __ssdp_find_remote_service(g_found_ssdp_services,
                                                                                                ssdp_service);
+       }
 
        if (service == NULL || service->target == NULL) {
                SSDP_LOGE("Service not found");
+               SSDP_UNLOCK;
                return SSDP_ERROR_SERVICE_NOT_FOUND;
        }
 
        target_local = g_strndup(service->target, strlen(service->target));
        if (!target_local) {
                SSDP_LOGE("Failed to get memory for gssdp service type");
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_OUT_OF_MEMORY;        //LCOV_EXCL_LINE
        }
 
        *target = target_local;
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
@@ -722,36 +775,43 @@ EXPORT_API int ssdp_service_get_usn(ssdp_service_h ssdp_service, char **usn)
        char *usn_local = NULL;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        if (ssdp_service == 0 || !usn) {
                SSDP_LOGE("Invalid parameter");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
        SSDP_LOGD("SSDP service ID [%u]", ssdp_service);
 
        if (!g_is_gssdp_init) {
                SSDP_LOGE("gssdp not initialized");
+               SSDP_UNLOCK;
                return SSDP_ERROR_NOT_INITIALIZED;      //LCOV_EXCL_LINE
        }
 
        service = __ssdp_find_local_service(g_ssdp_local_services, ssdp_service);
-       if (service == NULL)
+       if (service == NULL) {
                service = __ssdp_find_remote_service(g_found_ssdp_services,
                                                                                                ssdp_service);
+       }
 
        if (service == NULL || service->usn == NULL) {
                SSDP_LOGE("Service not found");
+               SSDP_UNLOCK;
                return SSDP_ERROR_SERVICE_NOT_FOUND;
        }
 
        usn_local = g_strndup(service->usn, strlen(service->usn));
        if (!usn_local) {
                SSDP_LOGE("Failed to get memory for gssdp service type");
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_OUT_OF_MEMORY;        //LCOV_EXCL_LINE
        }
 
        *usn = usn_local;
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
@@ -764,36 +824,43 @@ EXPORT_API int ssdp_service_get_url(ssdp_service_h ssdp_service, char **url)
        char *url_local = NULL;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        if (ssdp_service == 0 || !url) {
                SSDP_LOGE("Invalid parameter");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
        SSDP_LOGD("SSDP service ID [%u]", ssdp_service);
 
        if (!g_is_gssdp_init) {
                SSDP_LOGE("gssdp not initialized");
+               SSDP_UNLOCK;
                return SSDP_ERROR_NOT_INITIALIZED;      //LCOV_EXCL_LINE
        }
 
        service = __ssdp_find_local_service(g_ssdp_local_services, ssdp_service);
-       if (service == NULL)
+       if (service == NULL) {
                service = __ssdp_find_remote_service(g_found_ssdp_services,
                                                                                                ssdp_service);
+       }
 
        if (service == NULL || service->url == NULL) {
                SSDP_LOGE("Service not found");
+               SSDP_UNLOCK;
                return SSDP_ERROR_SERVICE_NOT_FOUND;
        }
 
        url_local = g_strndup(service->url, strlen(service->url));
        if (!url_local) {
                SSDP_LOGE("Failed to get memory for gssdp service type");
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_OUT_OF_MEMORY;        //LCOV_EXCL_LINE
        }
 
        *url = url_local;
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
@@ -806,31 +873,37 @@ EXPORT_API int ssdp_register_local_service(ssdp_service_h local_service,
        ssdp_service_s *service = NULL;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        if (__ssdp_check_permission() == false) {
                SSDP_LOGE("Permission denied");
+               SSDP_UNLOCK;
                return SSDP_ERROR_PERMISSION_DENIED;
        }
 
        if (local_service == 0) {
                SSDP_LOGE("Invalid parameter");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
        SSDP_LOGD("SSDP service ID [%u]", local_service);
 
        if (!g_is_gssdp_init) {
                SSDP_LOGE("gssdp not initialized");
+               SSDP_UNLOCK;
                return SSDP_ERROR_NOT_INITIALIZED;      //LCOV_EXCL_LINE
        }
 
        service = __ssdp_find_local_service(g_ssdp_local_services, local_service);
        if (service == NULL) {
                SSDP_LOGE("Service not found");
+               SSDP_UNLOCK;
                return SSDP_ERROR_SERVICE_NOT_FOUND;
        }
 
        if (service->origin == SSDP_SERVICE_STATE_REGISTERED) {
                SSDP_LOGE("Already registered");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
 
@@ -844,12 +917,14 @@ EXPORT_API int ssdp_register_local_service(ssdp_service_h local_service,
 
        if (g_gssdp_client == NULL) {
                SSDP_LOGE("GSSDPClient is NULL. Init first");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
 
        service->resource_group = gssdp_resource_group_new(g_gssdp_client);
        if (service->resource_group == NULL) {
                SSDP_LOGE("Resource group is NULL");
+               SSDP_UNLOCK;
                return SSDP_ERROR_OPERATION_FAILED;
        }
 
@@ -861,6 +936,7 @@ EXPORT_API int ssdp_register_local_service(ssdp_service_h local_service,
 
        if (service->resource_id == 0) {
                SSDP_LOGE("Failed to add resource");
+               SSDP_UNLOCK;
                return SSDP_ERROR_OPERATION_FAILED;
        }
 
@@ -873,6 +949,7 @@ EXPORT_API int ssdp_register_local_service(ssdp_service_h local_service,
 
        SSDP_LOGD("Resource group id is [%d]\n", service->resource_id);
 
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
@@ -885,21 +962,25 @@ EXPORT_API int ssdp_deregister_local_service(ssdp_service_h local_service)
        ssdp_service_s *service = NULL;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        if (local_service == 0) {
                SSDP_LOGE("Invalid parameter");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
        SSDP_LOGD("SSDP service ID [%u]", local_service);
 
        if (!g_is_gssdp_init) {
                SSDP_LOGE("gssdp not initialized");
+               SSDP_UNLOCK;
                return SSDP_ERROR_NOT_INITIALIZED;      //LCOV_EXCL_LINE
        }
 
        service = __ssdp_find_local_service(g_ssdp_local_services, local_service);
        if (service == NULL) {
                SSDP_LOGE("Service not found");
+               SSDP_UNLOCK;
                return SSDP_ERROR_SERVICE_NOT_FOUND;
        }
 
@@ -917,6 +998,7 @@ EXPORT_API int ssdp_deregister_local_service(ssdp_service_h local_service)
        service->registered_cb = NULL;
        service->cb_user_data = NULL;
 
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
@@ -929,26 +1011,31 @@ EXPORT_API int ssdp_start_browsing_service(const char* target, ssdp_browser_h* s
        ssdp_service_s *browser = NULL;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        if (__ssdp_check_permission() == false) {
                SSDP_LOGE("Permission denied");
+               SSDP_UNLOCK;
                return SSDP_ERROR_PERMISSION_DENIED;
        }
 
        if (!g_is_gssdp_init) {
                SSDP_LOGE("gssdp not initialized");
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_NOT_INITIALIZED;      //LCOV_EXCL_LINE
        }
 
        if (ssdp_browser == NULL) {
                SSDP_LOGE("Invalid parameter");
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
 
        if (g_gssdp_client == NULL) {
                SSDP_LOGE("GSSDPClient is NULL. Init first");
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
@@ -966,6 +1053,7 @@ GLIST_ITER_END()
                browser = (ssdp_service_s*)g_try_malloc0(sizeof(ssdp_service_s));
                if (!browser) {
                        SSDP_LOGE("Failed to get memory for gssdp service structure");
+                       SSDP_UNLOCK;
                        __SSDP_LOG_FUNC_EXIT__;
                        return SSDP_ERROR_OUT_OF_MEMORY;
                }
@@ -974,6 +1062,7 @@ GLIST_ITER_END()
                if (!browser->target) {
                        SSDP_LOGE("Failed to get memory for gssdp service type");
                        g_free(browser);
+                       SSDP_UNLOCK;
                        __SSDP_LOG_FUNC_EXIT__;
                        return SSDP_ERROR_OUT_OF_MEMORY;
                }
@@ -988,6 +1077,7 @@ GLIST_ITER_END()
                                browser->target);
                if (browser->resource_browser == NULL) {
                        SSDP_LOGE("Failed to create service browser\n");
+                       SSDP_UNLOCK;
                        __SSDP_LOG_FUNC_EXIT__;
                        return SSDP_ERROR_OPERATION_FAILED;
                }
@@ -1007,6 +1097,7 @@ GLIST_ITER_END()
        } else {
                if (!(gssdp_resource_browser_rescan(browser->resource_browser))) {
                        SSDP_LOGE("Failed to request rescan");
+                       SSDP_UNLOCK;
                        __SSDP_LOG_FUNC_EXIT__;
                        return SSDP_ERROR_OPERATION_FAILED;
                }
@@ -1015,6 +1106,7 @@ GLIST_ITER_END()
        browser->found_cb = found_cb;
        browser->cb_user_data = user_data;
 
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
@@ -1026,9 +1118,11 @@ EXPORT_API int ssdp_stop_browsing_service(ssdp_browser_h ssdp_browser)
        ssdp_service_s *browser = NULL;
 
        CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE);
+       SSDP_LOCK;
 
        if (ssdp_browser == 0) {
                SSDP_LOGE("Invalid parameter");
+               SSDP_UNLOCK;
                return SSDP_ERROR_INVALID_PARAMETER;
        }
 
@@ -1036,6 +1130,7 @@ EXPORT_API int ssdp_stop_browsing_service(ssdp_browser_h ssdp_browser)
        browser = __ssdp_find_local_service(g_ssdp_local_services, ssdp_browser);
        if (browser == NULL) {
                SSDP_LOGE("Service not found");
+               SSDP_UNLOCK;
                __SSDP_LOG_FUNC_EXIT__;
                return SSDP_ERROR_SERVICE_NOT_FOUND;
        }
@@ -1057,9 +1152,18 @@ EXPORT_API int ssdp_stop_browsing_service(ssdp_browser_h ssdp_browser)
        g_free(browser->target);
        g_free(browser);
 
+       SSDP_UNLOCK;
        __SSDP_LOG_FUNC_EXIT__;
        return status;
 }
 
+void _ssdp_lock(void)
+{
+       pthread_mutex_lock(&ssdp_mutex);
+}
 
+void _ssdp_unlock(void)
+{
+       pthread_mutex_unlock(&ssdp_mutex);
+}