tizen 2.3 release
[kernel/api/system-resource.git] / src / common / notifier.c
1 /*
2  * resourced
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18 */
19
20 #include "macro.h"
21 #include "module.h"
22 #include "module-data.h"
23 #include "notifier.h"
24
25 #include <resourced.h>
26 #include <trace.h>
27 #include <stdlib.h>
28 #include <glib.h>
29
30 struct resourced_notifier {
31         enum notifier_type status;
32         int (*func)(void *data);
33 };
34
35 static GSList *resourced_notifier_list;
36
37 #define FIND_NOTIFIER(a, b, d, e, f) \
38         gslist_for_each(a, b, d) \
39                 if (e == d->e && f == (d->f))
40
41 int register_notifier(enum notifier_type status, int (*func)(void *data))
42 {
43         GSList *n;
44         struct resourced_notifier *notifier;
45
46         _I("%d, %x", status, func);
47
48         if (!func) {
49                 _E("invalid func address!");
50                 return -EINVAL;
51         }
52
53         FIND_NOTIFIER(resourced_notifier_list, n, notifier, status, func) {
54                 _E("function is already registered! [%d, %x]",
55                     status, func);
56                 return -EINVAL;
57         }
58
59         notifier = malloc(sizeof(struct resourced_notifier));
60         if (!notifier) {
61                 _E("Fail to malloc for notifier!");
62                 return -ENOMEM;
63         }
64
65         notifier->status = status;
66         notifier->func = func;
67
68         resourced_notifier_list = g_slist_append(resourced_notifier_list, notifier);
69
70         return 0;
71 }
72
73 int unregister_notifier(enum notifier_type status, int (*func)(void *data))
74 {
75         GSList *n;
76         struct resourced_notifier *notifier;
77
78         if (!func) {
79                 _E("invalid func address!");
80                 return -EINVAL;
81         }
82
83         FIND_NOTIFIER(resourced_notifier_list, n, notifier, status, func) {
84                 _I("[%d, %x]", status, func);
85                 resourced_notifier_list = g_slist_remove(resourced_notifier_list, notifier);
86                 free(notifier);
87         }
88
89         return 0;
90 }
91
92 void resourced_notify(enum notifier_type status, void *data)
93 {
94         GSList *iter;
95         struct resourced_notifier *notifier;
96
97         gslist_for_each_item(iter, resourced_notifier_list) {
98                 notifier = (struct resourced_notifier *)iter->data;
99                 if (status == notifier->status) {
100                         if (notifier->func)
101                                 notifier->func(data);
102                 }
103         }
104 }
105
106 static int notifier_exit(void *data)
107 {
108         GSList *iter;
109         /* Deinitialize in reverse order */
110         GSList *reverse_list = g_slist_reverse(resourced_notifier_list);
111         struct resourced_notifier *notifier;
112
113         gslist_for_each_item(iter, reverse_list) {
114                 notifier = (struct resourced_notifier *)iter->data;
115                 resourced_notifier_list = g_slist_remove(resourced_notifier_list, iter);
116                 free(notifier);
117         }
118         return RESOURCED_ERROR_NONE;
119 }
120
121 static struct module_ops notifier_ops = {
122         .priority = MODULE_PRIORITY_NORMAL,
123         .name     = "notifier",
124         .exit     = notifier_exit,
125 };
126
127 MODULE_REGISTER(&notifier_ops)
128