Introduce VineMap for synchronized map 22/265422/4
authorcheoleun moon <chleun.moon@samsung.com>
Tue, 19 Oct 2021 05:55:31 +0000 (14:55 +0900)
committercheoleun moon <chleun.moon@samsung.com>
Tue, 19 Oct 2021 08:17:20 +0000 (17:17 +0900)
Change-Id: I9f8940cef3fe8a8079bf30760e938099aaa464fb

plugins/dns-sd/dns-sd-plugin.cpp
src/include/vine-map.h [new file with mode: 0755]

index 0c6291d..5d8f5a9 100755 (executable)
@@ -26,6 +26,7 @@
 #include "vine-constants.h"
 #include "vine-disc-plugin.h"
 #include "vine-log.h"
+#include "vine-map.h"
 #include "vine-utils.h"
 #include "dns-sd-plugin.h"
 
@@ -37,7 +38,7 @@ typedef struct {
        int fd;
        void *user_data;        // vine_disc handle
        char service_type[VINE_MAX_SERVICE_TYPE_LEN + 1];
-       map<int, DNSServiceRef> sdref_map; // <fd, DNSServiceRef>
+       VineMap<int, DNSServiceRef> sdref_map; // <fd, DNSServiceRef>
 
        DNSServiceRef get_addr_ref; // Used for only resolve_ip
 } vine_dns_sd_s;
@@ -45,7 +46,7 @@ typedef struct {
 typedef struct {
        char service_type[VINE_MAX_SERVICE_TYPE_LEN + 1];
        char service_name[VINE_MAX_SERVICE_NAME_LEN + 1];
-       map<string, string> attributes;
+       std::map<string, string> attributes;
        int port;
        vine_dns_sd_s *dns_sd_handle;
 } dns_sd_discovered_service_s;
@@ -150,8 +151,8 @@ void add_new_fd(vine_dns_sd_s *dns_sd_handle,
        int fd = DNSServiceRefSockFD(service_ref);
        VINE_LOGD("Insert new service ref[%p] fd[%d]", service_ref, fd);
 
-       if (dns_sd_handle->sdref_map.find(fd) == dns_sd_handle->sdref_map.end()) {
-               dns_sd_handle->sdref_map[fd] = service_ref;
+       if (!dns_sd_handle->sdref_map.find(fd)) {
+               dns_sd_handle->sdref_map.insert(fd, service_ref);
                VINE_LOGD("New fd[%d] to be added", fd);
        } else {
                VINE_LOGI("Duplicate fd[%d]", fd);
@@ -182,17 +183,14 @@ static void __remove_service_ref(vine_dns_sd_s *dns_sd_handle, DNSServiceRef ser
 static void __remove_service_ref_all(vine_dns_sd_s *dns_sd_handle)
 {
        VINE_LOGD("Remove all DNSServiceRef for dns_sd_handle[%p]", dns_sd_handle);
-       for (auto iter = dns_sd_handle->sdref_map.begin();
-                       iter != dns_sd_handle->sdref_map.end(); ++iter) {
-               int fd = iter->first;
-               DNSServiceRef service_ref = iter->second;
+       dns_sd_handle->sdref_map.for_each([&](int fd, DNSServiceRef service_ref) {
+                               if (event_callbacks.fd_removed_cb)
+                                       event_callbacks.fd_removed_cb(fd, dns_sd_handle->user_data);
+                               DNSServiceRefDeallocate(service_ref);
 
-               if (event_callbacks.fd_removed_cb)
-                       event_callbacks.fd_removed_cb(fd, dns_sd_handle->user_data);
-               DNSServiceRefDeallocate(service_ref);
+                               VINE_LOGD("fd[%d]/service_ref[%p] is removed.", fd, service_ref);
+                       });
 
-               VINE_LOGD("fd[%d]/service_ref[%p] is removed.", fd, service_ref);
-       }
        dns_sd_handle->sdref_map.clear();
 }
 
@@ -499,11 +497,12 @@ void dns_sd_deinit(void *plugin_handle)
        RET_IF(plugin_handle == NULL, "Plugin handle is null");
        vine_dns_sd_s *dns_sd_handle = (vine_dns_sd_s *)plugin_handle;
 
-       auto it = dns_sd_handle->sdref_map.begin();
-       while (it != dns_sd_handle->sdref_map.end()) {
-               DNSServiceRefDeallocate(it->second);
-               it = dns_sd_handle->sdref_map.erase(it);
-       }
+       dns_sd_handle->sdref_map.for_each([&](int fd, DNSServiceRef service_ref) {
+                               DNSServiceRefDeallocate(service_ref);
+                               VINE_LOGD("fd[%d]/service_ref[%p] is removed.", fd, service_ref);
+                       });
+
+       dns_sd_handle->sdref_map.clear();
 
        delete dns_sd_handle;
 }
@@ -610,9 +609,9 @@ vine_disc_error dns_sd_process_event(void *plugin_handle, int fd)
        RET_VAL_IF(!plugin_handle, VINE_DISC_ERROR_INVALID_PARAMETER, "plugin_handle is NULL");
        vine_dns_sd_s *dns_sd_handle = (vine_dns_sd_s *)plugin_handle;
 
-       DNSServiceRef service_ref = dns_sd_handle->sdref_map[fd];
-       RET_VAL_IF(service_ref == NULL, VINE_DISC_ERROR_INVALID_PARAMETER,
+       RET_VAL_IF(!dns_sd_handle->sdref_map.find(fd), VINE_DISC_ERROR_INVALID_PARAMETER,
                        "No DNSServiceRef for fd");
+       DNSServiceRef service_ref = dns_sd_handle->sdref_map.at(fd);
        VINE_LOGD("service ref[%p] to be processed", service_ref);
        DNSServiceErrorType err = DNSServiceProcessResult(service_ref);
        if (err) {
diff --git a/src/include/vine-map.h b/src/include/vine-map.h
new file mode 100755 (executable)
index 0000000..12e79a8
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+#pragma once
+
+#include <functional>
+#include <mutex>
+#include <map>
+
+#include "vine-log.h"
+
+template <typename K, typename V>
+class VineMap
+{
+public:
+       VineMap()
+       {
+               VINE_LOGD("New Map");
+       }
+       virtual ~VineMap()
+       {
+               VINE_LOGD("Destroy Map");
+       }
+
+       // If the key of the inserted element already exists in the internal map,
+       // the element is not inserted.
+       void insert(const K &key, const V &val)
+       {
+               std::lock_guard<std::mutex> lock_guard(_q_mutex);
+               _map.insert(std::pair<K, V>(key, val));
+       }
+
+       const V &at(const K &key)
+       {
+               std::lock_guard<std::mutex> lock_guard(_q_mutex);
+               return _map.at(key);
+       }
+
+       bool find(const K &key)
+       {
+               std::lock_guard<std::mutex> lock_guard(_q_mutex);
+               return _map.find(key) != _map.end();
+       }
+
+       void erase(const K &key)
+       {
+               std::lock_guard<std::mutex> lock_guard(_q_mutex);
+               _map.erase(key);
+       }
+
+       void clear()
+       {
+               std::lock_guard<std::mutex> lock_guard(_q_mutex);
+               _map.clear();
+       }
+
+       // The protyotype of do_func(): void func(K &k, V & v)
+       template <class BinaryPredicate> void for_each(BinaryPredicate do_func)
+       {
+               for (auto it = _map.begin(); it != _map.end(); ++it)
+                       do_func(it->first, it->second);
+       }
+
+private:
+       std::map<K, V> _map;
+       std::mutex _q_mutex;
+};