From: jaesick.shin Date: Sun, 4 Sep 2016 22:17:02 +0000 (+0900) Subject: Hold GetTopics API return until related code finishes in the other thread X-Git-Tag: 1.2.0+RC3~151^2^2~28 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ac3918b8b529bdf4c639fe333da2c93f36620684;p=platform%2Fupstream%2Fiotivity.git Hold GetTopics API return until related code finishes in the other thread Issue: Crash happen Get Topic just after Topic registration. (between RegistrerTopic and GetTopics/GetConsumerTopic APIs) Fix: apply condition variable to RegistrerTopic API logic and GetTopics/GetConsumerTopic API logic. Other Fixes: locking the NSProviderInterface. modify unittest for functions of 1 and 2. Change-Id: Ia8e75d7b21198b3d4c3810050baa0867d60eeb78 Signed-off-by: jaesick.shin Reviewed-on: https://gerrit.iotivity.org/gerrit/11365 Reviewed-by: Uze Choi Tested-by: Uze Choi --- diff --git a/service/notification/src/common/NSConstants.h b/service/notification/src/common/NSConstants.h index a6cc2a379..3c6d9497a 100644 --- a/service/notification/src/common/NSConstants.h +++ b/service/notification/src/common/NSConstants.h @@ -266,7 +266,9 @@ typedef enum eTaskType TASK_DELETE_TOPIC = 11002, TASK_SUBSCRIBE_TOPIC = 11003, TASK_UNSUBSCRIBE_TOPIC = 11004, - TASK_POST_TOPIC = 11005 + TASK_POST_TOPIC = 11005, + TASK_GET_TOPICS = 11006, + TAST_GET_CONSUMER_TOPICS = 11007 } NSTaskType; diff --git a/service/notification/src/provider/NSProviderInterface.c b/service/notification/src/provider/NSProviderInterface.c index 51d3785f2..0a956dbcc 100644 --- a/service/notification/src/provider/NSProviderInterface.c +++ b/service/notification/src/provider/NSProviderInterface.c @@ -32,10 +32,12 @@ #include "cautilinterface.h" #include "NSProviderSystem.h" #include "oic_time.h" +#include bool initProvider = false; pthread_mutex_t nsInitMutex; +pthread_cond_t nstopicCond; void initializeMutex() { @@ -43,6 +45,31 @@ void initializeMutex() nsInitMutex = initMutex; } +void NSInitialize() +{ + NS_LOG(DEBUG, "NSSetList - IN"); + + pthread_mutexattr_init(&NSCacheMutexAttr); + pthread_mutexattr_settype(&NSCacheMutexAttr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&NSCacheMutex, &NSCacheMutexAttr); + pthread_cond_init(&nstopicCond, NULL); + + NSInitSubscriptionList(); + NSInitTopicList(); + NS_LOG(DEBUG, "NSSetList - OUT"); +} + +void NSDeinitailize() +{ + NSStorageDestroy(consumerSubList); + NSStorageDestroy(consumerTopicList); + NSStorageDestroy(registeredTopicList); + + pthread_mutex_destroy(&NSCacheMutex); + pthread_mutexattr_destroy(&NSCacheMutexAttr); + pthread_cond_destroy(&nstopicCond); +} + NSResult NSStartProvider(NSProviderConfig config) { NS_LOG(DEBUG, "NSStartProvider - IN"); @@ -62,7 +89,7 @@ NSResult NSStartProvider(NSProviderConfig config) CARegisterNetworkMonitorHandler((CAAdapterStateChangedCB)NSProviderAdapterStateListener, (CAConnectionStateChangedCB)NSProviderConnectionStateListener); - NSSetList(); + NSInitialize(); NSInitScheduler(); NSStartScheduler(); @@ -79,29 +106,6 @@ NSResult NSStartProvider(NSProviderConfig config) return NS_OK; } -void NSSetList() -{ - NS_LOG(DEBUG, "NSSetList - IN"); - - pthread_mutexattr_init(&NSCacheMutexAttr); - pthread_mutexattr_settype(&NSCacheMutexAttr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&NSCacheMutex, &NSCacheMutexAttr); - - NSInitSubscriptionList(); - NSInitTopicList(); - NS_LOG(DEBUG, "NSSetList - OUT"); -} - -void NSDestroyList() -{ - NSStorageDestroy(consumerSubList); - NSStorageDestroy(consumerTopicList); - NSStorageDestroy(registeredTopicList); - - pthread_mutex_destroy(&NSCacheMutex); - pthread_mutexattr_destroy(&NSCacheMutexAttr); -} - NSResult NSStopProvider() { NS_LOG(DEBUG, "NSStopProvider - IN"); @@ -115,7 +119,7 @@ NSResult NSStopProvider() NSRegisterSubscribeRequestCb((NSSubscribeRequestCallback)NULL); NSRegisterSyncCb((NSProviderSyncInfoCallback)NULL); NSStopScheduler(); - NSDestroyList(); + NSDeinitailize(); initProvider = false; } @@ -266,11 +270,18 @@ NSTopicLL * NSProviderGetConsumerTopics(const char * consumerId) return NULL; } - NSTopicLL * topics = NSProviderGetConsumerTopicsCacheData(registeredTopicList, - consumerTopicList, consumerId); + NSTopicSynchronization topics; + topics.consumerId = OICStrdup(consumerId); + topics.topics = NULL; + topics.condition = nstopicCond; + + NSPushQueue(TOPIC_SCHEDULER, TAST_GET_CONSUMER_TOPICS, &topics); + pthread_cond_wait(&topics.condition, &nsInitMutex); + OICFree(topics.consumerId); pthread_mutex_unlock(&nsInitMutex); - return topics; + NS_LOG(DEBUG, "NSProviderGetConsumerTopics - OUT"); + return topics.topics; } NSTopicLL * NSProviderGetTopics() @@ -278,12 +289,17 @@ NSTopicLL * NSProviderGetTopics() NS_LOG(DEBUG, "NSProviderGetTopics - IN"); pthread_mutex_lock(&nsInitMutex); - NSTopicLL * topics = NSProviderGetTopicsCacheData(registeredTopicList); + NSTopicSynchronization topics; + topics.consumerId = NULL; + topics.topics = NULL; + topics.condition = nstopicCond; + + NSPushQueue(TOPIC_SCHEDULER, TASK_GET_TOPICS, &topics); + pthread_cond_wait(&topics.condition, &nsInitMutex); pthread_mutex_unlock(&nsInitMutex); NS_LOG(DEBUG, "NSProviderGetTopics - OUT"); - - return topics; + return topics.topics; } NSResult NSProviderRegisterTopic(const char * topicName) diff --git a/service/notification/src/provider/NSProviderTopic.c b/service/notification/src/provider/NSProviderTopic.c index a16efa6cf..f7d9940b9 100644 --- a/service/notification/src/provider/NSProviderTopic.c +++ b/service/notification/src/provider/NSProviderTopic.c @@ -21,6 +21,7 @@ #include "NSProviderTopic.h" #include "oic_string.h" #include "oic_malloc.h" +#include NSResult NSSendTopicUpdation(); @@ -426,6 +427,25 @@ void * NSTopicSchedule(void * ptr) NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) node->taskData); } break; + case TASK_GET_TOPICS: + { + NS_LOG(DEBUG, "TASK_GET_TOPICS : "); + NSTopicSynchronization * topicData = (NSTopicSynchronization *) node->taskData; + NSTopicLL * topics = NSProviderGetTopicsCacheData(registeredTopicList); + topicData->topics = topics; + pthread_cond_signal(&topicData->condition); + } + break; + case TAST_GET_CONSUMER_TOPICS: + { + NS_LOG(DEBUG, "TASK_GET_CONSUMER_TOPICS : "); + NSTopicSynchronization * topicData = (NSTopicSynchronization *) node->taskData; + NSTopicLL * topics = NSProviderGetConsumerTopicsCacheData(registeredTopicList, + consumerTopicList, topicData->consumerId); + topicData->topics = topics; + pthread_cond_signal(&topicData->condition); + } + break; default: break; } diff --git a/service/notification/src/provider/NSProviderTopic.h b/service/notification/src/provider/NSProviderTopic.h index 20e416e36..e14a8bff8 100644 --- a/service/notification/src/provider/NSProviderTopic.h +++ b/service/notification/src/provider/NSProviderTopic.h @@ -28,6 +28,12 @@ #include "NSProviderResource.h" #include "NSProviderSubscription.h" +typedef struct { + pthread_cond_t condition; + char * consumerId; + NSTopicLL * topics; +} NSTopicSynchronization; + NSCacheList * consumerTopicList; NSCacheList * registeredTopicList; diff --git a/service/notification/unittest/NSProviderTest.cpp b/service/notification/unittest/NSProviderTest.cpp index ba46cc7db..dd2238bde 100755 --- a/service/notification/unittest/NSProviderTest.cpp +++ b/service/notification/unittest/NSProviderTest.cpp @@ -341,9 +341,6 @@ TEST_F(NotificationProviderTest, ExpectEqualAddedTopicsAndRegisteredTopics) NSProviderRegisterTopic(str.c_str()); NSProviderRegisterTopic(str2.c_str()); - std::unique_lock< std::mutex > lock{ mutexForCondition }; - responseCon.wait_for(lock, std::chrono::milliseconds(1000)); - bool isSame = true; NSTopicLL * topics = NSProviderGetTopics(); @@ -378,9 +375,6 @@ TEST_F(NotificationProviderTest, ExpectEqualUnregisteredTopicsAndRegisteredTopic NSProviderRegisterTopic(str2.c_str()); NSProviderUnregisterTopic(str2.c_str()); - std::unique_lock< std::mutex > lock{ mutexForCondition }; - responseCon.wait_for(lock, std::chrono::milliseconds(1000)); - bool isSame = true; NSTopicLL * topics = NSProviderGetTopics();