summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2016-05-06 15:33:36 -0700
committerCedric BAIL <cedric@osg.samsung.com>2016-05-06 15:35:36 -0700
commitc96383e42c8d8b2de64ebbe14fc9fe02eb09f037 (patch)
tree0c4b217001bb02699617a05461f5199a44c810f6
parent45d17f100e927ee90ea782a387893add0e7f3fbd (diff)
ecore: add Efl.Loop.Fd.
This allow you to monitor fd and get notification using Eo events. I have not implemented the buffered read as used by X. I think that if this is useful, we should just do another class to handle bufferred fd.
-rw-r--r--src/Makefile_Ecore.am2
-rw-r--r--src/lib/ecore/Ecore_Eo.h2
-rw-r--r--src/lib/ecore/efl_loop_fd.c177
-rw-r--r--src/lib/ecore/efl_loop_fd.eo46
4 files changed, 227 insertions, 0 deletions
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am
index fbbd4f3..197dbd2 100644
--- a/src/Makefile_Ecore.am
+++ b/src/Makefile_Ecore.am
@@ -10,6 +10,7 @@ ecore_eolian_files_legacy = \
10ecore_eolian_files = \ 10ecore_eolian_files = \
11 lib/ecore/efl_loop.eo \ 11 lib/ecore/efl_loop.eo \
12 lib/ecore/efl_loop_user.eo \ 12 lib/ecore/efl_loop_user.eo \
13 lib/ecore/efl_loop_fd.eo \
13 lib/ecore/ecore_parent.eo \ 14 lib/ecore/ecore_parent.eo \
14 $(ecore_eolian_files_legacy) 15 $(ecore_eolian_files_legacy)
15 16
@@ -60,6 +61,7 @@ lib/ecore/ecore_idler.c \
60lib/ecore/ecore_job.c \ 61lib/ecore/ecore_job.c \
61lib/ecore/ecore_main.c \ 62lib/ecore/ecore_main.c \
62lib/ecore/efl_loop_user.c \ 63lib/ecore/efl_loop_user.c \
64lib/ecore/efl_loop_fd.c \
63lib/ecore/ecore_pipe.c \ 65lib/ecore/ecore_pipe.c \
64lib/ecore/ecore_poller.c \ 66lib/ecore/ecore_poller.c \
65lib/ecore/ecore_time.c \ 67lib/ecore/ecore_time.c \
diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h
index 3106489..10e9c42 100644
--- a/src/lib/ecore/Ecore_Eo.h
+++ b/src/lib/ecore/Ecore_Eo.h
@@ -64,6 +64,8 @@ extern "C" {
64 64
65#include "efl_loop_user.eo.h" 65#include "efl_loop_user.eo.h"
66 66
67#include "efl_loop_fd.eo.h"
68
67/* We ue the factory pattern here, so you shouldn't call eo_add directly. */ 69/* We ue the factory pattern here, so you shouldn't call eo_add directly. */
68EAPI Eo *ecore_main_loop_get(void); 70EAPI Eo *ecore_main_loop_get(void);
69 71
diff --git a/src/lib/ecore/efl_loop_fd.c b/src/lib/ecore/efl_loop_fd.c
new file mode 100644
index 0000000..fbef974
--- /dev/null
+++ b/src/lib/ecore/efl_loop_fd.c
@@ -0,0 +1,177 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Ecore.h>
6
7#include "ecore_private.h"
8
9#define MY_CLASS EFL_LOOP_FD_CLASS
10
11typedef struct _Efl_Loop_Fd_Data Efl_Loop_Fd_Data;
12struct _Efl_Loop_Fd_Data
13{
14 Ecore_Fd_Handler *handler;
15
16 struct {
17 unsigned int read;
18 unsigned int write;
19 unsigned int error;
20 } references;
21
22 int fd;
23
24 Eina_Bool file : 1;
25};
26
27static Eina_Bool
28_efl_loop_fd_read_cb(void *data, Ecore_Fd_Handler *fd_handler)
29{
30 Eo *obj = data;
31
32 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
33 {
34 eo_event_callback_call(obj, EFL_LOOP_FD_EVENT_READ, NULL);
35 }
36 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
37 {
38 eo_event_callback_call(obj, EFL_LOOP_FD_EVENT_WRITE, NULL);
39 }
40 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR))
41 {
42 eo_event_callback_call(obj, EFL_LOOP_FD_EVENT_ERROR, NULL);
43 }
44
45 return ECORE_CALLBACK_RENEW;
46}
47
48static void
49_efl_loop_fd_reset(Eo *obj, Efl_Loop_Fd_Data *pd)
50{
51 int flags = 0;
52
53 if (pd->handler) ecore_main_fd_handler_del(pd->handler);
54 pd->handler = NULL;
55 if (pd->fd < 0) return ;
56 flags |= pd->references.read > 0 ? ECORE_FD_READ : 0;
57 flags |= pd->references.write > 0 ? ECORE_FD_WRITE : 0;
58 flags |= pd->references.error > 0 ? ECORE_FD_ERROR : 0;
59 if (flags == 0) return ;
60
61 if (pd->file)
62 pd->handler = ecore_main_fd_handler_file_add(pd->fd, flags, _efl_loop_fd_read_cb, obj, NULL, NULL);
63 else
64 pd->handler = ecore_main_fd_handler_add(pd->fd, flags, _efl_loop_fd_read_cb, obj, NULL, NULL);
65}
66
67static void
68_efl_loop_fd_fd_set(Eo *obj, Efl_Loop_Fd_Data *pd, int fd)
69{
70 pd->fd = fd;
71 pd->file = EINA_FALSE;
72 _efl_loop_fd_reset(obj, pd);
73}
74
75static int
76_efl_loop_fd_fd_get(Eo *obj EINA_UNUSED, Efl_Loop_Fd_Data *pd)
77{
78 return pd->file ? -1 : pd->fd;
79}
80
81static void
82_efl_loop_fd_fd_file_set(Eo *obj, Efl_Loop_Fd_Data *pd, int fd)
83{
84 pd->fd = fd;
85 pd->file = EINA_TRUE;
86 _efl_loop_fd_reset(obj, pd);
87}
88
89static int
90_efl_loop_fd_fd_file_get(Eo *obj EINA_UNUSED, Efl_Loop_Fd_Data *pd)
91{
92 return pd->file ? pd->fd : -1;
93}
94
95static Eina_Bool
96_check_fd_event_catcher_add(void *data, const Eo_Event *event)
97{
98 const Eo_Callback_Array_Item *array = event->info;
99 Efl_Loop_Fd_Data *fd = data;
100 int i;
101
102 for (i = 0; array[i].desc != NULL; i++)
103 {
104 if (array[i].desc == EFL_LOOP_FD_EVENT_READ)
105 {
106 if (fd->references.read++ > 0) continue;
107 _efl_loop_fd_reset(event->obj, fd);
108 }
109 else if (array[i].desc == EFL_LOOP_FD_EVENT_WRITE)
110 {
111 if (fd->references.write++ > 0) continue;
112 _efl_loop_fd_reset(event->obj, fd);
113 }
114 if (array[i].desc == EFL_LOOP_FD_EVENT_ERROR)
115 {
116 if (fd->references.error++ > 0) continue;
117 _efl_loop_fd_reset(event->obj, fd);
118 }
119 }
120
121 return EO_CALLBACK_CONTINUE;
122}
123
124static Eina_Bool
125_check_fd_event_catcher_del(void *data, const Eo_Event *event)
126{
127 const Eo_Callback_Array_Item *array = event->info;
128 Efl_Loop_Fd_Data *fd = data;
129 int i;
130
131 for (i = 0; array[i].desc != NULL; i++)
132 {
133 if (array[i].desc == EFL_LOOP_FD_EVENT_READ)
134 {
135 if (fd->references.read++ > 0) continue;
136 _efl_loop_fd_reset(event->obj, fd);
137 }
138 else if (array[i].desc == EFL_LOOP_FD_EVENT_WRITE)
139 {
140 if (fd->references.write++ > 0) continue;
141 _efl_loop_fd_reset(event->obj, fd);
142 }
143 if (array[i].desc == EFL_LOOP_FD_EVENT_ERROR)
144 {
145 if (fd->references.error++ > 0) continue;
146 _efl_loop_fd_reset(event->obj, fd);
147 }
148 }
149
150 return EO_CALLBACK_CONTINUE;
151}
152
153EO_CALLBACKS_ARRAY_DEFINE(fd_watch,
154 { EO_BASE_EVENT_CALLBACK_ADD, _check_fd_event_catcher_add },
155 { EO_BASE_EVENT_CALLBACK_DEL, _check_fd_event_catcher_del });
156
157static Eo_Base *
158_efl_loop_fd_eo_base_constructor(Eo *obj, Efl_Loop_Fd_Data *pd)
159{
160 eo_constructor(eo_super(obj, MY_CLASS));
161
162 eo_event_callback_array_add(obj, fd_watch(), pd);
163
164 pd->fd = -1;
165
166 return obj;
167}
168
169static void
170_efl_loop_fd_eo_base_destructor(Eo *obj, Efl_Loop_Fd_Data *pd)
171{
172 eo_destructor(eo_super(obj, MY_CLASS));
173
174 ecore_main_fd_handler_del(pd->handler);
175}
176
177#include "efl_loop_fd.eo.c"
diff --git a/src/lib/ecore/efl_loop_fd.eo b/src/lib/ecore/efl_loop_fd.eo
new file mode 100644
index 0000000..1be9f0a
--- /dev/null
+++ b/src/lib/ecore/efl_loop_fd.eo
@@ -0,0 +1,46 @@
1import eina_types;
2
3class Efl.Loop.Fd (Efl.Loop_User)
4{
5 [[Fds are objects that what the activity on a given
6 file descriptor. This file descriptor can be a
7 network, a file, provided by a library.
8
9 The object will trigger relevant event depending
10 on what is happening.]]
11
12 legacy_prefix: null;
13 methods {
14 @property fd {
15 [[Define which file descriptor to watch. If it is a file, use file_fd variant.]]
16 set {
17 [[Define the fd to watch on.]]
18 }
19 get {
20 }
21 values {
22 fd: int; [[The file descriptor.]]
23 }
24 }
25 @property fd_file {
26 [[Define which file descriptor to watch when watching a file.]]
27 set {
28 [[Define the fd to watch on.]]
29 }
30 get {
31 }
32 values {
33 fd: int; [[The file descriptor.]]
34 }
35 }
36 }
37 events {
38 read;
39 write;
40 error;
41 }
42 implements {
43 Eo.Base.constructor;
44 Eo.Base.destructor;
45 }
46}