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