bug fix about memory leak.
[platform/upstream/iotivity.git] / service / notification / src / provider / NSProviderMemoryCache.c
1 //******************************************************************\r
2 //\r
3 // Copyright 2016 Samsung Electronics All Rights Reserved.\r
4 //\r
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
6 //\r
7 // Licensed under the Apache License, Version 2.0 (the "License");\r
8 // you may not use this file except in compliance with the License.\r
9 // You may obtain a copy of the License at\r
10 //\r
11 //      http://www.apache.org/licenses/LICENSE-2.0\r
12 //\r
13 // Unless required by applicable law or agreed to in writing, software\r
14 // distributed under the License is distributed on an "AS IS" BASIS,\r
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16 // See the License for the specific language governing permissions and\r
17 // limitations under the License.\r
18 //\r
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
20 \r
21 #include "NSProviderMemoryCache.h"\r
22 #include <string.h>\r
23 \r
24 NSCacheList * NSProviderStorageCreate()\r
25 {\r
26     pthread_mutex_lock(&NSCacheMutex);\r
27     NSCacheList * newList = (NSCacheList *) OICMalloc(sizeof(NSCacheList));\r
28     if (!newList)\r
29     {\r
30         pthread_mutex_unlock(&NSCacheMutex);\r
31         return NULL;\r
32     }\r
33 \r
34     newList->head = newList->tail = NULL;\r
35 \r
36     pthread_mutex_unlock(&NSCacheMutex);\r
37     NS_LOG(DEBUG, "NSCacheCreate");\r
38 \r
39     return newList;\r
40 }\r
41 \r
42 NSCacheElement * NSProviderStorageRead(NSCacheList * list, const char * findId)\r
43 {\r
44     pthread_mutex_lock(&NSCacheMutex);\r
45 \r
46     NS_LOG(DEBUG, "NSCacheRead - IN");\r
47 \r
48     NSCacheElement * iter = list->head;\r
49     NSCacheElement * next = NULL;\r
50     NSCacheType type = list->cacheType;\r
51 \r
52     NS_LOG_V(DEBUG, "Find ID - %s", findId);\r
53 \r
54     while (iter)\r
55     {\r
56         next = iter->next;\r
57 \r
58         if (NSProviderCompareIdCacheData(type, iter->data, findId))\r
59         {\r
60             NS_LOG(DEBUG, "Found in Cache");\r
61             pthread_mutex_unlock(&NSCacheMutex);\r
62             return iter;\r
63         }\r
64 \r
65         iter = next;\r
66     }\r
67 \r
68     NS_LOG(DEBUG, "Not found in Cache");\r
69     NS_LOG(DEBUG, "NSCacheRead - OUT");\r
70     pthread_mutex_unlock(&NSCacheMutex);\r
71 \r
72     return NULL;\r
73 }\r
74 \r
75 NSResult NSCacheUpdateSubScriptionState(NSCacheList * list, char * id, bool state)\r
76 {\r
77     pthread_mutex_lock(&NSCacheMutex);\r
78 \r
79     NS_LOG(DEBUG, "NSCacheUpdateSubScriptionState - IN");\r
80 \r
81     if (id == NULL)\r
82     {\r
83         NS_LOG(DEBUG, "id is NULL");\r
84         pthread_mutex_unlock(&NSCacheMutex);\r
85         return NS_ERROR;\r
86     }\r
87 \r
88     NSCacheElement * it = NSProviderStorageRead(list, id);\r
89 \r
90     if (it)\r
91     {\r
92         NSCacheSubData * itData = (NSCacheSubData *) it->data;\r
93         if (strcmp(itData->id, id) == 0)\r
94         {\r
95             NS_LOG(DEBUG, "Update Data - IN");\r
96 \r
97             NS_LOG_V(DEBUG, "currData_ID = %s", itData->id);\r
98             NS_LOG_V(DEBUG, "currData_MsgObID = %d", itData->messageObId);\r
99             NS_LOG_V(DEBUG, "currData_SyncObID = %d", itData->syncObId);\r
100             NS_LOG_V(DEBUG, "currData_Cloud_MsgObID = %d", itData->remote_messageObId);\r
101             NS_LOG_V(DEBUG, "currData_Cloud_SyncObID = %d", itData->remote_syncObId);\r
102             NS_LOG_V(DEBUG, "currData_IsWhite = %d", itData->isWhite);\r
103 \r
104             NS_LOG_V(DEBUG, "update state = %d", state);\r
105 \r
106             itData->isWhite = state;\r
107 \r
108             NS_LOG(DEBUG, "Update Data - OUT");\r
109             pthread_mutex_unlock(&NSCacheMutex);\r
110             return NS_OK;\r
111         }\r
112     }\r
113     else\r
114     {\r
115         NS_LOG(DEBUG, "Not Found Data");\r
116     }\r
117 \r
118     NS_LOG(DEBUG, "NSCacheUpdateSubScriptionState - OUT");\r
119     pthread_mutex_unlock(&NSCacheMutex);\r
120     return NS_ERROR;\r
121 }\r
122 \r
123 NSResult NSProviderStorageWrite(NSCacheList * list, NSCacheElement * newObj)\r
124 {\r
125     pthread_mutex_lock(&NSCacheMutex);\r
126 \r
127     NSCacheType type = list->cacheType;\r
128 \r
129     NS_LOG(DEBUG, "NSCacheWrite - IN");\r
130 \r
131     if (newObj == NULL)\r
132     {\r
133         NS_LOG(DEBUG, "newObj is NULL - IN");\r
134         pthread_mutex_unlock(&NSCacheMutex);\r
135         return NS_ERROR;\r
136     }\r
137 \r
138     if (type == NS_PROVIDER_CACHE_SUBSCRIBER)\r
139     {\r
140         NS_LOG(DEBUG, "Type is SUBSCRIBER");\r
141 \r
142         NSCacheSubData * subData = (NSCacheSubData *) newObj->data;\r
143         NSCacheElement * it = NSProviderStorageRead(list, subData->id);\r
144 \r
145         if (it)\r
146         {\r
147             NSCacheSubData * itData = (NSCacheSubData *) it->data;\r
148 \r
149             if (strcmp(itData->id, subData->id) == 0)\r
150             {\r
151                 NS_LOG(DEBUG, "Update Data - IN");\r
152 \r
153                 NS_LOG_V(DEBUG, "currData_ID = %s", itData->id);\r
154                 NS_LOG_V(DEBUG, "currData_MsgObID = %d", itData->messageObId);\r
155                 NS_LOG_V(DEBUG, "currData_SyncObID = %d", itData->syncObId);\r
156                 NS_LOG_V(DEBUG, "currData_Cloud_MsgObID = %d", itData->remote_messageObId);\r
157                 NS_LOG_V(DEBUG, "currData_Cloud_SyncObID = %d", itData->remote_syncObId);\r
158                 NS_LOG_V(DEBUG, "currData_IsWhite = %d", itData->isWhite);\r
159 \r
160                 NS_LOG_V(DEBUG, "subData_ID = %s", subData->id);\r
161                 NS_LOG_V(DEBUG, "subData_MsgObID = %d", subData->messageObId);\r
162                 NS_LOG_V(DEBUG, "subData_SyncObID = %d", subData->syncObId);\r
163                 NS_LOG_V(DEBUG, "subData_Cloud_MsgObID = %d", subData->remote_messageObId);\r
164                 NS_LOG_V(DEBUG, "subData_Cloud_SyncObID = %d", subData->remote_syncObId);\r
165                 NS_LOG_V(DEBUG, "subData_IsWhite = %d", subData->isWhite);\r
166 \r
167                 if (subData->messageObId != 0)\r
168                 {\r
169                     itData->messageObId = subData->messageObId;\r
170                 }\r
171 \r
172                 if (subData->syncObId != 0)\r
173                 {\r
174                     itData->syncObId = subData->syncObId;\r
175                 }\r
176 \r
177                 if (subData->remote_messageObId != 0)\r
178                 {\r
179                     itData->remote_messageObId = subData->remote_messageObId;\r
180                 }\r
181 \r
182                 if (subData->remote_syncObId != 0)\r
183                 {\r
184                     itData->remote_syncObId = subData->remote_syncObId;\r
185                     NS_LOG_V(DEBUG, "sync id cached: %d", itData->remote_syncObId);\r
186                 }\r
187 \r
188                 NS_LOG(DEBUG, "Update Data - OUT");\r
189                 OICFree(subData);\r
190                 OICFree(newObj);\r
191                 pthread_mutex_unlock(&NSCacheMutex);\r
192                 return NS_OK;\r
193             }\r
194         }\r
195 \r
196     }\r
197     else if(type == NS_PROVIDER_CACHE_REGISTER_TOPIC)\r
198     {\r
199         NS_LOG(DEBUG, "Type is REGITSTER TOPIC");\r
200 \r
201         NSCacheTopicData * topicData = (NSCacheTopicData *) newObj->data;\r
202         NSCacheElement * it = NSProviderStorageRead(list, topicData->topicName);\r
203 \r
204         if (it)\r
205         {\r
206             NS_LOG(DEBUG, "already registered for topic name");\r
207             OICFree(topicData->topicName);\r
208             OICFree(topicData);\r
209             OICFree(newObj);\r
210             pthread_mutex_unlock(&NSCacheMutex);\r
211             return NS_FAIL;\r
212         }\r
213     }\r
214     else if(type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME)\r
215     {\r
216         NS_LOG(DEBUG, "Type is REGITSTER TOPIC");\r
217 \r
218         NSCacheTopicSubData * topicData = (NSCacheTopicSubData *) newObj->data;\r
219         NSCacheElement * it = NSProviderStorageRead(list, topicData->topicName);\r
220 \r
221         if (it)\r
222         {\r
223             NS_LOG(DEBUG, "already registered for topic name");\r
224             OICFree(topicData->topicName);\r
225             OICFree(topicData);\r
226             OICFree(newObj);\r
227             pthread_mutex_unlock(&NSCacheMutex);\r
228             return NS_FAIL;\r
229         }\r
230     }\r
231     else if(type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID)\r
232     {\r
233         NS_LOG(DEBUG, "Type is REGITSTER TOPIC");\r
234 \r
235         NSCacheTopicSubData * topicData = (NSCacheTopicSubData *) newObj->data;\r
236         NSCacheElement * it = NSProviderStorageRead(list, topicData->id);\r
237 \r
238         if (it)\r
239         {\r
240             NS_LOG(DEBUG, "already registered for topic name");\r
241             OICFree(topicData->topicName);\r
242             OICFree(topicData);\r
243             OICFree(newObj);\r
244             pthread_mutex_unlock(&NSCacheMutex);\r
245             return NS_FAIL;\r
246         }\r
247     }\r
248 \r
249     if (list->head == NULL)\r
250     {\r
251         NS_LOG(DEBUG, "list->head is NULL, Insert First Data");\r
252         list->head = list->tail = newObj;\r
253         pthread_mutex_unlock(&NSCacheMutex);\r
254         return NS_OK;\r
255     }\r
256 \r
257     list->tail = list->tail->next = newObj;\r
258     NS_LOG(DEBUG, "list->head is not NULL");\r
259     pthread_mutex_unlock(&NSCacheMutex);\r
260     return NS_OK;\r
261 }\r
262 \r
263 NSResult NSProviderStorageDestroy(NSCacheList * list)\r
264 {\r
265     NSCacheElement * iter = list->head;\r
266     NSCacheElement * next = NULL;\r
267     NSCacheType type = list->cacheType;\r
268 \r
269     while (iter)\r
270     {\r
271         next = (NSCacheElement *) iter->next;\r
272         NSProviderDeleteCacheData(type, iter->data);\r
273         OICFree(iter);\r
274         iter = next;\r
275     }\r
276 \r
277     OICFree(list);\r
278     return NS_OK;\r
279 }\r
280 \r
281 \r
282 bool NSIsSameObId(NSCacheSubData * data, OCObservationId id)\r
283 {\r
284     if (id == data->messageObId || id == data->syncObId || id == data->remote_messageObId ||\r
285                 id == data->remote_syncObId)\r
286     {\r
287         return true;\r
288     }\r
289 \r
290     return false;\r
291 }\r
292 \r
293 bool NSProviderCompareIdCacheData(NSCacheType type, void * data, const char * id)\r
294 {\r
295     NS_LOG(DEBUG, "NSProviderCompareIdCacheData - IN");\r
296 \r
297     if (data == NULL)\r
298     {\r
299         return false;\r
300     }\r
301 \r
302     NS_LOG_V(DEBUG, "Data(compData) = [%s]", id);\r
303 \r
304     if (type == NS_PROVIDER_CACHE_SUBSCRIBER)\r
305     {\r
306         NSCacheSubData * subData = (NSCacheSubData *) data;\r
307 \r
308         NS_LOG_V(DEBUG, "Data(subData) = [%s]", subData->id);\r
309 \r
310         if (strcmp(subData->id, id) == 0)\r
311         {\r
312             NS_LOG(DEBUG, "SubData is Same");\r
313             return true;\r
314         }\r
315 \r
316         NS_LOG(DEBUG, "Message Data is Not Same");\r
317         return false;\r
318     }\r
319     else if (type == NS_PROVIDER_CACHE_SUBSCRIBER_OBSERVE_ID)\r
320     {\r
321         NSCacheSubData * subData = (NSCacheSubData *) data;\r
322 \r
323         NS_LOG_V(DEBUG, "Data(subData) = [%s]", subData->id);\r
324 \r
325         OCObservationId currID = *id;\r
326 \r
327         if (NSIsSameObId(subData, currID))\r
328         {\r
329             NS_LOG(DEBUG, "SubData is Same");\r
330             return true;\r
331         }\r
332 \r
333         NS_LOG(DEBUG, "Message Data is Not Same");\r
334         return false;\r
335     }\r
336     else if (type == NS_PROVIDER_CACHE_REGISTER_TOPIC)\r
337     {\r
338         NSCacheTopicData * topicData = (NSCacheTopicData *) data;\r
339 \r
340         NS_LOG_V(DEBUG, "Data(topicData) = [%s]", topicData->topicName);\r
341 \r
342         if (strcmp(topicData->topicName, id) == 0)\r
343         {\r
344             NS_LOG(DEBUG, "SubData is Same");\r
345             return true;\r
346         }\r
347 \r
348         NS_LOG(DEBUG, "Message Data is Not Same");\r
349         return false;\r
350     }\r
351     else if (type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME)\r
352     {\r
353         NSCacheTopicSubData * topicData = (NSCacheTopicSubData *) data;\r
354 \r
355         NS_LOG_V(DEBUG, "Data(topicData) = [%s]", topicData->topicName);\r
356 \r
357         if (strcmp(topicData->topicName, id) == 0)\r
358         {\r
359             NS_LOG(DEBUG, "SubData is Same");\r
360             return true;\r
361         }\r
362 \r
363         NS_LOG(DEBUG, "Message Data is Not Same");\r
364         return false;\r
365     }\r
366     else if (type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID)\r
367     {\r
368         NSCacheTopicSubData * topicData = (NSCacheTopicSubData *) data;\r
369 \r
370         NS_LOG_V(DEBUG, "Data(topicData) = [%s]", topicData->id);\r
371 \r
372         if (strcmp(topicData->id, id) == 0)\r
373         {\r
374             NS_LOG(DEBUG, "SubData is Same");\r
375             return true;\r
376         }\r
377 \r
378         NS_LOG(DEBUG, "Message Data is Not Same");\r
379         return false;\r
380     }\r
381 \r
382 \r
383     NS_LOG(DEBUG, "NSProviderCompareIdCacheData - OUT");\r
384     return false;\r
385 }\r
386 \r
387 NSResult NSProviderDeleteCacheData(NSCacheType type, void * data)\r
388 {\r
389     if (!data)\r
390     {\r
391         return NS_ERROR;\r
392     }\r
393 \r
394     if (type == NS_PROVIDER_CACHE_SUBSCRIBER || type == NS_PROVIDER_CACHE_SUBSCRIBER_OBSERVE_ID)\r
395     {\r
396         NSCacheSubData * subData = (NSCacheSubData *) data;\r
397 \r
398         (subData->id)[0] = '\0';\r
399         OICFree(subData);\r
400         return NS_OK;\r
401     }\r
402     else if(type == NS_PROVIDER_CACHE_REGISTER_TOPIC)\r
403     {\r
404 \r
405         NSCacheTopicData * topicData = (NSCacheTopicData *) data;\r
406         NS_LOG_V(DEBUG, "topicData->topicName = %s, topicData->state = %d", topicData->topicName,\r
407                 (int)topicData->state);\r
408 \r
409         OICFree(topicData->topicName);\r
410         OICFree(topicData);\r
411     }\r
412     else if(type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME ||\r
413             type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID)\r
414     {\r
415         NSCacheTopicSubData * topicData = (NSCacheTopicSubData *) data;\r
416         OICFree(topicData->topicName);\r
417         OICFree(topicData);\r
418     }\r
419 \r
420     return NS_OK;\r
421 }\r
422 \r
423 NSResult NSProviderStorageDelete(NSCacheList * list, const char * delId)\r
424 {\r
425     pthread_mutex_lock(&NSCacheMutex);\r
426     NSCacheElement * prev = list->head;\r
427     NSCacheElement * del = list->head;\r
428 \r
429     NSCacheType type = list->cacheType;\r
430 \r
431     if(!del)\r
432     {\r
433         NS_LOG(DEBUG, "list head is NULL");\r
434         pthread_mutex_unlock(&NSCacheMutex);\r
435         return NS_FAIL;\r
436     }\r
437 \r
438     if (NSProviderCompareIdCacheData(type, del->data, delId))\r
439     {\r
440         if (del == list->head) // first object\r
441         {\r
442             if (del == list->tail) // first object (one object)\r
443             {\r
444                 list->tail = del->next;\r
445             }\r
446 \r
447             list->head = del->next;\r
448             NSProviderDeleteCacheData(type, del->data);\r
449             OICFree(del);\r
450             pthread_mutex_unlock(&NSCacheMutex);\r
451             return NS_OK;\r
452         }\r
453     }\r
454 \r
455     del = del->next;\r
456     while (del)\r
457     {\r
458         if (NSProviderCompareIdCacheData(type, del->data, delId))\r
459         {\r
460             if (del == list->tail) // delete object same to last object\r
461             {\r
462                 list->tail = prev;\r
463             }\r
464 \r
465             prev->next = del->next;\r
466             NSProviderDeleteCacheData(type, del->data);\r
467             OICFree(del);\r
468             pthread_mutex_unlock(&NSCacheMutex);\r
469             return NS_OK;\r
470         }\r
471 \r
472         prev = del;\r
473         del = del->next;\r
474     }\r
475     pthread_mutex_unlock(&NSCacheMutex);\r
476     return NS_FAIL;\r
477 }\r
478 \r
479 NSTopicLL * NSProviderGetTopicsCacheData(NSCacheList * regTopicList)\r
480 {\r
481     NS_LOG(DEBUG, "NSProviderGetTopicsCache - IN");\r
482     pthread_mutex_lock(&NSCacheMutex);\r
483 \r
484     NSCacheElement * iter = regTopicList->head;\r
485 \r
486     if(!iter)\r
487     {\r
488         pthread_mutex_unlock(&NSCacheMutex);\r
489         return NULL;\r
490     }\r
491 \r
492     NSTopicLL * iterTopic = NULL;\r
493     NSTopicLL * newTopic = NULL;\r
494     NSTopicLL * topics = NULL;\r
495 \r
496     while (iter)\r
497     {\r
498         NSCacheTopicData * curr = (NSCacheTopicData *) iter->data;\r
499         newTopic = (NSTopicLL *) OICMalloc(sizeof(NSTopicLL));\r
500         if(!newTopic)\r
501         {\r
502             pthread_mutex_unlock(&NSCacheMutex);\r
503             return NULL;\r
504         }\r
505 \r
506         newTopic->state = curr->state;\r
507         newTopic->next = NULL;\r
508         newTopic->topicName = OICStrdup(curr->topicName);\r
509 \r
510         if(!topics)\r
511         {\r
512             iterTopic = topics = newTopic;\r
513         }\r
514         else\r
515         {\r
516             iterTopic->next = newTopic;\r
517             iterTopic = newTopic;\r
518         }\r
519 \r
520         iter = iter->next;\r
521     }\r
522 \r
523     pthread_mutex_unlock(&NSCacheMutex);\r
524     NS_LOG(DEBUG, "NSProviderGetTopicsCache - OUT");\r
525 \r
526     return topics;\r
527 }\r
528 \r
529 NSTopicLL * NSProviderGetConsumerTopicsCacheData(NSCacheList * regTopicList,\r
530         NSCacheList * conTopicList, const char * consumerId)\r
531 {\r
532     NS_LOG(DEBUG, "NSProviderGetConsumerTopicsCacheData - IN");\r
533 \r
534     pthread_mutex_lock(&NSCacheMutex);\r
535     NSTopicLL * topics = NSProviderGetTopicsCacheData(regTopicList);\r
536 \r
537     if(!topics)\r
538     {\r
539         pthread_mutex_unlock(&NSCacheMutex);\r
540         return NULL;\r
541     }\r
542 \r
543     NSCacheElement * iter = conTopicList->head;\r
544     conTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID;\r
545 \r
546     while(iter)\r
547     {\r
548         NSCacheTopicSubData * curr = (NSCacheTopicSubData *)iter->data;\r
549 \r
550         if(curr && strcmp(curr->id, consumerId) == 0)\r
551         {\r
552             NS_LOG_V(DEBUG, "curr->id = %s", curr->id);\r
553             NS_LOG_V(DEBUG, "curr->topicName = %s", curr->topicName);\r
554 \r
555             NSTopicLL * topicIter = topics;\r
556             while(topicIter)\r
557             {\r
558                 if(strcmp(topicIter->topicName, curr->topicName) == 0)\r
559                 {\r
560                     topicIter->state = NS_TOPIC_SUBSCRIBED;\r
561                     break;\r
562                 }\r
563                 topicIter = topicIter->next;\r
564             }\r
565         }\r
566 \r
567         iter = iter->next;\r
568     }\r
569 \r
570     conTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME;\r
571     pthread_mutex_unlock(&NSCacheMutex);\r
572     NS_LOG(DEBUG, "NSProviderGetConsumerTopics - OUT");\r
573 \r
574     return topics;\r
575 }\r
576 \r
577 bool NSProviderIsTopicSubScribed(NSCacheElement * conTopicList, char * cId, char * topicName)\r
578 {\r
579     pthread_mutex_lock(&NSCacheMutex);\r
580 \r
581     if(!conTopicList || !cId || !topicName)\r
582     {\r
583         pthread_mutex_unlock(&NSCacheMutex);\r
584         return false;\r
585     }\r
586 \r
587     NSCacheElement * iter = conTopicList;\r
588     while(iter)\r
589     {\r
590         NSCacheTopicSubData * curr = (NSCacheTopicSubData *) iter->data;\r
591 \r
592         if( (strcmp(curr->id, cId) == 0) && (strcmp(curr->topicName, topicName) == 0) )\r
593         {\r
594             pthread_mutex_unlock(&NSCacheMutex);\r
595             return true;\r
596         }\r
597         iter = iter->next;\r
598     }\r
599 \r
600     pthread_mutex_unlock(&NSCacheMutex);\r
601     return false;\r
602 }\r
603 \r
604 NSResult NSProviderDeleteConsumerTopic(NSCacheList * conTopicList,\r
605         NSCacheTopicSubData * topicSubData)\r
606 {\r
607     pthread_mutex_lock(&NSCacheMutex);\r
608 \r
609     char * cId = topicSubData->id;\r
610     char * topicName = topicSubData->topicName;\r
611 \r
612     if(!conTopicList || !cId || !topicName)\r
613     {\r
614         pthread_mutex_unlock(&NSCacheMutex);\r
615         return NS_ERROR;\r
616     }\r
617 \r
618     NSCacheElement * prev = conTopicList->head;\r
619     NSCacheElement * del = conTopicList->head;\r
620 \r
621     NSCacheType type = conTopicList->cacheType;\r
622 \r
623     if(!del)\r
624     {\r
625         NS_LOG(DEBUG, "list head is NULL");\r
626         pthread_mutex_unlock(&NSCacheMutex);\r
627         return NS_FAIL;\r
628     }\r
629 \r
630     NSCacheTopicSubData * curr = (NSCacheTopicSubData *) del->data;\r
631     NS_LOG_V(DEBUG, "compareid = %s", cId);\r
632     NS_LOG_V(DEBUG, "comparetopicName = %s", topicName);\r
633     NS_LOG_V(DEBUG, "curr->id = %s", curr->id);\r
634     NS_LOG_V(DEBUG, "curr->topicName = %s", curr->topicName);\r
635 \r
636     if( (strncmp(curr->id, cId, NS_UUID_STRING_SIZE) == 0) &&\r
637             (strcmp(curr->topicName, topicName) == 0) )\r
638     {\r
639         if (del == conTopicList->head) // first object\r
640         {\r
641             if (del == conTopicList->tail) // first object (one object)\r
642             {\r
643                 conTopicList->tail = del->next;\r
644             }\r
645 \r
646             conTopicList->head = del->next;\r
647             NSProviderDeleteCacheData(type, del->data);\r
648             OICFree(del);\r
649             pthread_mutex_unlock(&NSCacheMutex);\r
650             return NS_OK;\r
651         }\r
652     }\r
653 \r
654     curr = NULL;\r
655     del = del->next;\r
656     while (del)\r
657     {\r
658         curr = (NSCacheTopicSubData *) del->data;\r
659         if( (strncmp(curr->id, cId, NS_UUID_STRING_SIZE) == 0) &&\r
660                 (strcmp(curr->topicName, topicName) == 0) )\r
661         {\r
662             if (del == conTopicList->tail) // delete object same to last object\r
663             {\r
664                 conTopicList->tail = prev;\r
665             }\r
666 \r
667             prev->next = del->next;\r
668             NSProviderDeleteCacheData(type, del->data);\r
669             OICFree(del);\r
670             pthread_mutex_unlock(&NSCacheMutex);\r
671             return NS_OK;\r
672         }\r
673 \r
674         prev = del;\r
675         del = del->next;\r
676     }\r
677     pthread_mutex_unlock(&NSCacheMutex);\r
678     return NS_FAIL;\r
679 }\r