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
#include <functional>
#include <limits>
#include <map>
#include <functional>
#include <limits>
#include <map>
#include <string>
#include <vector>
#include <string>
#include <vector>
};
static std::map<int, DatacontrolInformation*> IdMap;
};
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();
ReplyCallbackData::~ReplyCallbackData() {
ScopeLogger();
static void MAPAddResponseCallback(int requestId, data_control_h handle, bool providerResult,
const char* error, void* user_data) {
ScopeLogger();
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");
DatacontrolInformation* info = IdMap[requestId];
if (info == NULL) {
LoggerE("Invalid context");
static void MAPSetResponseCallback(int requestId, data_control_h handle, bool providerResult,
const char* error, void* user_data) {
ScopeLogger();
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");
DatacontrolInformation* info = IdMap[requestId];
if (info == NULL) {
LoggerE("Invalid context");
int result_value_count, bool providerResult, const char* error,
void* user_data) {
ScopeLogger();
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");
DatacontrolInformation* info = IdMap[requestId];
if (info == NULL) {
LoggerE("Invalid context");
static void MAPRemoveReponseCallback(int requestId, data_control_h handle, bool providerResult,
const char* error, void* user_data) {
ScopeLogger();
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");
DatacontrolInformation* info = IdMap[requestId];
if (info == NULL) {
LoggerE("Invalid context");
result_set_cursor cursor, bool providerResult,
const char* error, void* user_data) {
ScopeLogger();
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");
DatacontrolInformation* info = IdMap[requestId];
if (info == NULL) {
LoggerE("Invalid context");
long long inserted_row_id, bool providerResult,
const char* error, void* user_data) {
ScopeLogger();
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");
DatacontrolInformation* info = IdMap[requestId];
if (info == NULL) {
LoggerE("Invalid context");
static void SQLUpdateResponseCallback(int requestId, data_control_h handle, bool providerResult,
const char* error, void* user_data) {
ScopeLogger();
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");
DatacontrolInformation* info = IdMap[requestId];
if (info == NULL) {
LoggerE("Invalid context");
static void SQLDeleteResponseCallback(int requestId, data_control_h handle, bool providerResult,
const char* error, void* user_data) {
ScopeLogger();
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");
DatacontrolInformation* info = IdMap[requestId];
if (info == NULL) {
LoggerE("Invalid context");
info->callbackId = callbackId;
info->userDefinedRequestId = userRequestId;
data_control_h handle;
info->callbackId = callbackId;
info->userDefinedRequestId = userRequestId;
data_control_h handle;
SCOPE_EXIT {
::data_control_map_destroy(handle);
};
SCOPE_EXIT {
::data_control_map_destroy(handle);
};
result = ::data_control_map_register_response_cb(handle, &mapResponseCallback, this);
RETURN_IF_FAIL(result, "Setting result Callback failed with error");
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");
result = job(handle, &info->requestId);
RETURN_IF_FAIL(result, "Doing job failed with error");
result = ::data_control_sql_register_response_cb(handle, &sqlResponseCallback, this);
RETURN_IF_FAIL(result, "Setting result Callback failed with error");
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");
result = job(handle, &info->requestId);
RETURN_IF_FAIL(result, "Doing job failed with error");