Apply tizen coding rule
[platform/framework/web/download-provider.git] / provider / download-provider-notification-manager.c
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifdef SUPPORT_NOTIFICATION
18 #include <stdlib.h>
19 #include <signal.h> // pthread_kill
20 #include <errno.h> // ESRCH
21
22 #include "download-provider-log.h"
23 #include "download-provider-pthread.h"
24 #include "download-provider-client.h"
25 #include "download-provider-client-manager.h"
26 #include "download-provider-notification.h"
27 #include "download-provider-db-defs.h"
28 #include "download-provider-db.h"
29 #endif
30 #include "download-provider-notification-manager.h"
31
32 #ifdef SUPPORT_NOTIFICATION
33 typedef struct { // manage clients without mutex
34         int id;
35         int state;
36         int noti_priv_id;
37         double received_size;
38         double file_size;
39         dp_noti_type type;
40         void *slot; // client can not be NULL. it will exist in dummy
41         void *request; // this can be NULL after destroy
42         void *next;
43 } dp_notification_queue_fmt;
44
45
46 pthread_mutex_t g_dp_notification_manager_mutex = PTHREAD_MUTEX_INITIALIZER;
47 pthread_cond_t g_dp_notification_manager_cond = PTHREAD_COND_INITIALIZER;
48 pthread_t g_dp_notification_manager_tid = 0;
49
50 static dp_notification_queue_fmt *g_dp_notification_clear = NULL;
51 static dp_notification_queue_fmt *g_dp_notification_ongoing = NULL;
52 static dp_notification_queue_fmt *g_dp_notification = NULL;
53
54 pthread_mutex_t g_dp_notification_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
55 pthread_mutex_t g_dp_notification_queue_ongoing_mutex = PTHREAD_MUTEX_INITIALIZER;
56
57 // normal . push at the tail of queue.
58 static int __dp_notification_queue_push(dp_notification_queue_fmt **queue, void *slot, void *request, const int id, const int state, const int noti_priv_id, const double received_size, const double file_size, const dp_noti_type type)
59 {
60         if (queue == NULL) {
61                 TRACE_ERROR("check memory address of queue");
62                 return -1;
63         }
64         if (slot == NULL || request == NULL) {
65                 TRACE_ERROR("check client and request memory address");
66                 return -1;
67         } else if (id <= 0) {
68                 TRACE_ERROR("check slot or download id:%d", id);
69                 return -1;
70         }
71
72         int ret = -1;
73         CLIENT_MUTEX_LOCK(&g_dp_notification_queue_mutex);
74         // search the tail of queue
75         int i = 0;
76         dp_notification_queue_fmt *tailp = *queue;
77         dp_notification_queue_fmt *prevp = NULL;
78         for (; tailp != NULL; i++) {
79                 prevp = tailp;
80                 tailp = tailp->next;
81         }
82         dp_notification_queue_fmt *new_queue = (dp_notification_queue_fmt *)malloc(sizeof(dp_notification_queue_fmt));
83         if (new_queue != NULL) {
84                 new_queue->slot = slot;
85                 new_queue->id = id;
86                 new_queue->state = state;
87                 new_queue->noti_priv_id = noti_priv_id;
88                 new_queue->received_size = received_size;
89                 new_queue->file_size = file_size;
90                 new_queue->type = type;
91                 new_queue->request = request;
92                 new_queue->next = NULL;
93                 if (prevp == NULL)
94                         *queue = new_queue;
95                 else
96                         prevp->next = new_queue;
97                 ret = 0;
98         }
99         //TRACE_DEBUG("queue push %d id:%d", i, id);
100         CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_mutex);
101         return ret;
102 }
103
104 int __dp_notification_queue_pop(dp_notification_queue_fmt **queue, void **slot, void **request, int *id, int *state, int *noti_priv_id, double *received_size, double *file_size, dp_noti_type *type)
105 {
106         if (queue == NULL) {
107                 TRACE_ERROR("check memory address of queue");
108                 return -1;
109         }
110         if (slot == NULL) {
111                 TRACE_ERROR("check client memory address");
112                 return -1;
113         }
114
115         int lock = CLIENT_MUTEX_TRYLOCK(&g_dp_notification_queue_mutex);
116         if (lock != 0) {
117                 TRACE_DEBUG("skip queue is used by other thread");
118                 return 0;
119         }
120         if (queue == NULL || *queue == NULL) {
121                 //TRACE_DEBUG("queue empty");
122                 CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_mutex);
123                 return -1;
124         }
125         // get a head of queue
126         int ret = -1;
127         do {
128                 dp_notification_queue_fmt *popp = *queue;
129                 *queue = popp->next;
130                 if (popp->slot == NULL) {
131                         TRACE_DEBUG("queue error slot:%p id:%d", popp->slot, popp->id);
132                 } else {
133                         *slot = popp->slot;
134                         if (request != NULL)
135                                 *request = popp->request;
136                         *id = popp->id;
137                         *state = popp->state;
138                         if (noti_priv_id != NULL)
139                                 *noti_priv_id = popp->noti_priv_id;
140                         if (received_size != NULL)
141                                 *received_size = popp->received_size;
142                         if (file_size != NULL)
143                                 *file_size = popp->file_size;
144                         *type = popp->type;
145                         ret = 0;
146                         break;
147                 }
148         } while (*queue != NULL); // if meet the tail of queue
149         CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_mutex);
150         return ret;
151 }
152
153 int __dp_notification_queue_ongoing_pop(dp_notification_queue_fmt **queue, void **slot, void **request, int *id, int *state, double *received_size, double *file_size, dp_noti_type *type)
154 {
155         if (queue == NULL) {
156                 TRACE_ERROR("check memory address of queue");
157                 return -1;
158         }
159         if (slot == NULL) {
160                 TRACE_ERROR("check client memory address");
161                 return -1;
162         }
163
164         int lock = CLIENT_MUTEX_TRYLOCK(&g_dp_notification_queue_ongoing_mutex);
165         if (lock != 0) {
166                 TRACE_DEBUG("skip queue is used by other thread");
167                 return 0;
168         }
169         if (queue == NULL || *queue == NULL) {
170                 //TRACE_DEBUG("queue empty");
171                 CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_ongoing_mutex);
172                 return -1;
173         }
174         // get a head of queue
175         int ret = -1;
176         do {
177                 dp_notification_queue_fmt *popp = *queue;
178                 *queue = popp->next;
179                 if (popp->slot == NULL) {
180                         TRACE_DEBUG("queue error slot:%p id:%d", popp->slot, popp->id);
181                 } else {
182                         *slot = popp->slot;
183                         if (request != NULL)
184                                 *request = popp->request;
185                         *id = popp->id;
186                         *state = popp->state;
187                         if (received_size != NULL)
188                                 *received_size = popp->received_size;
189                         if (file_size != NULL)
190                                 *file_size = popp->file_size;
191                         *type = popp->type;
192                         ret = 0;
193                         break;
194                 }
195         } while (*queue != NULL); // if meet the tail of queue
196         CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_ongoing_mutex);
197         return ret;
198 }
199
200 static int __dp_notification_queue_ongoing_push(dp_notification_queue_fmt **queue, void *slot, void *request, const int id, const int state, const double received_size, const double file_size, const dp_noti_type type)
201 {
202         if (queue == NULL) {
203                 TRACE_ERROR("check memory address of queue");
204                 return -1;
205         }
206         if (slot == NULL || request == NULL) {
207                 TRACE_ERROR("check client and request memory address");
208                 return -1;
209         } else if (id <= 0) {
210                 TRACE_ERROR("check slot or download id:%d", id);
211                 return -1;
212         }
213
214         int ret = -1;
215         CLIENT_MUTEX_LOCK(&g_dp_notification_queue_ongoing_mutex);
216         // search the tail of queue
217         int i = 0;
218         dp_notification_queue_fmt *tailp = *queue;
219         dp_notification_queue_fmt *prevp = NULL;
220         for (; tailp != NULL; i++) {
221                 if (tailp->slot == slot && tailp->request == request) {
222                         if (tailp->id == id && tailp->state == state && tailp->type == type) {
223                                 CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_ongoing_mutex);
224                                 return 0;
225                         }
226                 }
227                 prevp = tailp;
228                 tailp = tailp->next;
229         }
230         dp_notification_queue_fmt *new_queue = (dp_notification_queue_fmt *)malloc(sizeof(dp_notification_queue_fmt));
231         if (new_queue != NULL) {
232                 new_queue->slot = slot;
233                 new_queue->id = id;
234                 new_queue->state = state;
235                 new_queue->received_size = received_size;
236                 new_queue->file_size = file_size;
237                 new_queue->type = type;
238                 new_queue->request = request;
239                 new_queue->next = NULL;
240                 if (prevp == NULL)
241                         *queue = new_queue;
242                 else
243                         prevp->next = new_queue;
244                 ret = 0;
245         }
246         //TRACE_DEBUG("queue push %d id:%d", i, id);
247         CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_ongoing_mutex);
248         return ret;
249 }
250
251 void __dp_notification_queue_clear(dp_notification_queue_fmt **queue, const int id)
252 {
253         if (queue == NULL) {
254                 TRACE_ERROR("check memory address of queue");
255                 return ;
256         }
257         CLIENT_MUTEX_LOCK(&g_dp_notification_queue_mutex);
258         int i = 0;
259         dp_notification_queue_fmt *tailp = *queue;
260         dp_notification_queue_fmt *prevp = NULL;
261         for (; tailp != NULL; i++) {
262                 if (tailp->id == id) {
263                         // clear.
264                         if (prevp == NULL)
265                                 *queue = tailp->next;
266                         else
267                                 prevp->next = tailp->next;
268                         TRACE_DEBUG("queue clear this %d id:%d", i, tailp->id);
269                         free(tailp);
270                         break;
271                 }
272                 prevp = tailp;
273                 tailp = tailp->next;
274         }
275         CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_mutex);
276 }
277
278 int dp_notification_manager_clear_notification(void *slot, void *request, const dp_noti_type type)
279 {
280         dp_request_fmt *requestp = request;
281         if (request == NULL) {
282                 TRACE_DEBUG("check address request:%p id:%d",
283                                 request, (request == NULL ? 0 : requestp->id));
284                 return -1;
285         }
286         __dp_notification_queue_clear(&g_dp_notification, requestp->id);
287         TRACE_DEBUG("push clear id:%d noti_priv_id:%d", requestp->id, requestp->noti_priv_id);
288         if (__dp_notification_queue_push(&g_dp_notification_clear, slot, request, requestp->id, requestp->state, -1, 0, 0, type) < 0) {
289                 TRACE_ERROR("failed to push to notification id:%d", requestp->id);
290                 return -1;
291         }
292         dp_notification_manager_wake_up();
293         return 0;
294 }
295
296 int dp_notification_manager_push_notification(void *slot, void *request, const dp_noti_type type)
297 {
298         dp_request_fmt *requestp = request;
299         if (slot == NULL || request == NULL) {
300                 TRACE_DEBUG("check address client:%p request:%p id:%d", slot,
301                                 request, (request == NULL ? 0 : requestp->id));
302                 return -1;
303         }
304 //      TRACE_DEBUG("push noti id:%d noti_priv_id:%d type:%d", requestp->id, requestp->noti_priv_id, type);
305         if (type == DP_NOTIFICATION) {
306                 __dp_notification_queue_clear(&g_dp_notification_ongoing, requestp->id);
307                 if (__dp_notification_queue_push(&g_dp_notification, slot, request, requestp->id, requestp->state, requestp->noti_priv_id, 0, (double)requestp->file_size, type) < 0) {
308                         TRACE_ERROR("failed to push to notification id:%d", requestp->id);
309                         return -1;
310                 }
311         } else {
312                 __dp_notification_queue_clear(&g_dp_notification, requestp->id);
313                 if (__dp_notification_queue_ongoing_push(&g_dp_notification_ongoing, slot, request, requestp->id, requestp->state, (double)requestp->received_size, (double)requestp->file_size, type) < 0) {
314                         TRACE_ERROR("failed to push to notification id:%d", requestp->id);
315                         return -1;
316                 }
317         }
318         dp_notification_manager_wake_up();
319         return 0;
320 }
321
322 static void __dp_notification_manager_check_notification()
323 {
324         int pop_queue = 0;
325         do {
326                 int errorcode = DP_ERROR_NONE;
327                 int download_id = -1;
328                 int state = -1;
329                 dp_noti_type noti_type = -1;
330                 dp_client_slots_fmt *slot = NULL;
331                 dp_request_fmt *request = NULL;
332                 pop_queue = 0;
333                 if (__dp_notification_queue_pop(&g_dp_notification_clear, (void *)&slot, (void *)&request, &download_id, &state, NULL, NULL, NULL, &noti_type) == 0) {
334                         if (slot != NULL) {
335                                 int noti_priv_id = -1;
336                                 if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
337                                         if (request != NULL && request->id == download_id && request->noti_priv_id >= 0) {
338                                                 noti_priv_id = request->noti_priv_id;
339                                                 request->noti_priv_id = -1;
340                                                 if (dp_db_replace_property(slot->client.dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_PRIV_ID, (void *)&request->noti_priv_id, 0, 0, &errorcode) < 0)
341                                                         TRACE_ERROR("failed to set priv_id id:%d error:%s", download_id, dp_print_errorcode(errorcode));
342                                         }
343                                         CLIENT_MUTEX_UNLOCK(&slot->mutex);
344                                 }
345                                 TRACE_DEBUG("clear ongoing id:%d noti_priv_id:%d type:%d", download_id, noti_priv_id, noti_type);
346                                 if (noti_priv_id >= 0) {
347                                         if (noti_type > DP_NOTIFICATION)
348                                                 dp_notification_delete_ongoing(noti_priv_id);
349                                         else
350                                                 dp_notification_delete(noti_priv_id);
351                                 }
352                         }
353                         pop_queue++;
354                         continue;
355                 }
356                 int noti_priv_id = -1;
357                 if (__dp_notification_queue_pop(&g_dp_notification, (void *)&slot, (void *)&request, &download_id, &state, &noti_priv_id, NULL, NULL, &noti_type) == 0) {
358                         if (slot != NULL) {
359                                 __dp_notification_queue_clear(&g_dp_notification_ongoing, download_id); // prevent new ongoing
360                                 if (noti_priv_id >= 0) {
361                                         TRACE_DEBUG("clear ongoing(%d) id:%d type:%d state:%d", noti_priv_id, download_id, noti_type, state);
362                                         dp_notification_delete_ongoing(noti_priv_id);
363                                         noti_priv_id = -1;
364                                 }
365                                 if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
366                                         TRACE_DEBUG("notification id:%d type:%d state:%d", download_id, noti_type, state);
367                                         if (request != NULL && request->id == download_id && request->noti_priv_id >= 0) {
368                                                 dp_notification_delete_ongoing(request->noti_priv_id);
369                                                 request->noti_priv_id = -1;
370                                         }
371                                         dp_content_type content_type = DP_CONTENT_UNKNOWN;
372                                         if (request != NULL)
373                                                 content_type = request->content_type;
374                                         noti_priv_id = dp_notification_new(slot->client.dbhandle, download_id, state, content_type, slot->pkgname); // lazy API
375                                         TRACE_DEBUG("new notification(%d) id:%d type:%d state:%d", noti_priv_id, download_id, noti_type, state);
376                                         if (noti_priv_id < 0) {
377                                                 TRACE_ERROR("failed to register notification for id:%d", download_id);
378                                         } else {
379                                                 if (request != NULL && request->id == download_id)
380                                                         request->noti_priv_id = noti_priv_id;
381                                                 if (dp_db_replace_property(slot->client.dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_PRIV_ID, (void *)&noti_priv_id, 0, 0, &errorcode) < 0)
382                                                         TRACE_ERROR("failed to set priv_id id:%d error:%s", download_id, dp_print_errorcode(errorcode));
383                                         }
384                                         CLIENT_MUTEX_UNLOCK(&slot->mutex);
385                                 }
386                         }
387                         pop_queue++;
388                 }
389                 double received_size = 0;
390                 double file_size = 0;
391                 if (__dp_notification_queue_ongoing_pop(&g_dp_notification_ongoing, (void *)&slot, (void *)&request, &download_id, &state, &received_size, &file_size, &noti_type) == 0) {
392                         if (slot != NULL) {
393                                 int noti_priv_id = -1;
394                                 int request_id = -1;
395                                 if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
396                                         if (request != NULL && request->id == download_id) {
397                                                 request_id = download_id;
398                                                 if (request->noti_priv_id >= 0)
399                                                         noti_priv_id = request->noti_priv_id;
400                                         }
401                                         CLIENT_MUTEX_UNLOCK(&slot->mutex);
402                                 } else {
403                                         TRACE_ERROR("ongoing wrong address id:%d noti_priv_id:%d type:%d state:%d", download_id, noti_priv_id, noti_type, state);
404                                         continue;
405                                 }
406
407                                 if (request_id < 0) {
408                                         TRACE_ERROR("ongoing wrong info id:%d noti_priv_id:%d type:%d state:%d", download_id, noti_priv_id, noti_type, state);
409                                         slot = NULL;
410                                         request = NULL;
411                                         continue;
412                                 }
413                                 if (noti_priv_id < 0 && noti_type > DP_NOTIFICATION_ONGOING) {
414                                         TRACE_DEBUG("ongoing precheck id:%d noti_priv_id:%d type:%d state:%d", download_id, noti_priv_id, noti_type, state);
415                                         noti_type = DP_NOTIFICATION_ONGOING;
416                                 }
417
418                                 TRACE_DEBUG("ongoing id:%d noti_priv_id:%d type:%d state:%d", download_id, noti_priv_id, noti_type, state);
419
420                                 char *subject = NULL;
421                                 if (noti_type == DP_NOTIFICATION || noti_type == DP_NOTIFICATION_ONGOING_UPDATE) {
422                                         unsigned length = 0;
423                                         if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
424                                                 if (request != NULL) {
425                                                         if (dp_db_get_property_string(slot->client.dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_SUBJECT, (unsigned char **)&subject, &length, &errorcode) < 0)
426                                                                 TRACE_ERROR("failed to get subject id:%d error:%s", download_id, dp_print_errorcode(errorcode));
427                                                         else if (subject == NULL && dp_db_get_property_string(slot->client.dbhandle, download_id, DP_TABLE_DOWNLOAD, DP_DB_COL_CONTENT_NAME, (unsigned char **)&subject, &length, &errorcode) < 0)
428                                                                 TRACE_ERROR("failed to get content_name id:%d error:%s", download_id, dp_print_errorcode(errorcode));
429                                                 }
430                                                 CLIENT_MUTEX_UNLOCK(&slot->mutex);
431                                         }
432                                 }
433
434                                 if (noti_type > DP_NOTIFICATION_ONGOING) { // update
435                                         if (noti_priv_id >= 0 && dp_notification_ongoing_update(noti_priv_id, received_size, file_size, subject) < 0)
436                                                 TRACE_ERROR("failed to update ongoing for id:%d", download_id);
437                                 } else { // new ongoing
438                                         if (noti_priv_id >= 0) {
439                                                 TRACE_DEBUG("clear ongoing id:%d noti_priv_id:%d", download_id, noti_priv_id);
440                                                 dp_notification_delete(noti_priv_id);
441                                                 dp_notification_delete_ongoing(noti_priv_id);
442                                                 noti_priv_id = -1;
443                                         }
444                                         unsigned char *raws_buffer = NULL;
445                                         unsigned length = 0;
446                                         if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
447                                                 if (dp_db_get_property_string(slot->client.dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_RAW_ONGOING, &raws_buffer, &length, &errorcode) < 0)
448                                                         TRACE_DEBUG("failed to get bundle raws id:%d error:%s", download_id, dp_print_errorcode(errorcode));
449                                                 CLIENT_MUTEX_UNLOCK(&slot->mutex);
450                                         }
451                                         noti_priv_id = dp_notification_ongoing_new(slot->pkgname, subject, raws_buffer, length);
452                                         TRACE_DEBUG("new ongoing(%d) id:%d type:%d state:%d", noti_priv_id, download_id, noti_type, state);
453                                         free(raws_buffer);
454                                         if (noti_priv_id < 0) {
455                                                 TRACE_ERROR("failed to update ongoing for id:%d", download_id);
456                                         } else {
457                                                 if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
458                                                         if (request != NULL)
459                                                                 request->noti_priv_id = noti_priv_id;
460                                                         if (dp_db_replace_property(slot->client.dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_PRIV_ID, (void *)&noti_priv_id, 0, 0, &errorcode) < 0)
461                                                                 TRACE_ERROR("failed to set priv_id id:%d error:%s", download_id, dp_print_errorcode(errorcode));
462                                                         CLIENT_MUTEX_UNLOCK(&slot->mutex);
463                                                 }
464                                         }
465                                 }
466                                 free(subject);
467                         }
468                         pop_queue++;
469                 }
470         } while (pop_queue > 0);
471 }
472
473 static void *__dp_notification_manager(void *arg)
474 {
475         pthread_cond_init(&g_dp_notification_manager_cond, NULL);
476
477         dp_notification_set_locale();
478
479         while (g_dp_notification_manager_tid > 0) {
480
481                 if (g_dp_notification_manager_tid <= 0) {
482                         TRACE_DEBUG("notification-manager is closed by other thread");
483                         break;
484                 }
485
486                 // check wifi_direct first
487                 __dp_notification_manager_check_notification();
488
489                 CLIENT_MUTEX_LOCK(&g_dp_notification_manager_mutex);
490                 pthread_cond_wait(&g_dp_notification_manager_cond, &g_dp_notification_manager_mutex);
491                 CLIENT_MUTEX_UNLOCK(&g_dp_notification_manager_mutex);
492         }
493
494         TRACE_DEBUG("notification-manager's working is done");
495         dp_notification_clear_locale();
496         pthread_cond_destroy(&g_dp_notification_manager_cond);
497         pthread_exit(NULL);
498         return 0;
499 }
500
501 static int __dp_notification_manager_start()
502 {
503         if (g_dp_notification_manager_tid == 0 ||
504                         pthread_kill(g_dp_notification_manager_tid, 0) == ESRCH) {
505                 TRACE_DEBUG("try to create notification-manager");
506                 if (pthread_create(&g_dp_notification_manager_tid, NULL,
507                                 __dp_notification_manager, NULL) != 0) {
508                         TRACE_ERROR("failed to create notification-manager");
509                         return -1;
510                 }
511         }
512         return 0;
513 }
514
515 void dp_notification_manager_wake_up()
516 {
517         if (g_dp_notification_manager_tid > 0) {
518                 int locked = CLIENT_MUTEX_TRYLOCK(&g_dp_notification_manager_mutex);
519                 if (locked == 0) {
520                         pthread_cond_signal(&g_dp_notification_manager_cond);
521                         CLIENT_MUTEX_UNLOCK(&g_dp_notification_manager_mutex);
522                 }
523         } else {
524                 __dp_notification_manager_start();
525         }
526 }
527
528 void dp_notification_manager_kill()
529 {
530         if (g_dp_notification_manager_tid > 0 &&
531                         pthread_kill(g_dp_notification_manager_tid, 0) != ESRCH) {
532                 //send signal to notification thread
533                 int status;
534                 pthread_t tid;
535                 tid = g_dp_notification_manager_tid;
536                 CLIENT_MUTEX_LOCK(&g_dp_notification_manager_mutex);
537                 g_dp_notification_manager_tid = 0;
538                 pthread_cond_signal(&g_dp_notification_manager_cond);
539                 CLIENT_MUTEX_UNLOCK(&g_dp_notification_manager_mutex);
540                 pthread_join(tid, (void **)&status);
541         }
542 }
543 #else
544
545 int dp_notification_manager_clear_notification(void *slot, void *request, const dp_noti_type type)
546 {
547         return 0;
548 }
549
550 int dp_notification_manager_push_notification(void *slot, void *request, const dp_noti_type type)
551 {
552         return 0;
553 }
554
555 void dp_notification_manager_wake_up()
556 {
557         return;
558 }
559
560 void dp_notification_manager_kill()
561 {
562         return;
563 }
564 #endif