Fix invalid memory access on resource cache module.
authorjyong2.kim <jyong2.kim@samsung.com>
Wed, 29 Jul 2015 10:52:48 +0000 (19:52 +0900)
committerUze Choi <uzchoi@samsung.com>
Wed, 29 Jul 2015 20:56:15 +0000 (20:56 +0000)
invalidate callback in deleted instance.

Change-Id: Ica3028700935c0cef062719a43affc5f4754a336
Signed-off-by: jyong2.kim <jyong2.kim@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1972
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Younghyun Joo <yh_.joo@samsung.com>
Reviewed-by: Uze Choi <uzchoi@samsung.com>
service/resource-encapsulation/src/resourceCache/include/DataCache.h
service/resource-encapsulation/src/resourceCache/src/DataCache.cpp

index 3e20f54..820960a 100644 (file)
@@ -33,7 +33,7 @@ namespace OIC
 {
     namespace Service
     {
-        class DataCache
+        class DataCache : public std::enable_shared_from_this<DataCache>
         {
             public:
                 typedef unsigned int TimerID;
@@ -66,6 +66,7 @@ namespace OIC
 
                 // subscriber info
                 std::unique_ptr<SubscriberInfo> subscriberList;
+                mutable std::mutex m_mutex;
 
                 ExpiryTimer networkTimer;
                 ExpiryTimer pollingTimer;
@@ -77,18 +78,17 @@ namespace OIC
                 TimerCB pTimerCB;
                 TimerCB pPollingCB;
 
-                // for requestCB from base
+            public:
                 void onObserve(const HeaderOptions &_hos,
                                const ResponseStatement &_rep, int _result, int _seq);
                 void onGet(const HeaderOptions &_hos, const ResponseStatement &_rep, int _result);
+            private:
                 void onTimeOut(const unsigned int timerID);
                 void onPollingOut(const unsigned int timerID);
 
                 CacheID generateCacheID();
                 SubscriberInfoPair findSubscriber(CacheID id);
                 void notifyObservers(const RCSResourceAttributes Att);
-
-                mutable std::mutex m_mutex;
         };
     } // namespace Service
 } // namespace OIC
index eac00e9..4def52c 100644 (file)
@@ -35,6 +35,47 @@ namespace OIC
 {
     namespace Service
     {
+
+        namespace
+        {
+            std::mutex cbMutex;
+            void vertifyObserveCB(
+                const HeaderOptions &_hos, const ResponseStatement &_rep,
+                int _result, int _seq, std::weak_ptr<DataCache> rpPtr)
+            {
+                std::lock_guard<std::mutex> lock(cbMutex);
+                std::shared_ptr<DataCache> Ptr = rpPtr.lock();
+                if(Ptr)
+                {
+                    Ptr->onObserve(_hos, _rep, _result, _seq);
+                }
+            }
+            ObserveCB vertifiedObserveCB(std::weak_ptr<DataCache> rpPtr)
+            {
+                return std::bind(vertifyObserveCB,
+                        std::placeholders::_1, std::placeholders::_2,
+                        std::placeholders::_3, std::placeholders::_4, rpPtr);
+            }
+
+            void vertifyGetCB(
+                    const HeaderOptions &_hos, const ResponseStatement &_rep,
+                    int _result, std::weak_ptr<DataCache> rpPtr)
+            {
+                std::lock_guard<std::mutex> lock(cbMutex);
+                std::shared_ptr<DataCache> Ptr = rpPtr.lock();
+                if(Ptr)
+                {
+                    Ptr->onGet(_hos, _rep, _result);
+                }
+            }
+            GetCB vertifiedGetCB(std::weak_ptr<DataCache> rpPtr)
+            {
+                return std::bind(vertifyGetCB,
+                        std::placeholders::_1, std::placeholders::_2,
+                        std::placeholders::_3, rpPtr);
+            }
+        }
+
         DataCache::DataCache()
         {
             subscriberList = std::unique_ptr<SubscriberInfo>(new SubscriberInfo());
@@ -46,15 +87,6 @@ namespace OIC
 
             networkTimeOutHandle = 0;
             pollingHandle = 0;
-
-            pObserveCB = (ObserveCB)(std::bind(&DataCache::onObserve, this,
-                                               std::placeholders::_1, std::placeholders::_2,
-                                               std::placeholders::_3, std::placeholders::_4));
-            pGetCB = (GetCB)(std::bind(&DataCache::onGet, this,
-                                       std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
-            pTimerCB = (TimerCB)(std::bind(&DataCache::onTimeOut, this, std::placeholders::_1));
-            pPollingCB = (TimerCB)(std::bind(&DataCache::onPollingOut, this, std::placeholders::_1));
-
         }
 
         DataCache::~DataCache()
@@ -82,6 +114,10 @@ namespace OIC
         void DataCache::initializeDataCache(PrimitiveResourcePtr pResource)
         {
             sResource = pResource;
+            pObserveCB = vertifiedObserveCB(std::weak_ptr<DataCache>(shared_from_this()));
+            pGetCB = vertifiedGetCB(std::weak_ptr<DataCache>(shared_from_this()));
+            pTimerCB = (TimerCB)(std::bind(&DataCache::onTimeOut, this, std::placeholders::_1));
+            pPollingCB = (TimerCB)(std::bind(&DataCache::onPollingOut, this, std::placeholders::_1));
 
             sResource->requestGet(pGetCB);
             if (sResource->isObservable())
@@ -197,7 +233,7 @@ namespace OIC
                 state = CACHE_STATE::READY;
             }
 
-            if (!sResource->isObservable())
+            if (mode != CACHE_MODE::OBSERVE)
             {
                 networkTimer.cancelTimer(networkTimeOutHandle);
                 networkTimeOutHandle = networkTimer.postTimer(
@@ -235,8 +271,20 @@ namespace OIC
 
         void DataCache::onTimeOut(unsigned int timerID)
         {
+            if(mode == CACHE_MODE::OBSERVE)
+            {
+                sResource->cancelObserve();
+                mode = CACHE_MODE::FREQUENCY;
+
+                networkTimer.cancelTimer(networkTimeOutHandle);
+                networkTimeOutHandle = networkTimer.postTimer(
+                        CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
+
+                pollingHandle = pollingTimer.postTimer(CACHE_DEFAULT_REPORT_MILLITIME, pPollingCB);
+                return;
+            }
+
             state = CACHE_STATE::LOST_SIGNAL;
-            return;
         }
         void DataCache::onPollingOut(const unsigned int timerID)
         {