[CONPRO-1429] 100% CPU usage by iotivity stack 44/208344/1
authorsourav bhuwalka <s.bhuwalka@samsung.com>
Mon, 3 Jun 2019 07:16:47 +0000 (12:46 +0530)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Mon, 24 Jun 2019 00:49:39 +0000 (09:49 +0900)
Here before the max number of observers was 255 and when more
than 255 observers were there an infinite loop was running.
Increasing the number of observers and changing the logic so
that infinite loop should not be run when observer count reaches
max number of observers.

https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/commit/3f9cb8af60cd5ed929ed876d95e82f2650309f9c
(cherry picked from 3f9cb8af60cd5ed929ed876d95e82f2650309f9c)

Change-Id: Ib0bb86817d2dbf8c2d5f5806cb49ffa2e002cd21
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
resource/c_common/ocrandom/include/ocrandom.h
resource/c_common/ocrandom/src/ocrandom.c
resource/csdk/stack/include/internal/ocobserve.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/src/ocobserve.c
service/notification/src/provider/NSProviderNotification.c
service/notification/src/provider/NSProviderTopic.c

index d4af63436e4d17e5197133c77889e82f57d9c5d4..a531c7069fb3567328830f1b10ffce50881be26c 100644 (file)
@@ -66,6 +66,12 @@ uint32_t OCGetRandom();
  */
 uint8_t OCGetRandomByte(void);
 
+/**
+ * Generate a uniformly [0,2^16] distributed random number
+ * @retval On Success, it returns the random value, otherwise -1 for error.
+ */
+uint16_t OCGetRandomTwoByte(void);
+
 /**
  * Generate a uniformly distributed 8-bit (byte) array random numbers
  * @param[out] location
index c7c7e090115a4f686e33c600d7b2e15201cee1ae..1c43edbfe26a170128c5231e916625c5a5a01bd1 100644 (file)
@@ -227,6 +227,16 @@ uint8_t OCGetRandomByte(void)
 #endif
 }
 
+uint16_t OCGetRandomTwoByte(void)
+{
+#ifdef HAVE_SRANDOM
+    return random() & 0x00FFFF;
+#else
+    return rand() & 0x00FFFF;
+#endif
+}
+
+
 uint32_t OCGetRandomRange(uint32_t firstBound, uint32_t secondBound)
 {
     uint32_t base;
index f5fc6c1f6416bfddecda909a360aa75ba1c6bf09..018ee7cb8d4ae6cd0f3a0f67724ae6f892edbae8 100644 (file)
@@ -150,7 +150,7 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
 OCStackResult SendListObserverNotification (OCResource * resource,
-        OCObservationId  *obsIdList, uint8_t numberOfIds,
+        OCObservationId  *obsIdList, uint16_t numberOfIds,
         const OCRepPayload *payload, uint32_t maxAge,
         OCQualityOfService qos);
 
index a7e6dbfcb4b252329b9c3bc8762859bd9af1ba01..8187b884f7afb7525ae44554f96692648535102a 100644 (file)
@@ -1063,9 +1063,9 @@ typedef uint32_t OCRequestHandle;
  * Unique identifier for each observation request. Used when observations are
  * registered or de-registered. Used by entity handler to signal specific
  * observers to be notified of resource changes.
- * There can be maximum of 256 observations per server.
+ * There can be maximum of 3840 observations per server.
  */
