#include <functional>
#include <limits>
#include <map>
+#include <mutex>
#include <string>
#include <vector>
};
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();
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");
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");
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");
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");
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");
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");
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");
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");
info->callbackId = callbackId;
info->userDefinedRequestId = userRequestId;
data_control_h 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");
+ std::lock_guard<std::mutex> lock(IdMapMutex);
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");
+ std::lock_guard<std::mutex> lock(IdMapMutex);
result = job(handle, &info->requestId);
RETURN_IF_FAIL(result, "Doing job failed with error");