Allow to set event loop type with api
[platform/core/api/vine.git] / src / vine-event-loop-glib.cpp
1 /*
2  * Copyright (c) 2021 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
18 #if defined USE_VINE_EVENT_LOOP_EXTERNAL_GLIB
19 #include <glib.h>
20 #include <unistd.h>
21 #include <stdint.h>
22
23 #include "vine.h"
24 #include "vine-event-loop.h"
25 #include "vine-queue.h"
26 #include "vine-log.h"
27 #include "vine-utils.h"
28
29 typedef struct {
30         int fd;
31         vine_poll_handler handler;
32         void *user_data;
33         guint g_source_id;
34 } vine_glib_io_event_handler;
35
36 #define MAX_IO_EVENT_HANDLERS FD_SETSIZE
37 static vine_glib_io_event_handler *io_event_handlers[MAX_IO_EVENT_HANDLERS] = {0, };
38
39 #ifdef FD_SETSIZE
40 #define MAX_IO_EVENT_HANDLERS FD_SETSIZE
41 #else
42 #define MAX_IO_EVENT_HANDLERS MAX_VINE_FDS
43 #endif
44
45 int vine_event_loop_glib_init()
46 {
47         return VINE_ERROR_NONE;
48 }
49
50 void vine_event_loop_glib_deinit()
51 {
52 }
53
54 int vine_event_loop_glib_start()
55 {
56         return VINE_ERROR_NONE;
57 }
58
59 void vine_event_loop_glib_stop()
60 {
61 }
62
63 int vine_event_queue_glib_create(vine_event_queue_h *event_queue)
64 {
65         return VINE_ERROR_NONE;
66 }
67
68 void vine_event_queue_glib_destroy(vine_event_queue_h event_queue)
69 {
70 }
71
72 void vine_event_loop_glib_get_eventfd(vine_event_queue_h event_queue, int *eventfd)
73 {
74 }
75
76 static void _add_io_event_handler(int fd, vine_glib_io_event_handler *h)
77 {
78         if (io_event_handlers[fd])
79                 free(io_event_handlers[fd]);
80         io_event_handlers[fd] = h;
81 }
82
83 static void _del_io_event_handler(int fd)
84 {
85         if (io_event_handlers[fd]) {
86                 free(io_event_handlers[fd]);
87                 io_event_handlers[fd] = NULL;
88         }
89 }
90
91 static vine_glib_io_event_handler *_find_io_event_handler(int fd)
92 {
93         return io_event_handlers[fd];
94 }
95
96 static int convert_glib_cond_to_poll_events(GIOCondition condition)
97 {
98         int events = 0;
99         if (condition & G_IO_IN)
100                 events |= VINE_POLLIN;
101         if (condition & G_IO_OUT)
102                 events |= VINE_POLLOUT;
103         if (condition & G_IO_HUP)
104                 events |= VINE_POLLHUP;
105         return events;
106 }
107
108 static GIOCondition convert_poll_events_to_glib_cond(int events)
109 {
110         int cond = 0;
111         if (events & VINE_POLLIN)
112                 cond |= G_IO_IN;
113         if (events & VINE_POLLOUT)
114                 cond |= G_IO_OUT;
115         if (events & VINE_POLLHUP)
116                 cond |= G_IO_HUP;
117         return (GIOCondition)cond;
118 }
119
120 static gboolean __vine_glib_io_handler(GIOChannel *source,
121             GIOCondition condition,
122             gpointer data)
123 {
124         RET_VAL_IF(data == NULL, TRUE, "vine_glib_io_event_handler is NULL");
125         vine_glib_io_event_handler *h = (vine_glib_io_event_handler *)data;
126         if (h->handler)
127                 h->handler(h->fd, convert_glib_cond_to_poll_events(condition), h->user_data);
128         return TRUE;
129 }
130
131 int vine_event_loop_glib_add_io_handler(
132         int fd, int events, vine_poll_handler handler, void *user_data)
133 {
134         RET_VAL_IF(fd < 0, VINE_ERROR_INVALID_PARAMETER,
135                 "fd should be equal to or greater than zero");
136         RET_VAL_IF(handler == NULL, VINE_ERROR_INVALID_PARAMETER,
137                 "handler should not be null");
138
139         vine_glib_io_event_handler *h =
140                 (vine_glib_io_event_handler *)calloc(1, sizeof(vine_glib_io_event_handler));
141         RET_VAL_IF(h == NULL, VINE_ERROR_OUT_OF_MEMORY, "Out of memory");
142         h->fd = fd;
143         h->handler = handler;
144         h->user_data = user_data;
145
146         GIOChannel *ch = g_io_channel_unix_new(fd);
147         g_io_channel_set_flags(ch, G_IO_FLAG_NONBLOCK, NULL);
148         g_io_channel_set_close_on_unref(ch, FALSE);
149         h->g_source_id  = g_io_add_watch(ch,
150                 convert_poll_events_to_glib_cond(events), __vine_glib_io_handler, h);
151
152         _add_io_event_handler(fd, h);
153         return VINE_ERROR_NONE;
154 }
155
156 int vine_event_loop_glib_del_io_handler(int fd)
157 {
158         RET_VAL_IF(fd < 0, VINE_ERROR_INVALID_PARAMETER,
159                 "fd should be equal to or greater than zero");
160
161         vine_glib_io_event_handler *handler = _find_io_event_handler(fd);
162         if (handler == NULL) {
163                 VINE_LOGE("vine_glib_io_event_handler is NULL for fd %d", fd);
164                 return VINE_ERROR_INVALID_PARAMETER;
165         }
166         g_source_remove(handler->g_source_id);
167         _del_io_event_handler(fd);
168         VINE_LOGD("Del an glib event. fd: %d", fd);
169
170         return VINE_ERROR_NONE;
171 }
172
173 int vine_event_loop_glib_mod_io_handler(
174         int fd, int events, vine_poll_handler handler, void *user_data)
175 {
176         RET_VAL_IF(fd < 0, VINE_ERROR_INVALID_PARAMETER,
177                 "fd should be equal to or greater than zero");
178         RET_VAL_IF(handler == NULL, VINE_ERROR_INVALID_PARAMETER,
179                 "handler should not be null");
180
181         vine_event_loop_glib_del_io_handler(fd);
182         vine_event_loop_glib_add_io_handler(fd, events, handler, user_data);
183         VINE_LOGD("Modify an glib event. fd: %d event: %d", fd, events);
184
185         return VINE_ERROR_NONE;
186 }
187
188 int vine_event_loop_glib_add_event(vine_event_queue_h event_queue, void *event_data,
189         vine_event_handler handler, vine_event_free_handler free_func,
190         void *user_data)
191 {
192         // Ignore event_queue
193
194         RET_VAL_IF(handler == NULL, VINE_ERROR_INVALID_PARAMETER, "handler is NULL");
195         VINE_LOGD("event_data[%p]", event_data);
196
197         handler(event_data, user_data);
198         if (free_func)
199                 free_func(event_data);
200
201         return VINE_ERROR_NONE;
202 }
203
204 int vine_event_loop_glib_process(vine_event_queue_h event_queue)
205 {
206         return VINE_ERROR_NONE;
207 }
208
209 vine_event_loop_fn vine_event_loop_glib = {
210         .init = vine_event_loop_glib_init,
211         .deinit = vine_event_loop_glib_deinit,
212         .start = vine_event_loop_glib_start,
213         .stop = vine_event_loop_glib_stop,
214         .event_queue_create = vine_event_queue_glib_create,
215         .event_queue_destroy = vine_event_queue_glib_destroy,
216         .get_eventfd = vine_event_loop_glib_get_eventfd,
217         .process = vine_event_loop_glib_process,
218         .add_io_handler = vine_event_loop_glib_add_io_handler,
219         .mod_io_handler = vine_event_loop_glib_mod_io_handler,
220         .del_io_handler = vine_event_loop_glib_del_io_handler,
221         .add_event = vine_event_loop_glib_add_event,
222 };
223
224 #endif // USE_VINE_EVENT_LOOP_EXTERNAL_GLIB