Fix answer callback call in asynchronous client 91/30291/9
authorMarcin Niesluchowski <m.niesluchow@samsung.com>
Wed, 12 Nov 2014 12:41:43 +0000 (13:41 +0100)
committerLukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Fri, 14 Nov 2014 22:02:20 +0000 (14:02 -0800)
Answer callback may modify check map by calling async client api functions
within it. Check map is accessed after that call.

Change-Id: Ifbf91f99cfa119e5524457f585b2779d7ae52558

src/client-async/callback/ResponseCallback.cpp
src/client-async/callback/ResponseCallback.h
src/client-async/check/CheckData.h
src/client-async/logic/Logic.cpp
src/common/types/PolicyKey.h

index 9307195..f904483 100644 (file)
@@ -28,6 +28,12 @@ ResponseCallback::ResponseCallback(cynara_response_callback callback, void *user
     : m_callback(callback), m_userData(userData) {
 }
 
+ResponseCallback::ResponseCallback(ResponseCallback &&other)
+    : m_callback(other.m_callback), m_userData(other.m_userData) {
+    other.m_callback = nullptr;
+    other.m_userData = nullptr;
+}
+
 void ResponseCallback::onAnswer(cynara_check_id checkId, int response) const {
     if (!m_callback)
         return;
index 925d7f4..1af7291 100644 (file)
@@ -31,6 +31,7 @@ class ResponseCallback {
 public:
     ResponseCallback(cynara_response_callback callback, void *userData);
     ResponseCallback(const ResponseCallback&) = default;
+    ResponseCallback(ResponseCallback &&other);
     ~ResponseCallback() {};
 
     void onAnswer(cynara_check_id checkId, int response) const;
index a25abb3..453af76 100644 (file)
@@ -38,6 +38,11 @@ class CheckData
 public:
     CheckData(const PolicyKey &key, const std::string &session, const ResponseCallback &callback)
         : m_key(key), m_session(session), m_callback(callback),  m_cancelled(false) {}
+    CheckData(CheckData &&other)
+        : m_key(std::move(other.m_key)), m_session(std::move(other.m_session)),
+          m_callback(std::move(other.m_callback)), m_cancelled(other.m_cancelled) {
+        other.m_cancelled = false;
+    }
     ~CheckData() {}
 
     const PolicyKey &key(void) const {
index bfb494c..9725d64 100644 (file)
@@ -166,10 +166,12 @@ void Logic::processCheckResponse(CheckResponsePtr checkResponse) {
     }
     int result = m_cache->update(it->second.session(), it->second.key(),
                                  checkResponse->m_resultRef);
-    if (!it->second.cancelled())
-        it->second.callback().onAnswer(static_cast<cynara_check_id>(it->first), result);
+    CheckData checkData(std::move(it->second));
     m_sequenceContainer.release(it->first);
     m_checks.erase(it);
+    if (!checkData.cancelled())
+        checkData.callback().onAnswer(
+            static_cast<cynara_check_id>(checkResponse->sequenceNumber()), result);
 }
 
 void Logic::processCancelResponse(CancelResponsePtr cancelResponse) {
index 6bf0302..3f65c58 100644 (file)
@@ -36,6 +36,9 @@ class PolicyKeyFeature {
 friend class PolicyKey;
 
 public:
+    PolicyKeyFeature(const PolicyKeyFeature &) = default;
+    PolicyKeyFeature(PolicyKeyFeature &&) = default;
+
     typedef std::string ValueType;
 
     static PolicyKeyFeature create(ValueType value) {
@@ -98,6 +101,9 @@ public:
             const PolicyKeyFeature::ValueType &privilegeId)
         : m_client(clientId), m_user(userId), m_privilege(privilegeId) {};
 
+    PolicyKey(const PolicyKey &) = default;
+    PolicyKey(PolicyKey &&) = default;
+
     bool operator==(const PolicyKey &other) const {
         return std::tie(m_client, m_user, m_privilege)
             == std::tie(other.m_client, other.m_user, other.m_privilege);