57164fdcb50bdf392320671911efe0943b17cbba
[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                         }
137                         *id = popp->id;
138                         *state = popp->state;
139                         if (noti_priv_id != NULL)
140                                 *noti_priv_id = popp->noti_priv_id;
141                         if (received_size != NULL)
142                                 *received_size = popp->received_size;
143                         if (file_size != NULL)
144                                 *file_size = popp->file_size;
145                         *type = popp->type;
146                         ret = 0;
147                         break;
148                 }
149         } while (*queue != NULL); // if meet the tail of queue
150         CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_mutex);
151         return ret;
152 }
153
154 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)
155 {
156         if (queue == NULL) {
157                 TRACE_ERROR("check memory address of queue");
158                 return -1;
159         }
160         if (slot == NULL) {
161                 TRACE_ERROR("check client memory address");
162                 return -1;
163         }
164
165         int lock = CLIENT_MUTEX_TRYLOCK(&g_dp_notification_queue_ongoing_mutex);
166         if (lock != 0) {
167                 TRACE_DEBUG("skip queue is used by other thread");
168                 return 0;
169         }
170         if (queue == NULL || *queue == NULL) {
171                 //TRACE_DEBUG("queue empty");
172                 CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_ongoing_mutex);
173                 return -1;
174         }
175         // get a head of queue
176         int ret = -1;
177         do {
178                 dp_notification_queue_fmt *popp = *queue;
179                 *queue = popp->next;
180                 if (popp->slot == NULL) {
181                         TRACE_DEBUG("queue error slot:%p id:%d", popp->slot, popp->id);
182                 } else {
183                         *slot = popp->slot;
184                         if (request != NULL) {
185                                 *request = popp->request;
186                         }
187                         *id = popp->id;
188                         *state = popp->state;
189                         if (received_size != NULL)
190                                 *received_size = popp->received_size;
191                         if (file_size != NULL)
192                                 *file_size = popp->file_size;
193                         *type = popp->type;
194                         ret = 0;
195                         break;
196                 }
197         } while (*queue != NULL); // if meet the tail of queue
198         CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_ongoing_mutex);
199         return ret;
200 }
201
202 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)
203 {
204         if (queue == NULL) {
205                 TRACE_ERROR("check memory address of queue");
206                 return -1;
207         }
208         if (slot == NULL || request == NULL) {
209                 TRACE_ERROR("check client and request memory address");
210                 return -1;
211         } else if (id <= 0) {
212                 TRACE_ERROR("check slot or download id:%d", id);
213                 return -1;
214         }
215
216         int ret = -1;
217         CLIENT_MUTEX_LOCK(&g_dp_notification_queue_ongoing_mutex);
218         // search the tail of queue
219         int i = 0;
220         dp_notification_queue_fmt *tailp = *queue;
221         dp_notification_queue_fmt *prevp = NULL;
222         for (; tailp != NULL; i++) {
223                 if (tailp->slot == slot && tailp->request == request) {
224                         if (tailp->id == id && tailp->state == state && tailp->type == type) {
225                                 CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_ongoing_mutex);
226                                 return 0;
227                         }
228                 }
229                 prevp = tailp;
230                 tailp = tailp->next;
231         }
232         dp_notification_queue_fmt *new_queue = (dp_notification_queue_fmt *)malloc(sizeof(dp_notification_queue_fmt));
233         if (new_queue != NULL) {
234                 new_queue->slot = slot;
235                 new_queue->id = id;
236                 new_queue->state = state;
237                 new_queue->received_size = received_size;
238                 new_queue->file_size = file_size;
239                 new_queue->type = type;
240                 new_queue->request = request;
241                 new_queue->next = NULL;
242                 if (prevp == NULL)
243                         *queue = new_queue;
244                 else
245                         prevp->next = new_queue;
246                 ret = 0;
247         }
248         //TRACE_DEBUG("queue push %d id:%d", i, id);
249         CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_ongoing_mutex);
250         return ret;
251 }
252
253 void __dp_notification_queue_clear(dp_notification_queue_fmt **queue, const int id)
254 {
255         if (queue == NULL) {
256                 TRACE_ERROR("check memory address of queue");
257                 return ;
258         }
259         CLIENT_MUTEX_LOCK(&g_dp_notification_queue_mutex);
260         int i = 0;
261         dp_notification_queue_fmt *tailp = *queue;
262         dp_notification_queue_fmt *prevp = NULL;
263         for (; tailp != NULL; i++) {
264                 if (tailp->id == id) {
265                         // clear.
266                         if (prevp == NULL)
267                                 *queue = tailp->next;
268                         else
269                                 prevp->next = tailp->next;
270                         TRACE_DEBUG("queue clear this %d id:%d", i, tailp->id);
271                         free(tailp);
272                         break;
273                 }
274                 prevp = tailp;
275                 tailp = tailp->next;
276         }
277         CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_mutex);
278 }
279
280 int dp_notification_manager_clear_notification(void *slot, void *request, const dp_noti_type type)
281 {
282         dp_request_fmt *requestp = request;
283         if (request == NULL) {
284                 TRACE_DEBUG("check address request:%p id:%d",
285                                 request, (request == NULL ? 0 : requestp->id));
286                 return -1;
287         }
288         __dp_notification_queue_clear(&g_dp_notification, requestp->id);
289         TRACE_DEBUG("push clear id:%d noti_priv_id:%d", requestp->id, requestp->noti_priv_id);
290         if (__dp_notification_queue_push(&g_dp_notification_clear, slot, request, requestp->id, requestp->state, -1, 0, 0, type) < 0) {
291                 TRACE_ERROR("failed to push to notification id:%d", requestp->id);
292                 return -1;
293         }
294         dp_notification_manager_wake_up();
295         return 0;
296 }
297
298 int dp_notification_manager_push_notification(void *slot, void *request, const dp_noti_type type)
299 {
300         dp_request_fmt *requestp = request;
301         if (slot == NULL || request == NULL) {
302                 TRACE_DEBUG("check address client:%p request:%p id:%d", slot,
303                                 request, (request == NULL ? 0 : requestp->id));
304                 return -1;
305         }
306 //      TRACE_DEBUG("push noti id:%d noti_priv_id:%d type:%d", requestp->id, requestp->noti_priv_id, type);
307         if (type == DP_NOTIFICATION) {
308                 __dp_notification_queue_clear(&g_dp_notification_ongoing, requestp->id);
309                 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) {
310                         TRACE_ERROR("failed to push to notification id:%d", requestp->id);
311                         return -1;
312                 }
313         } else {
314                 __dp_notification_queue_clear(&g_dp_notification, requestp->id);
315                 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) {
316                         TRACE_ERROR("failed to push to notification id:%d", requestp->id);
317                         return -1;
318                 }
319         }
320         dp_notification_manager_wake_up();
321         return 0;
322 }
323
324 static void __dp_notification_manager_check_notification()
325 {
326         int pop_queue = 0;
327         do {
328                 int errorcode = DP_ERROR_NONE;
329                 int download_id = -1;
330                 int state = -1;
331                 dp_noti_type noti_type = -1;
332                 dp_client_slots_fmt *slot = NULL;
333                 dp_request_fmt *request = NULL;
334                 pop_queue = 0;
335                 if (__dp_notification_queue_pop(&g_dp_notification_clear, (void *)&slot, (void *)&request, &download_id, &state, NULL, NULL, NULL, &noti_type) == 0) {
336                         if (slot != NULL) {
337                                 int noti_priv_id = -1;
338                                 if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
339                                         if (request != NULL && request->id == download_id && request->noti_priv_id >= 0) {
340                                                 noti_priv_id = request->noti_priv_id;
341                                                 request->noti_priv_id = -1;
342                                                 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) {
343                                                         TRACE_ERROR("failed to set priv_id id:%d error:%s", download_id, dp_print_errorcode(errorcode));
344                                                 }
345                                         }
346                                         CLIENT_MUTEX_UNLOCK(&slot->mutex);
347                                 }
348                                 TRACE_DEBUG("clear ongoing id:%d noti_priv_id:%d type:%d", download_id, noti_priv_id, noti_type);
349                                 if (noti_priv_id >= 0) {
350                                         if (noti_type > DP_NOTIFICATION)
351                                                 dp_notification_delete_ongoing(noti_priv_id);
352                                         else
353                                                 dp_notification_delete(noti_priv_id);
354                                 }
355                         }
356                         pop_queue++;
357                         continue;
358                 }
359                 int noti_priv_id = -1;
360                 if (__dp_notification_queue_pop(&g_dp_notification, (void *)&slot, (void *)&request, &download_id, &state, &noti_priv_id, NULL, NULL, &noti_type) == 0) {
361                         if (slot != NULL) {
362                                 __dp_notification_queue_clear(&g_dp_notification_ongoing, download_id); // prevent new ongoing
363                                 if (noti_priv_id >= 0) {
364                                         TRACE_DEBUG("clear ongoing(%d) id:%d type:%d state:%d", noti_priv_id, download_id, noti_type, state);
365                                         dp_notification_delete_ongoing(noti_priv_id);
366                                         noti_priv_id = -1;
367                                 }
368                                 if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
369                                         TRACE_DEBUG("notification id:%d type:%d state:%d", download_id, noti_type, state);
370                                         if (request != NULL && request->id == download_id && request->noti_priv_id >= 0) {
371                                                 dp_notification_delete_ongoing(request->noti_priv_id);
372                                                 request->noti_priv_id = -1;
373                                         }
374                                         dp_content_type content_type = DP_CONTENT_UNKNOWN;
375                                         if (request != NULL)
376                                                 content_type = request->content_type;
377                                         noti_priv_id = dp_notification_new(slot->client.dbhandle, download_id, state, content_type, slot->pkgname); // lazy API
378                                         TRACE_DEBUG("new notification(%d) id:%d type:%d state:%d", noti_priv_id, download_id, noti_type, state);
379                                         if (noti_priv_id < 0) {
380                                                 TRACE_ERROR("failed to register notification for id:%d", download_id);
381                                         } else {
382                                                 if (request != NULL && request->id == download_id) {
383                                                         request->noti_priv_id = noti_priv_id;
384                                                 }
385                                                 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) {
386                                                         TRACE_ERROR("failed to set priv_id id:%d error:%s", download_id, dp_print_errorcode(errorcode));
387                                                 }
388                                         }
389                                         CLIENT_MUTEX_UNLOCK(&slot->mutex);
390                                 }
391                         }
392                         pop_queue++;
393                 }
394                 double received_size = 0;
395                 double file_size = 0;
396                 if (__dp_notification_queue_ongoing_pop(&g_dp_notification_ongoing, (void *)&slot, (void *)&request, &download_id, &state, &received_size, &file_size, &noti_type) == 0) {
397                         if (slot != NULL) {
398                                 int noti_priv_id = -1;
399                                 int request_id = -1;
400                                 if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
401                                         if (request != NULL && request->id == download_id) {
402                                                 request_id = download_id;
403                                                 if (request->noti_priv_id >= 0) {
404                                                         noti_priv_id = request->noti_priv_id;
405                                                 }
406                                         }
407                                         CLIENT_MUTEX_UNLOCK(&slot->mutex);
408                                 } else {
409                                         TRACE_ERROR("ongoing wrong address id:%d noti_priv_id:%d type:%d state:%d", download_id, noti_priv_id, noti_type, state);
410                                         continue;
411                                 }
412
413                                 if (request_id < 0) {
414                                         TRACE_ERROR("ongoing wrong info id:%d noti_priv_id:%d type:%d state:%d", download_id, noti_priv_id, noti_type, state);
415                                         slot = NULL;
416                                         request = NULL;
417                                         continue;
418                                 }
419                                 if (noti_priv_id < 0 && noti_type > DP_NOTIFICATION_ONGOING) {
420                                         TRACE_DEBUG("ongoing precheck id:%d noti_priv_id:%d type:%d state:%d", download_id, noti_priv_id, noti_type, state);
421                                         noti_type = DP_NOTIFICATION_ONGOING;
422                                 }
423
424                                 TRACE_DEBUG("ongoing id:%d noti_priv_id:%d type:%d state:%d", download_id, noti_priv_id, noti_type, state);
425
426                                 char *subject = NULL;
427                                 if (noti_type == DP_NOTIFICATION || noti_type == DP_NOTIFICATION_ONGOING_UPDATE) {
428                                         unsigned length = 0;
429                                         if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
430                                                 if (request != NULL) {
431                                                         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) {
432                                                                 TRACE_ERROR("failed to get subject id:%d error:%s", download_id, dp_print_errorcode(errorcode));
433                                                         } 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) {
434                                                                 TRACE_ERROR("failed to get content_name id:%d error:%s", download_id, dp_print_errorcode(errorcode));
435                                                         }
436                                                 }
437                                                 CLIENT_MUTEX_UNLOCK(&slot->mutex);
438                                         }
439                                 }
440
441                                 if (noti_type > DP_NOTIFICATION_ONGOING) { // update
442                                         if (noti_priv_id >= 0 && dp_notification_ongoing_update(noti_priv_id, received_size, file_size, subject) < 0) {
443                                                 TRACE_ERROR("failed to update ongoing for id:%d", download_id);
444                                         }
445                                 } else { // new ongoing
446                                         if (noti_priv_id >= 0) {
447                                                 TRACE_DEBUG("clear ongoing id:%d noti_priv_id:%d", download_id, noti_priv_id);
448                                                 dp_notification_delete(noti_priv_id);
449                                                 dp_notification_delete_ongoing(noti_priv_id);
450                                                 noti_priv_id = -1;
451                                         }
452                                         unsigned char *raws_buffer = NULL;
453                                         unsigned length = 0;
454                                         if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
455                                                 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) {
456                                                         TRACE_DEBUG("failed to get bundle raws id:%d error:%s", download_id, dp_print_errorcode(errorcode));
457                                                 }
458                                                 CLIENT_MUTEX_UNLOCK(&slot->mutex);
459                                         }
460                                         noti_priv_id = dp_notification_ongoing_new(slot->pkgname, subject, raws_buffer, length);
461                                         TRACE_DEBUG("new ongoing(%d) id:%d type:%d state:%d", noti_priv_id, download_id, noti_type, state);
462                                         free(raws_buffer);
463                                         if (noti_priv_id < 0) {
464                                                 TRACE_ERROR("failed to update ongoing for id:%d", download_id);
465                                         } else {
466                                                 if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
467                                                         if (request != NULL)
468                                                                 request->noti_priv_id = noti_priv_id;
469                                                         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) {
470                                                                 TRACE_ERROR("failed to set priv_id id:%d error:%s", download_id, dp_print_errorcode(errorcode));
471                                                         }
472                                                         CLIENT_MUTEX_UNLOCK(&slot->mutex);
473                                                 }
474                                         }
475                                 }
476                                 free(subject);
477                         }
478                         pop_queue++;
479                 }
480         } while (pop_queue > 0);
481 }
482
483 static void *__dp_notification_manager(void *arg)
484 {
485         pthread_cond_init(&g_dp_notification_manager_cond, NULL);
486
487         dp_notification_set_locale();
488
489         while (g_dp_notification_manager_tid > 0) {
490
491                 if (g_dp_notification_manager_tid <= 0) {
492                         TRACE_DEBUG("notification-manager is closed by other thread");
493                         break;
494                 }
495
496                 // check wifi_direct first
497                 __dp_notification_manager_check_notification();
498
499                 CLIENT_MUTEX_LOCK(&g_dp_notification_manager_mutex);
500                 pthread_cond_wait(&g_dp_notification_manager_cond, &g_dp_notification_manager_mutex);
501                 CLIENT_MUTEX_UNLOCK(&g_dp_notification_manager_mutex);
502         }
503
504         TRACE_DEBUG("notification-manager's working is done");
505         dp_notification_clear_locale();
506         pthread_cond_destroy(&g_dp_notification_manager_cond);
507         pthread_exit(NULL);
508         return 0;
509 }
510
511 static int __dp_notification_manager_start()
512 {
513         if (g_dp_notification_manager_tid == 0 ||
514                         pthread_kill(g_dp_notification_manager_tid, 0) == ESRCH) {
515                 TRACE_DEBUG("try to create notification-manager");
516                 if (pthread_create(&g_dp_notification_manager_tid, NULL,
517                                 __dp_notification_manager, NULL) != 0) {
518                         TRACE_ERROR("failed to create notification-manager");
519                         return -1;
520                 }
521         }
522         return 0;
523 }
524
525 void dp_notification_manager_wake_up()
526 {
527         if (g_dp_notification_manager_tid > 0) {
528                 int locked = CLIENT_MUTEX_TRYLOCK(&g_dp_notification_manager_mutex);
529                 if (locked == 0) {
530                         pthread_cond_signal(&g_dp_notification_manager_cond);
531                         CLIENT_MUTEX_UNLOCK(&g_dp_notification_manager_mutex);
532                 }
533         } else {
534                 __dp_notification_manager_start();
535         }
536 }
537
538 void dp_notification_manager_kill()
539 {
540         if (g_dp_notification_manager_tid > 0 &&
541                         pthread_kill(g_dp_notification_manager_tid, 0) != ESRCH) {
542                 //send signal to notification thread
543                 int status;
544                 pthread_t tid;
545                 tid = g_dp_notification_manager_tid;
546                 CLIENT_MUTEX_LOCK(&g_dp_notification_manager_mutex);
547                 g_dp_notification_manager_tid = 0;
548                 pthread_cond_signal(&g_dp_notification_manager_cond);
549                 CLIENT_MUTEX_UNLOCK(&g_dp_notification_manager_mutex);
550                 pthread_join(tid, (void **)&status);
551         }
552 }
553 #else
554
555 int dp_notification_manager_clear_notification(void *slot, void *request, const dp_noti_type type)
556 {
557         return 0;
558 }
559
560 int dp_notification_manager_push_notification(void *slot, void *request, const dp_noti_type type)
561 {
562         return 0;
563 }
564
565 void dp_notification_manager_wake_up()
566 {
567         return;
568 }
569
570 void dp_notification_manager_kill()
571 {
572         return;
573 }
574 #endif