Modify Logic for unsubscribing all provider.
authorYounghyunJoo <yh_.joo@samsung.com>
Thu, 21 Jul 2016 10:47:20 +0000 (19:47 +0900)
committerUze Choi <uzchoi@samsung.com>
Fri, 22 Jul 2016 08:19:50 +0000 (08:19 +0000)
when consumer service stop, unsubscribes all provider.
and when user call APIs, check the service is enabled.

Conflicts:
        service/notification/examples/linux/notificationconsumer.c

Change-Id: Ib065b4c0644c0241fd4866119f0d209be360e352
Signed-off-by: YounghyunJoo <yh_.joo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/9495
Reviewed-by: Uze Choi <uzchoi@samsung.com>
Tested-by: Uze Choi <uzchoi@samsung.com>
service/notification/examples/linux/notificationconsumer.c
service/notification/src/consumer/NSConsumerInterface.c
service/notification/src/consumer/NSConsumerInternalTaskController.c
service/notification/src/consumer/NSConsumerInternalTaskController.h
service/notification/src/consumer/NSConsumerScheduler.c
service/notification/src/consumer/cache/linux/NSConsumerMemoryCache.c
service/notification/src/consumer/cache/linux/NSConsumerMemoryCache.h

index 4d72807..082de18 100644 (file)
@@ -1,5 +1,26 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
 #include <stdio.h>
 #include <unistd.h>
+#include "pthread.h"
 
 #include "ocstack.h"
 #include "NSCommon.h"
@@ -46,6 +67,7 @@ void onNotificationSync(NSSyncInfo * sync)
     printf("Sync STATE : %d\n", sync->state);
 }
 