-typedef uint8_t OCObservationId;
+typedef uint16_t OCObservationId;
 
 /**
  * Sequence number is a 24 bit field,
index 18de8c68baaf902f4d529fa0e3c73d38bdb66dfe..7495f2b4b12882f8449566516920522ce19c5396 100644 (file)
 
 #define VERIFY_NON_NULL(arg) { if (!arg) {OIC_LOG(FATAL, TAG, #arg " is NULL"); goto exit;} }
 
+#define MAX_OBSERVERS 3840
+
 static struct ResourceObserver * g_serverObsList = NULL;
 static oc_mutex g_serverObsListMutex = NULL;
 
+static int observer_count = 0;
+
 static ResourceObserver* GetObserverUsingIdAsOwner (const OCObservationId observeId);
 
 static ResourceObserver* CloneObserverNode (ResourceObserver* observer)
@@ -255,7 +259,7 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
 
     OCStackResult result = OC_STACK_ERROR;
     ResourceObserver * resourceObserver = NULL;
-    uint8_t numObs = 0;
+    uint16_t numObs = 0;
     OCServerRequest * request = NULL;
     bool observeErrorFlag = false;
 
@@ -347,7 +351,7 @@ OCStackResult SendAllObserverNotification (OCMethod method, OCResource *resPtr,
 }
 
 OCStackResult SendListObserverNotification (OCResource * resource,
-        OCObservationId  *obsIdList, uint8_t numberOfIds,
+        OCObservationId  *obsIdList, uint16_t numberOfIds,
         const OCRepPayload *payload,
         uint32_t maxAge,
         OCQualityOfService qos)
@@ -358,9 +362,9 @@ OCStackResult SendListObserverNotification (OCResource * resource,
         return OC_STACK_INVALID_PARAM;
     }
 
-    uint8_t numIds = numberOfIds;
+    uint16_t numIds = numberOfIds;
     ResourceObserver *observer = NULL;
-    uint8_t numSentNotification = 0;
+    uint16_t numSentNotification = 0;
     OCServerRequest * request = NULL;
     OCStackResult result = OC_STACK_ERROR;
     bool observeErrorFlag = false;
@@ -464,19 +468,32 @@ OCStackResult GenerateObserverId (OCObservationId *observationId)
     OIC_LOG(INFO, TAG, "Entering GenerateObserverId");
     VERIFY_NON_NULL (observationId);
 
-    do
+    oc_mutex_lock(g_serverObsListMutex);
+
+    if (observer_count < MAX_OBSERVERS)
     {
+        oc_mutex_unlock(g_serverObsListMutex);
         do
         {
-            *observationId = OCGetRandomByte();
-        } while (0 == *observationId); //Make sure *observationId is not 0
-        // Check if observation Id already exists
-        found = IsObserverAvailable (*observationId);
-    } while (found);
-
+            do
+            {
+                *observationId = OCGetRandomTwoByte();
+            } while (0 == *observationId); //Make sure *observationId is not 0
+            // Check if observation Id already exists
+            found = IsObserverAvailable (*observationId);
+        } while (found);
     OIC_LOG_V(INFO, TAG, "GeneratedObservation ID is %u", *observationId);
+    //oc_mutex_unlock(g_serverObsListMutex);
 
     return OC_STACK_OK;
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "No more observers can be added");
+        oc_mutex_unlock(g_serverObsListMutex);
+
+        return OC_STACK_ERROR;
+    }
 exit:
     return OC_STACK_ERROR;
 }
@@ -547,6 +564,7 @@ OCStackResult AddObserver (const char         *resUri,
 
         oc_mutex_lock(g_serverObsListMutex);
         LL_APPEND (g_serverObsList, obsNode);
+        observer_count++;
         oc_mutex_unlock(g_serverObsListMutex);
 
         return OC_STACK_OK;
@@ -728,6 +746,7 @@ OCStackResult DeleteObserverUsingToken (CAToken_t token, uint8_t tokenLength)
         OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)obsNode->token, tokenLength);
 
         LL_DELETE (g_serverObsList, obsNode);
+        observer_count--;
         FreeObserver(obsNode);
     }
     oc_mutex_unlock(g_serverObsListMutex);
index 01191164e8294df50d15290c817c3fd63c5929ed..74708dff13b095dbfe2908af8f83b0f600dff52f 100644 (file)
@@ -108,7 +108,7 @@ NSResult NSSendNotification(NSMessage *msg)
     NS_LOG(DEBUG, "NSSendMessage - IN");
 
     OCResourceHandle rHandle;
-    OCObservationId obArray[255] = { 0, };
+    OCObservationId obArray[3839] = { 0, };
     int obCount = 0, i;
 
     if (NSPutMessageResource(msg, &rHandle) != NS_OK)
@@ -232,7 +232,7 @@ NSResult NSSendSync(NSSyncInfo *sync)
 {
     NS_LOG(DEBUG, "NSSendSync - IN");
 
-    OCObservationId obArray[255] = { 0, };
+    OCObservationId obArray[3839] = { 0, };
     int obCount = 0;
     int i;
 
index f6aa8e9410f2cf48499caaaee3345ad3a17535f6..9a6dee9a3cb0c68df279ca8915c78892a80d9c47 100644 (file)
@@ -143,7 +143,7 @@ NSResult NSSendTopicUpdation()
     OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, NS_TOPIC);
     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);
 
-    OCObservationId obArray[255] =
+    OCObservationId obArray[3839] =
     { 0, };
     int obCount = 0;