Release version 1.3.1
[platform/core/appfw/app-core.git] / src / appcore-noti.c
1 /*
2  *  app-core
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <errno.h>
29
30 #include <heynoti.h>
31
32 #include "appcore-internal.h"
33
34 #define NOTI_COMP(a, b) (strcmp(a->name, b->name))
35
36 struct noti_s {
37         const char *name;
38         void *data;
39         int (*cb_pre) (void *);
40         int (*cb) (void *);
41         int (*cb_post) (void *);
42
43         struct noti_s *next;
44 };
45 typedef struct noti_s notis;
46
47
48 SGLIB_DEFINE_LIST_PROTOTYPES(notis, NOTI_COMP, next);
49 SGLIB_DEFINE_LIST_FUNCTIONS(notis, NOTI_COMP, next);
50
51 static struct noti_s *noti_h;
52
53 static void __main_handle(void *data)
54 {
55         struct noti_s *n = data;
56
57         _ret_if(n == NULL || n->name == NULL);
58
59         _DBG("[APP %d] noti: %s", getpid(), n->name);
60
61         if (n->cb_pre)
62                 n->cb_pre(n->data);
63
64         if (n->cb)
65                 n->cb(n->data);
66
67         if (n->cb_post)
68                 n->cb_post(n->data);
69 }
70
71 static int __del_noti(int fd, struct noti_s *t)
72 {
73         int r;
74
75         r = heynoti_unsubscribe(fd, t->name, __main_handle);
76         if (r == 0) {
77                 sglib_notis_delete(&noti_h, t);
78                 free((void *)t->name);
79                 free(t);
80         }
81
82         return r;
83 }
84
85 static int __del_notis(int fd)
86 {
87         struct sglib_notis_iterator it;
88         struct noti_s *t;
89
90         t = sglib_notis_it_init(&it, noti_h);
91         while (t) {
92                 __del_noti(fd, t);
93                 t = sglib_notis_it_next(&it);
94         }
95
96         return 0;
97 }
98
99 int add_noti(int fd, const char *name, int (*cb_pre) (void *),
100              int (*cb) (void *), int (*cb_post) (void *), void *data)
101 {
102         int r;
103         struct noti_s *t;
104
105         if (fd < 0) {
106                 errno = EBADF;
107                 return -1;
108         }
109
110         if (name == NULL || name[0] == '\0') {
111                 errno = EINVAL;
112                 return -1;
113         }
114
115         t = calloc(1, sizeof(struct noti_s));
116         if (t == NULL)
117                 return -1;
118
119         t->name = strdup(name);
120         if (t->name == NULL) {
121                 free(t);
122                 return -1;
123         }
124
125         t->cb_pre = cb_pre;
126         t->cb = cb;
127         t->cb_post = cb_post;
128         t->data = data;
129
130         r = heynoti_subscribe(fd, name, __main_handle, t);
131         if (r != 0) {
132                 free((void *)t->name);
133                 free(t);
134                 return -1;
135         }
136
137         sglib_notis_add(&noti_h, t);
138
139         return r;
140 }
141
142 int del_noti(int fd, const char *name)
143 {
144         struct noti_s t;
145         struct noti_s *f;
146
147         if (fd < 0) {
148                 errno = EBADF;
149                 return -1;
150         }
151
152         t.name = name;
153         f = sglib_notis_find_member(noti_h, &t);
154         if (f == NULL) {
155                 errno = ENOENT;
156                 return -1;
157         }
158
159         return __del_noti(fd, f);
160 }
161
162 int noti_start(int fd)
163 {
164         return heynoti_attach_handler(fd);
165 }
166
167 int noti_init(void)
168 {
169         return heynoti_init();
170 }
171
172 void noti_exit(int *fd)
173 {
174         _ret_if(fd == NULL || *fd < 0);
175
176         __del_notis(*fd);
177
178         heynoti_close(*fd);
179
180         *fd = -1;
181 }