+
 #ifdef WITH_CLOUD
 OCStackApplicationResult handleLoginoutCB(void *ctx,
         OCDoHandle handle,
@@ -86,8 +108,27 @@ OCStackApplicationResult handleLoginoutCB(void *ctx,
 }
 #endif
 
+void* OCProcessThread(void * ptr)
+{
+    (void) ptr;
+
+    while (true)
+    {
+        usleep(2000);
+        if(OCProcess() != OC_STACK_OK)
+        {
+            OCStop();
+            break;
+        }
+    }
+
+    return NULL;
+}
+
 int main(void)
 {
+    bool isExit = false;
+    pthread_t OCThread;
 
     printf("start Iotivity\n");
     if (OCInit1(OC_CLIENT, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS) != OC_STACK_OK)
@@ -102,27 +143,47 @@ int main(void)
     cfg.messageCb = onNotificationPosted;
     cfg.syncInfoCb = onNotificationSync;
 
-
-    printf("start notification consumer service\n");
-    NSResult ret = NSStartConsumer(cfg);
-    if(ret != NS_OK)
-    {
-        printf("error discoverNoti %d\n", ret);
-    }
-
 #ifdef WITH_CLOUD
     NS_LOG(DEBUG, "process OCCloudLogin...");
     OCCloudLogin(CLOUD_HOST_ADDRESS, CLOUD_IOTIVITYNS_SESSION, handleLoginoutCB);
     NS_LOG(DEBUG, "OCCloudLogin return");
 #endif
 
-    while (true)
+    pthread_create(&OCThread, NULL, OCProcessThread, NULL);
+
+    printf("start notification consumer service\n");
+    while (!isExit)
     {
-        usleep(2000);
-        if(OCProcess() != OC_STACK_OK)
+        int num;
+        char dummy;
+
+        printf("1. Start Consumer\n");
+        printf("2. Stop Consumer\n");
+        printf("5. Exit\n");
+
+        printf("Input: ");
+
+        scanf("%d", &num);
+        fflush(stdin);
+        scanf("%c", &dummy);
+        fflush(stdin);
+
+        switch (num)
         {
-            OCStop();
-            break;
+            case 1:
+                printf("1. Start Consumer\n");
+                NSStartConsumer(cfg);
+                break;
+            case 2:
+                printf("2. Stop Consumer");
+                NSStopConsumer();
+                break;
+            case 5:
+                printf("5. Exit");
+                isExit = true;
+                break;
+            default:
+                break;
         }
     }
 
index 60cf0c3..1402248 100644 (file)
@@ -56,6 +56,9 @@ NSResult NSStartConsumer(NSConsumerConfig config)
 
 NSResult NSStopConsumer()
 {
+    bool isStartedConsumer = NSIsStartedConsumer();
+    NS_VERIFY_NOT_NULL(isStartedConsumer == true ? (void *) 1 : NULL, NS_ERROR);
+
     NSSetDiscoverProviderCb(NULL);
     NSSetMessagePostedCb(NULL);
     NSSetNotificationSyncCb(NULL);
@@ -69,6 +72,9 @@ NSResult NSStopConsumer()
 
 NSResult NSConsumerEnableRemoteService(char *serverAddress)
 {
+    bool isStartedConsumer = NSIsStartedConsumer();
+    NS_VERIFY_NOT_NULL(isStartedConsumer == true ? (void *) 1 : NULL, NS_ERROR);
+
     NSTask * discoverTask = NSMakeTask(TASK_CONSUMER_REQ_DISCOVER, (void *)serverAddress);
     NS_VERIFY_NOT_NULL(discoverTask, NS_ERROR);
 
@@ -77,6 +83,9 @@ NSResult NSConsumerEnableRemoteService(char *serverAddress)
 
 NSResult NSSubscribe(NSProvider * provider)
 {
+    bool isStartedConsumer = NSIsStartedConsumer();
+    NS_VERIFY_NOT_NULL(isStartedConsumer == true ? (void *) 1 : NULL, NS_ERROR);
+
     NSTask * subscribeTask = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE, (void *) provider);
     NS_VERIFY_NOT_NULL(subscribeTask, NS_ERROR);
 
@@ -85,6 +94,9 @@ NSResult NSSubscribe(NSProvider * provider)
 
 NSResult NSUnsubscribe(NSProvider * provider)
 {
+    bool isStartedConsumer = NSIsStartedConsumer();
+    NS_VERIFY_NOT_NULL(isStartedConsumer == true ? (void *) 1 : NULL, NS_ERROR);
+
     NSTask * unsubscribeTask = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL, (void *) provider);
     NS_VERIFY_NOT_NULL(unsubscribeTask, NS_ERROR);
 
@@ -93,6 +105,9 @@ NSResult NSUnsubscribe(NSProvider * provider)
 
 NSResult NSConsumerSendSyncInfo(const char * providerId, uint64_t messageId, NSSyncType type)
 {
+    bool isStartedConsumer = NSIsStartedConsumer();
+    NS_VERIFY_NOT_NULL(isStartedConsumer == true ? (void *) 1 : NULL, NS_ERROR);
+
     NSSyncInfo * syncInfo = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
     NS_VERIFY_NOT_NULL(syncInfo, NS_ERROR);
 
@@ -108,6 +123,9 @@ NSResult NSConsumerSendSyncInfo(const char * providerId, uint64_t messageId, NSS
 
 NSResult NSRescanProvider()
 {
+    bool isStartedConsumer = NSIsStartedConsumer();
+    NS_VERIFY_NOT_NULL(isStartedConsumer == true ? (void *) 1 : NULL, NS_ERROR);
+
     NSTask * discoverTask = NSMakeTask(TASK_CONSUMER_REQ_DISCOVER, NULL);
     NS_VERIFY_NOT_NULL(discoverTask, NS_ERROR);
 
@@ -116,6 +134,9 @@ NSResult NSRescanProvider()
 
 NSProvider * NSConsumerGetProvider(const char * providerId)
 {
+    bool isStartedConsumer = NSIsStartedConsumer();
+    NS_VERIFY_NOT_NULL(isStartedConsumer == true ? (void *) 1 : NULL, NULL);
+
     NS_VERIFY_NOT_NULL(providerId, NULL);
 
     return (NSProvider *) NSConsumerFindNSProvider(providerId);
@@ -123,6 +144,9 @@ NSProvider * NSConsumerGetProvider(const char * providerId)
 
 NSMessage * NSConsumerGetMessage(uint64_t messageId)
 {
+    bool isStartedConsumer = NSIsStartedConsumer();
+    NS_VERIFY_NOT_NULL(isStartedConsumer == true ? (void *) 1 : NULL, NULL);
+
     char msgId[NS_DEVICE_ID_LENGTH] = { 0, };
     snprintf(msgId, NS_DEVICE_ID_LENGTH, "%lld", (long long int)messageId);
 
index a00e42a..c73178e 100644 (file)
@@ -173,6 +173,30 @@ NSResult NSProviderCacheUpdate(NSProvider_internal * provider)
     return NS_OK;
 }
 
+void NSCancelAllSubscription()
+{
+    NSCacheList * ProviderCache = *(NSGetProviderCacheList());
+    if (!ProviderCache)
+    {
+        NS_LOG(DEBUG, "Provider Cache Init");
+        ProviderCache = NSStorageCreate();
+        NS_VERIFY_NOT_NULL_V(ProviderCache);
+
+        ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
+        NSSetProviderCacheList(ProviderCache);
+    }
+
+    NSCacheElement * obj = NULL;
+    while ((obj = NSPopProviderCacheList(ProviderCache)))
+    {
+        NS_LOG(DEBUG, "build NSTask");
+        NSTask * task = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL, (void *) obj->data);
+        NS_VERIFY_NOT_NULL_V(task);
+
+        NSConsumerPushEvent(task);
+    }
+}
+
 void NSConsumerHandleProviderDiscovered(NSProvider_internal * provider)
 {
     NS_VERIFY_NOT_NULL_V(provider);
@@ -355,6 +379,7 @@ void NSConsumerInternalTaskProcessing(NSTask * task)
         }
         case TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL:
         {
+            NS_LOG(DEBUG, "Make Subscribe cancel from provider.");
             NSConsumerHandleProviderDeleted((NSProvider_internal *)task->taskData);
             NSRemoveProvider((NSProvider_internal *)task->taskData);
             break;
index 0be9f17..36b56bc 100644 (file)
@@ -27,6 +27,7 @@ extern "C" {
 
 #include "NSStructs.h"
 #include "NSStorageAdapter.h"
+#include "NSConsumerMemoryCache.h"
 #include "NSConsumerCommunication.h"
 
 NSCacheList ** NSGetMessageCacheList();
@@ -35,6 +36,8 @@ void NSSetMessageCacheList(NSCacheList *);
 
 NSCacheList ** NSGetProviderCacheList();
 
+void NSCancelAllSubscription();
+
 void NSSetProviderCacheList(NSCacheList *);
 
 void NSDestroyMessageCacheList();
index 6e1ccf7..1d911fa 100644 (file)
@@ -112,17 +112,20 @@ NSResult NSConsumerPushEvent(NSTask * task)
 
 void NSConsumerMessageHandlerExit()
 {
-    NSDestroyMessageCacheList();
-    NSDestroyProviderCacheList();
+
     NSConsumerListenerTermiate();
+    NSCancelAllSubscription();
     NSThreadStop(*(NSGetMsgHandleThreadHandle()));
     NSDestroyQueue(*(NSGetMsgHandleQueue()));
     NSSetMsgHandleQueue(NULL);
+
+    NSDestroyMessageCacheList();
+    NSDestroyProviderCacheList();
 }
 
 void * NSConsumerMsgHandleThreadFunc(void * threadHandle)
 {
-    NSConsumerQueue * queue = NULL;
+    NSConsumerQueue * queue = *(NSGetMsgHandleQueue());;
     NSConsumerQueueObject * obj = NULL;
 
     NS_LOG(DEBUG, "create thread for consumer message handle");
@@ -131,16 +134,17 @@ void * NSConsumerMsgHandleThreadFunc(void * threadHandle)
 
     while (true)
     {
-        if (!queueHandleThread->isStarted)
+        if (!queue)
         {
-            NS_LOG(ERROR, "msg handler thread will be terminated");
-            break;
+            queue = *(NSGetMsgHandleQueue());
+            usleep(2000);
+            continue;
         }
 
-        queue = *(NSGetMsgHandleQueue());
-        if (!queue)
+        if (!queueHandleThread->isStarted && NSIsQueueEmpty(queue))
         {
-            continue;
+            NS_LOG(ERROR, "msg handler thread will be terminated");
+            break;
         }
 
         if (NSIsQueueEmpty(queue))
index 56fc5c7..fb4a8e8 100644 (file)
@@ -140,6 +140,7 @@ NSResult NSStorageDelete(NSCacheList * list, const char * delId)
 
     NSCacheElement * prev = list->head;
     NSCacheElement * del = list->head;
+    NS_VERIFY_NOT_NULL(del, NS_ERROR);
 
     if (NSConsumerCompareIdCacheData(type, del->data, delId))
     {
@@ -370,6 +371,30 @@ NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newOb
     return NS_OK;
 }
 
+NSCacheElement * NSPopProviderCacheList(NSCacheList * list)
+{
+    pthread_mutex_t * mutex = NSGetCacheMutex();
+
+    pthread_mutex_lock(mutex);
+
+    NSCacheElement * head = list->head;
+    if (head)
+    {
+               NSCacheElement * next = list->head->next;
+
+               if (list->tail == head)
+                       list->tail = NULL;
+
+               list->head = next;
+               head->next = NULL;
+    }
+
+    pthread_mutex_unlock(mutex);
+
+    return head;
+}
+
+
 NSResult NSStorageDestroy(NSCacheList * list)
 {
     pthread_mutex_t * mutex = NSGetCacheMutex();
@@ -438,7 +463,6 @@ bool NSConsumerCompareIdCacheData(NSCacheType type, void * data, const char * id
     else if (type == NS_CONSUMER_CACHE_PROVIDER)
     {
         NSProvider_internal * prov = (NSProvider_internal *) data;
-
         if (!strcmp(prov->providerId, id))
         {
             return true;
index 9cc47f3..69702a4 100644 (file)
@@ -35,6 +35,7 @@ extern "C" {
 bool NSConsumerCompareIdCacheData(NSCacheType type, void * data, const char * id);
 NSResult NSConsumerCacheWriteMessage(NSCacheList * list, NSCacheElement * newObj);
 NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newObj);
+NSCacheElement * NSPopProviderCacheList(NSCacheList * list);
 
 #ifdef __cplusplus
 }