[datacontrol] Fix synchronisation issue 87/245687/4
authork2.nagaraju <k2.nagaraju@samsung.com>
Wed, 14 Oct 2020 07:58:38 +0000 (13:28 +0530)
committerYoungsoo Choi <kenshin.choi@samsung.com>
Mon, 19 Oct 2020 03:09:48 +0000 (03:09 +0000)
k2.nagaraju:
In |RunMAPDataControlJob| updating the |IdMap| value and same value is
used in callback function |MAPAddResponseCallback| for any request id is
added. But before |RunMAPDataControlJob| updating value of |IdMap|,
getting |MAPAddResponseCallback| which is causing the failure with
|Invalid context|. Handled this scenario.

p.wasowski2:
Changed k2.nagaraju's commit a little to conform with the coding used in
the datacontrol module implementation and Web API.

[Verification] No synchronization issues in several runs of WebService2.wgt
app, attached to the related XWALK-2183 task (before, the problem,
signalled by "Invalid context" dlog entry, was reproducible on every run).
tct-datacontrol-tizen-tests: 100% pass rate

Signed-off-by: k2.nagaraju <k2.nagaraju@samsung.com>
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Change-Id: I247aaff45071331255528a62ffc5d8afa4b8e8af

src/datacontrol/datacontrol_instance.cc

index d98aa44..c0a6ba3 100644 (file)
@@ -22,6 +22,7 @@
 #include <functional>
 #include <limits>
 #include <map>
+#include <mutex>
 #include <string>
 #include <vector>
 
@@ -64,6 +65,12 @@ struct DatacontrolInformation {
 };
 
 static std::map<int, DatacontrolInformation*> IdMap;
+/*
+ * IdMap is accessed from the main application (browser) thread and
+ * concurrently from the callbacks, that are run in other threads.
+ * IdMapMutex shall be used to synchronize all the accesses.
+ */
+std::mutex IdMapMutex;
 
 ReplyCallbackData::~ReplyCallbackData() {
   ScopeLogger();
@@ -216,6 +223,8 @@ static bool SQLColumnValue(result_set_cursor cursor, int columnIndex, picojson::
 static void MAPAddResponseCallback(int requestId, data_control_h handle, bool providerResult,
                                    const char* error, void* user_data) {
   ScopeLogger();
+
+  std::lock_guard<std::mutex> lock(IdMapMutex);
   DatacontrolInformation* info = IdMap[requestId];
   if (info == NULL) {
     LoggerE("Invalid context");
@@ -236,6 +245,8 @@ static void MAPAddResponseCallback(int requestId, data_control_h handle, bool pr
 static void MAPSetResponseCallback(int requestId, data_control_h handle, bool providerResult,
                                    const char* error, void* user_data) {
   ScopeLogger();
+
+  std::lock_guard<std::mutex> lock(IdMapMutex);
   DatacontrolInformation* info = IdMap[requestId];
   if (info == NULL) {
     LoggerE("Invalid context");
@@ -257,6 +268,8 @@ static void MAPGetResponseCallback(int requestId, data_control_h handle, char**
                                    int result_value_count, bool providerResult, const char* error,
                                    void* user_data) {
   ScopeLogger();
+
+  std::lock_guard<std::mutex> lock(IdMapMutex);
   DatacontrolInformation* info = IdMap[requestId];
   if (info == NULL) {
     LoggerE("Invalid context");
@@ -283,6 +296,8 @@ static void MAPGetResponseCallback(int requestId, data_control_h handle, char**
 static void MAPRemoveReponseCallback(int requestId, data_control_h handle, bool providerResult,
                                      const char* error, void* user_data) {
   ScopeLogger();
+
+  std::lock_guard<std::mutex> lock(IdMapMutex);
   DatacontrolInformation* info = IdMap[requestId];
   if (info == NULL) {
     LoggerE("Invalid context");
@@ -304,6 +319,8 @@ static void SQLSelectResponseCallback(int requestId, data_control_h handle,
                                       result_set_cursor cursor, bool providerResult,
                                       const char* error, void* user_data) {
   ScopeLogger();
+
+  std::lock_guard<std::mutex> lock(IdMapMutex);
   DatacontrolInformation* info = IdMap[requestId];
   if (info == NULL) {
     LoggerE("Invalid context");
@@ -345,6 +362,8 @@ static void SQLInsertResponseCallback(int requestId, data_control_h handle,
                                       long long inserted_row_id, bool providerResult,
                                       const char* error, void* user_data) {
   ScopeLogger();
+
+  std::lock_guard<std::mutex> lock(IdMapMutex);
   DatacontrolInformation* info = IdMap[requestId];
   if (info == NULL) {
     LoggerE("Invalid context");
@@ -367,6 +386,8 @@ static void SQLInsertResponseCallback(int requestId, data_control_h handle,
 static void SQLUpdateResponseCallback(int requestId, data_control_h handle, bool providerResult,
                                       const char* error, void* user_data) {
   ScopeLogger();
+
+  std::lock_guard<std::mutex> lock(IdMapMutex);
   DatacontrolInformation* info = IdMap[requestId];
   if (info == NULL) {
     LoggerE("Invalid context");
@@ -387,6 +408,8 @@ static void SQLUpdateResponseCallback(int requestId, data_control_h handle, bool
 static void SQLDeleteResponseCallback(int requestId, data_control_h handle, bool providerResult,
                                       const char* error, void* user_data) {
   ScopeLogger();
+
+  std::lock_guard<std::mutex> lock(IdMapMutex);
   DatacontrolInformation* info = IdMap[requestId];
   if (info == NULL) {
     LoggerE("Invalid context");
@@ -428,7 +451,6 @@ int DatacontrolInstance::RunMAPDataControlJob(const std::string& providerId,
   info->callbackId = callbackId;
   info->userDefinedRequestId = userRequestId;
   data_control_h handle;
-
   SCOPE_EXIT {
     ::data_control_map_destroy(handle);
   };
@@ -445,6 +467,7 @@ int DatacontrolInstance::RunMAPDataControlJob(const std::string& providerId,
   result = ::data_control_map_register_response_cb(handle, &mapResponseCallback, this);
   RETURN_IF_FAIL(result, "Setting result Callback failed with error");
 
+  std::lock_guard<std::mutex> lock(IdMapMutex);
   result = job(handle, &info->requestId);
   RETURN_IF_FAIL(result, "Doing job failed with error");
 
@@ -478,6 +501,7 @@ int DatacontrolInstance::RunSQLDataControlJob(const std::string& providerId,
   result = ::data_control_sql_register_response_cb(handle, &sqlResponseCallback, this);
   RETURN_IF_FAIL(result, "Setting result Callback failed with error");
 
+  std::lock_guard<std::mutex> lock(IdMapMutex);
   result = job(handle, &info->requestId);
   RETURN_IF_FAIL(result, "Doing job failed with error");