Imported Upstream version 1.2.0
[platform/upstream/iotivity.git] / service / notification / src / consumer / NSConsumerMemoryCache.c
1 //******************************************************************
2 //
3 // Copyright 2016 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "NSConsumerMemoryCache.h"
22 #include "oic_malloc.h"
23 #include "oic_string.h"
24
25 pthread_mutex_t * NSGetCacheMutex()
26 {
27     static pthread_mutex_t * g_NSCacheMutex = NULL;
28     if (g_NSCacheMutex == NULL)
29     {
30         g_NSCacheMutex = (pthread_mutex_t *) OICMalloc(sizeof(pthread_mutex_t));
31         NS_VERIFY_NOT_NULL(g_NSCacheMutex, NULL);
32
33         pthread_mutex_init(g_NSCacheMutex, NULL);
34     }
35     return g_NSCacheMutex;
36 }
37
38 NSCacheList * NSConsumerStorageCreate()
39 {
40     pthread_mutex_t * mutex = NSGetCacheMutex();
41     pthread_mutex_lock(mutex);
42
43     NSCacheList * newList = (NSCacheList *) OICMalloc(sizeof(NSCacheList));
44     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newList, NULL, pthread_mutex_unlock(mutex));
45
46     newList->head = NULL;
47     newList->tail = NULL;
48
49     pthread_mutex_unlock(mutex);
50
51     return newList;
52 }
53
54 NSCacheElement * NSConsumerStorageRead(NSCacheList * list, const char * findId)
55 {
56     NS_VERIFY_NOT_NULL(list, NULL);
57     NS_VERIFY_NOT_NULL(findId, NULL);
58
59     pthread_mutex_t * mutex = NSGetCacheMutex();
60     pthread_mutex_lock(mutex);
61
62     NSCacheElement * iter = list->head;
63     NSCacheType type = list->cacheType;
64
65     while (iter)
66     {
67         if (NSConsumerCompareIdCacheData(type, iter->data, findId))
68         {
69             pthread_mutex_unlock(mutex);
70             return iter;
71         }
72
73         iter = iter->next;
74     }
75
76     NS_LOG (DEBUG, "No Cache Element");
77     pthread_mutex_unlock(mutex);
78     return NULL;
79 }
80
81 NSCacheElement * NSGetProviderFromAddr(NSCacheList * list, const char * addr, uint16_t port)
82 {
83     NS_VERIFY_NOT_NULL(list, NULL);
84     NS_VERIFY_NOT_NULL(addr, NULL);
85     NS_VERIFY_NOT_NULL(
86             (list->cacheType != NS_CONSUMER_CACHE_PROVIDER) ? NULL : (void *) 1, NULL);
87
88     pthread_mutex_t * mutex = NSGetCacheMutex();
89     pthread_mutex_lock(mutex);
90
91     NSCacheElement * iter = list->head;
92
93     while (iter)
94     {
95         NSProviderConnectionInfo * connection =
96                 ((NSProvider_internal *) iter->data)->connection;
97         while (connection)
98         {
99             char * conAddr = connection->addr->addr;
100             uint16_t conPort = connection->addr->port;
101
102             if (!strcmp(conAddr, addr) && conPort == port)
103             {
104                 pthread_mutex_unlock(mutex);
105                 return iter;
106             }
107             connection = connection->next;
108         }
109
110         iter = iter->next;
111     }
112
113     NS_LOG (DEBUG, "No Cache Element");
114     pthread_mutex_unlock(mutex);
115     return NULL;
116 }
117
118 NSResult NSConsumerStorageWrite(NSCacheList * list, NSCacheElement * newObj)
119 {
120     NS_VERIFY_NOT_NULL(list, NS_ERROR);
121     NS_VERIFY_NOT_NULL(newObj, NS_ERROR);
122
123     NSCacheType type = list->cacheType;
124     NS_LOG_V(DEBUG, "cache type : %d", type);
125
126     if (type == NS_CONSUMER_CACHE_PROVIDER)
127     {
128         return NSConsumerCacheWriteProvider(list, newObj);
129     }
130
131     NS_LOG (ERROR, "Not Supported Type");
132
133     return NS_ERROR;
134 }
135
136 NSResult NSConsumerStorageDelete(NSCacheList * list, const char * delId)
137 {
138     NS_VERIFY_NOT_NULL(list, NS_ERROR);
139     NS_VERIFY_NOT_NULL(delId, NS_ERROR);
140
141     NSCacheType type = list->cacheType;
142
143     pthread_mutex_t * mutex = NSGetCacheMutex();
144     pthread_mutex_lock(mutex);
145
146     NSCacheElement * prev = list->head;
147     NSCacheElement * del = list->head;
148     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(del, NS_ERROR, pthread_mutex_unlock(mutex));
149
150     if (NSConsumerCompareIdCacheData(type, del->data, delId))
151     {
152         if (del == list->head)
153         {
154             if (del == list->tail)
155             {
156                 list->tail = del->next;
157             }
158
159             list->head = del->next;
160
161             if (type == NS_CONSUMER_CACHE_PROVIDER)
162             {
163                 NSRemoveProvider_internal((void *) del->data);
164             }
165             NSOICFree(del);
166             pthread_mutex_unlock(mutex);
167
168             return NS_OK;
169         }
170     }
171
172     del = del->next;
173     while (del)
174     {
175         if (NSConsumerCompareIdCacheData(type, del->data, delId))
176         {
177             if (del == list->tail)
178             {
179                 list->tail = prev;
180             }
181
182             prev->next = del->next;
183
184             if (type == NS_CONSUMER_CACHE_PROVIDER)
185             {
186                 NSRemoveProvider_internal((NSProvider_internal *) del->data);
187             }
188             NSOICFree(del);
189             pthread_mutex_unlock(mutex);
190
191             return NS_OK;
192         }
193
194         prev = del;
195         del = del->next;
196     }
197     pthread_mutex_unlock(mutex);
198     return NS_OK;
199 }
200
201 NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newObj)
202 {
203     NS_VERIFY_NOT_NULL(list, NS_ERROR);
204     NS_VERIFY_NOT_NULL(newObj, NS_ERROR);
205
206     pthread_mutex_t * mutex = NSGetCacheMutex();
207
208     NSProvider_internal * newProvObj = (NSProvider_internal *) newObj->data;
209
210     NSCacheElement * it = NSConsumerStorageRead(list, newProvObj->providerId);
211
212     pthread_mutex_lock(mutex);
213
214     if (it)
215     {
216         if (newProvObj->connection)
217         {
218             NSProvider_internal * provObj = (NSProvider_internal *) it->data;
219
220             NSProviderConnectionInfo * infos = provObj->connection;
221             NSProviderConnectionInfo * lastConn = infos->next;
222             while(lastConn)
223             {
224                 infos = lastConn;
225                 lastConn = lastConn->next;
226             }
227             infos->next = NSCopyProviderConnections(newProvObj->connection);
228         }
229
230         if (newProvObj->topicLL)
231         {
232             NSProvider_internal * provObj = (NSProvider_internal *) it->data;
233             NSRemoveTopicLL(provObj->topicLL);
234             provObj->topicLL = NSCopyTopicLL(newProvObj->topicLL);
235         }
236
237         pthread_mutex_unlock(mutex);
238
239         return NS_OK;
240     }
241
242     NSCacheElement * obj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));
243     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(obj, NS_ERROR, pthread_mutex_unlock(mutex));
244
245     NS_LOG_V(DEBUG, "New Object address : %s:%d", newProvObj->connection->addr->addr, newProvObj->connection->addr->port);
246     obj->data = (void *) NSCopyProvider_internal(newProvObj);
247
248     if (!obj->data)
249     {
250         NS_LOG (ERROR, "Failed to CopyProvider");
251         pthread_mutex_unlock(mutex);
252
253         return NS_ERROR;
254     }
255     obj->next = NULL;
256
257     if (!list->head)
258     {
259         list->head = obj;
260         list->tail = obj;
261
262         pthread_mutex_unlock(mutex);
263
264         return NS_OK;
265     }
266
267     (list->tail)->next = obj;
268     list->tail = obj;
269
270     pthread_mutex_unlock(mutex);
271
272     return NS_OK;
273 }
274
275 NSCacheElement * NSPopProviderCacheList(NSCacheList * list)
276 {
277     NS_VERIFY_NOT_NULL(list, NULL);
278
279     pthread_mutex_t * mutex = NSGetCacheMutex();
280     pthread_mutex_lock(mutex);
281
282     NSCacheElement * head = list->head;
283     if (head)
284     {
285         if (list->tail == head)
286         {
287             list->tail = NULL;
288         }
289
290         list->head = head->next;
291         head->next = NULL;
292     }
293
294     pthread_mutex_unlock(mutex);
295     return head;
296 }
297
298
299 NSResult NSConsumerStorageDestroy(NSCacheList * list)
300 {
301     NS_VERIFY_NOT_NULL(list, NS_ERROR);
302
303     pthread_mutex_t * mutex = NSGetCacheMutex();
304     pthread_mutex_lock(mutex);
305
306     NSCacheElement * iter = list->head;
307     NSCacheElement * next = NULL;
308
309     NSCacheType type = list->cacheType;
310
311     if (type == NS_CONSUMER_CACHE_PROVIDER)
312     {
313         while (iter)
314         {
315             next = (NSCacheElement *) iter->next;
316
317             NSRemoveProvider_internal((void *) iter->data);
318             NSOICFree(iter);
319
320             iter = next;
321         }
322
323         NSOICFree(list);
324     }
325
326     pthread_mutex_unlock(mutex);
327
328     return NS_OK;
329 }
330
331 bool NSConsumerCompareIdCacheData(NSCacheType type, void * data, const char * id)
332 {
333     NS_VERIFY_NOT_NULL(data, false);
334     NS_VERIFY_NOT_NULL(id, false);
335
336     if (type == NS_CONSUMER_CACHE_PROVIDER)
337     {
338         NSProvider_internal * prov = (NSProvider_internal *) data;
339         if (!strcmp(prov->providerId, id))
340         {
341             return true;
342         }
343
344         return false;
345     }
346
347     return false;
348 }