summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Makefile_Ecore.am9
-rw-r--r--src/lib/ecore/Ecore_Eo.h4
-rw-r--r--src/lib/ecore/ecore.c10
-rw-r--r--src/lib/ecore/ecore_exe.c2
-rw-r--r--src/lib/ecore/ecore_main.c8
-rw-r--r--src/lib/ecore/ecore_private.h17
-rw-r--r--src/lib/ecore/ecore_signal.c9
-rw-r--r--src/lib/ecore/ecore_timer.c4
-rw-r--r--src/lib/ecore/efl_app.c415
-rw-r--r--src/lib/ecore/efl_app.eo57
-rw-r--r--src/lib/ecore/efl_appthread.c245
-rw-r--r--src/lib/ecore/efl_appthread.eo22
-rw-r--r--src/lib/ecore/efl_exe.c28
-rw-r--r--src/lib/ecore/efl_general.h6
-rw-r--r--src/lib/ecore/efl_loop.c94
-rw-r--r--src/lib/ecore/efl_loop.eo36
-rw-r--r--src/lib/ecore/efl_loop_fd.c4
-rw-r--r--src/lib/ecore/efl_loop_handler.c2
-rw-r--r--src/lib/ecore/efl_task.c11
-rw-r--r--src/lib/ecore/efl_thread.c917
-rw-r--r--src/lib/ecore/efl_thread.eo10
-rw-r--r--src/lib/ecore_evas/ecore_evas.c4
-rw-r--r--src/lib/eina/eina_internal.h2
-rw-r--r--src/lib/eina/eina_promise.c21
-rw-r--r--src/lib/elementary/efl_ui_text.c6
-rw-r--r--src/lib/elementary/efl_ui_win.c12
-rw-r--r--src/lib/elementary/elm_entry.c6
-rw-r--r--src/lib/elementary/elm_main.c8
-rw-r--r--src/lib/eo/Eo.h19
-rw-r--r--src/lib/eo/eo_base_class.c56
-rw-r--r--src/lib/evas/canvas/evas_callbacks.c4
-rw-r--r--src/tests/ecore/ecore_test_ecore.c6
-rw-r--r--src/tests/elementary/efl_ui_suite.c4
-rw-r--r--src/tests/eo/signals/signals_simple.c4
-rw-r--r--src/tests/eo/suite/eo_test_general.c6
35 files changed, 1882 insertions, 186 deletions
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am
index 28a46d374d..630977846d 100644
--- a/src/Makefile_Ecore.am
+++ b/src/Makefile_Ecore.am
@@ -8,6 +8,7 @@ ecore_eolian_files_legacy = \
8 lib/ecore/efl_loop_timer.eo 8 lib/ecore/efl_loop_timer.eo
9 9
10ecore_eolian_files_public = \ 10ecore_eolian_files_public = \
11 lib/ecore/efl_app.eo \
11 lib/ecore/efl_loop.eo \ 12 lib/ecore/efl_loop.eo \
12 lib/ecore/efl_loop_consumer.eo \ 13 lib/ecore/efl_loop_consumer.eo \
13 lib/ecore/efl_loop_fd.eo \ 14 lib/ecore/efl_loop_fd.eo \
@@ -16,6 +17,8 @@ ecore_eolian_files_public = \
16 lib/ecore/efl_loop_message_handler.eo \ 17 lib/ecore/efl_loop_message_handler.eo \
17 lib/ecore/efl_exe.eo \ 18 lib/ecore/efl_exe.eo \
18 lib/ecore/efl_thread.eo \ 19 lib/ecore/efl_thread.eo \
20 lib/ecore/efl_appthread.eo \
21 lib/ecore/efl_task.eo \
19 lib/ecore/efl_io_closer_fd.eo \ 22 lib/ecore/efl_io_closer_fd.eo \
20 lib/ecore/efl_io_positioner_fd.eo \ 23 lib/ecore/efl_io_positioner_fd.eo \
21 lib/ecore/efl_io_reader_fd.eo \ 24 lib/ecore/efl_io_reader_fd.eo \
@@ -35,8 +38,7 @@ ecore_eolian_files_public = \
35 lib/ecore/efl_interpolator_divisor.eo \ 38 lib/ecore/efl_interpolator_divisor.eo \
36 lib/ecore/efl_interpolator_bounce.eo \ 39 lib/ecore/efl_interpolator_bounce.eo \
37 lib/ecore/efl_interpolator_spring.eo \ 40 lib/ecore/efl_interpolator_spring.eo \
38 lib/ecore/efl_interpolator_cubic_bezier.eo \ 41 lib/ecore/efl_interpolator_cubic_bezier.eo
39 lib/ecore/efl_task.eo
40 42
41ecore_eolian_files = \ 43ecore_eolian_files = \
42 $(ecore_eolian_files_public) \ 44 $(ecore_eolian_files_public) \
@@ -95,6 +97,7 @@ lib/ecore/ecore_job.c \
95lib/ecore/ecore_main.c \ 97lib/ecore/ecore_main.c \
96lib/ecore/ecore_event_message.c \ 98lib/ecore/ecore_event_message.c \
97lib/ecore/ecore_event_message_handler.c \ 99lib/ecore/ecore_event_message_handler.c \
100lib/ecore/efl_app.c \
98lib/ecore/efl_loop.c \ 101lib/ecore/efl_loop.c \
99lib/ecore/efl_loop_consumer.c \ 102lib/ecore/efl_loop_consumer.c \
100lib/ecore/efl_loop_fd.c \ 103lib/ecore/efl_loop_fd.c \
@@ -134,6 +137,8 @@ lib/ecore/efl_interpolator_spring.c \
134lib/ecore/efl_interpolator_cubic_bezier.c \ 137lib/ecore/efl_interpolator_cubic_bezier.c \
135lib/ecore/efl_task.c \ 138lib/ecore/efl_task.c \
136lib/ecore/efl_exe.c \ 139lib/ecore/efl_exe.c \
140lib/ecore/efl_thread.c \
141lib/ecore/efl_appthread.c \
137lib/ecore/ecore_main_timechanges.c \ 142lib/ecore/ecore_main_timechanges.c \
138lib/ecore/ecore_pipe.c \ 143lib/ecore/ecore_pipe.c \
139lib/ecore/ecore_poller.c \ 144lib/ecore/ecore_poller.c \
diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h
index f5ce92d805..be4df7e377 100644
--- a/src/lib/ecore/Ecore_Eo.h
+++ b/src/lib/ecore/Ecore_Eo.h
@@ -45,9 +45,12 @@
45#include "efl_loop_message_handler.eo.h" 45#include "efl_loop_message_handler.eo.h"
46 46
47#include "efl_task.eo.h" 47#include "efl_task.eo.h"
48#include "efl_thread.eo.h"
48#include "efl_exe.eo.h" 49#include "efl_exe.eo.h"
49 50
50#include "efl_loop.eo.h" 51#include "efl_loop.eo.h"
52#include "efl_app.eo.h"
53#include "efl_appthread.eo.h"
51 54
52/** 55/**
53 * @brief Quits the main loop once all the events currently on the queue have 56 * @brief Quits the main loop once all the events currently on the queue have
@@ -103,6 +106,7 @@ EAPI Eina_Promise *efl_loop_promise_new(const Eo *obj, Eina_Promise_Cancel_Cb ca
103 106
104/* We ue the factory pattern here, so you shouldn't call eo_add directly. */ 107/* We ue the factory pattern here, so you shouldn't call eo_add directly. */
105EAPI Eo *efl_main_loop_get(void); 108EAPI Eo *efl_main_loop_get(void);
109EAPI Eo *efl_app_get(void);
106 110
107typedef struct _Efl_Future_Composite_Progress Efl_Future_All_Progress; 111typedef struct _Efl_Future_Composite_Progress Efl_Future_All_Progress;
108 112
diff --git a/src/lib/ecore/ecore.c b/src/lib/ecore/ecore.c
index d911bc4e23..754b826314 100644
--- a/src/lib/ecore/ecore.c
+++ b/src/lib/ecore/ecore.c
@@ -215,8 +215,7 @@ _efl_first_loop_iterate(void *data, const Efl_Event *event)
215 case 'T': fprintf(stderr, "Loop started: '%f' - '%f' = '%f' sec\n", end, _efl_startup_time, end - _efl_startup_time); 215 case 'T': fprintf(stderr, "Loop started: '%f' - '%f' = '%f' sec\n", end, _efl_startup_time, end - _efl_startup_time);
216 break; 216 break;
217 } 217 }
218 218 efl_event_callback_del(event->object, EFL_APP_EVENT_RESUME,
219 efl_event_callback_del(event->object, EFL_LOOP_EVENT_RESUME,
220 _efl_first_loop_iterate, data); 219 _efl_first_loop_iterate, data);
221} 220}
222 221
@@ -345,13 +344,11 @@ ecore_init(void)
345 344
346 if (!_no_system_modules) 345 if (!_no_system_modules)
347 ecore_system_modules_load(); 346 ecore_system_modules_load();
348
349 if (getenv("EFL_FIRST_LOOP")) 347 if (getenv("EFL_FIRST_LOOP"))
350 efl_event_callback_add(efl_main_loop_get(), 348 efl_event_callback_add(efl_main_loop_get(),
351 EFL_LOOP_EVENT_RESUME, 349 EFL_APP_EVENT_RESUME,
352 _efl_first_loop_iterate, 350 _efl_first_loop_iterate,
353 getenv("EFL_FIRST_LOOP")); 351 getenv("EFL_FIRST_LOOP"));
354
355 _ecore_init_count_threshold = _ecore_init_count; 352 _ecore_init_count_threshold = _ecore_init_count;
356 353
357 eina_log_timing(_ecore_log_dom, 354 eina_log_timing(_ecore_log_dom,
@@ -390,8 +387,7 @@ ecore_shutdown(void)
390 } 387 }
391 if (_ecore_init_count-- != _ecore_init_count_threshold) 388 if (_ecore_init_count-- != _ecore_init_count_threshold)
392 goto end; 389 goto end;
393 390 efl_event_callback_call(efl_main_loop_get(), EFL_APP_EVENT_TERMINATE, NULL);
394 efl_event_callback_call(efl_main_loop_get(), EFL_LOOP_EVENT_TERMINATE, NULL);
395 391
396 ecore_system_modules_unload(); 392 ecore_system_modules_unload();
397 393
diff --git a/src/lib/ecore/ecore_exe.c b/src/lib/ecore/ecore_exe.c
index 908f677539..781dea60bd 100644
--- a/src/lib/ecore/ecore_exe.c
+++ b/src/lib/ecore/ecore_exe.c
@@ -66,7 +66,7 @@ ecore_exe_pipe_run(const char *exe_cmd,
66 const void *data) 66 const void *data)
67{ 67{
68 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 68 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
69 Ecore_Exe *ret = efl_add(MY_CLASS, efl_loop_main_get(EFL_LOOP_CLASS), 69 Ecore_Exe *ret = efl_add(MY_CLASS, efl_main_loop_get(),
70 ecore_obj_exe_command_set(efl_added, exe_cmd, 70 ecore_obj_exe_command_set(efl_added, exe_cmd,
71 flags)); 71 flags));
72 if (ret) 72 if (ret)
diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index bc3c6c84a9..ebd572bb65 100644
--- a/src/lib/ecore/ecore_main.c
+++ b/src/lib/ecore/ecore_main.c
@@ -1372,7 +1372,7 @@ ecore_main_fd_handler_add(int fd,
1372{ 1372{
1373 Ecore_Fd_Handler *fdh = NULL; 1373 Ecore_Fd_Handler *fdh = NULL;
1374 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 1374 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
1375 fdh = _ecore_main_fd_handler_add(efl_loop_main_get(EFL_LOOP_CLASS), 1375 fdh = _ecore_main_fd_handler_add(efl_main_loop_get(),
1376 ML_DAT, NULL, fd, flags, func, data, 1376 ML_DAT, NULL, fd, flags, func, data,
1377 buf_func, buf_data, EINA_FALSE); 1377 buf_func, buf_data, EINA_FALSE);
1378 if (fdh) fdh->legacy = EINA_TRUE; 1378 if (fdh) fdh->legacy = EINA_TRUE;
@@ -1388,7 +1388,7 @@ ecore_main_fd_handler_file_add(int fd,
1388 const void *buf_data) 1388 const void *buf_data)
1389{ 1389{
1390 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 1390 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
1391 return _ecore_main_fd_handler_add(efl_loop_main_get(EFL_LOOP_CLASS), 1391 return _ecore_main_fd_handler_add(efl_main_loop_get(),
1392 ML_DAT, NULL, fd, flags, func, data, 1392 ML_DAT, NULL, fd, flags, func, data,
1393 buf_func, buf_data, EINA_TRUE); 1393 buf_func, buf_data, EINA_TRUE);
1394} 1394}
@@ -1595,7 +1595,7 @@ ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler,
1595} 1595}
1596 1596
1597void 1597void
1598_ecore_main_content_clear(Efl_Loop_Data *pd) 1598_ecore_main_content_clear(Eo *obj, Efl_Loop_Data *pd)
1599{ 1599{
1600 Efl_Promise *promise; 1600 Efl_Promise *promise;
1601 Efl_Future *future; 1601 Efl_Future *future;
@@ -1608,7 +1608,7 @@ _ecore_main_content_clear(Efl_Loop_Data *pd)
1608 ecore_loop_promise_fulfill(promise); 1608 ecore_loop_promise_fulfill(promise);
1609 1609
1610 // FIXME 1610 // FIXME
1611 __eina_promise_cancel_all(); 1611 __eina_promise_cancel_data(obj);
1612 1612
1613 while (pd->fd_handlers) 1613 while (pd->fd_handlers)
1614 { 1614 {
diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h
index 7ff80f57c3..7e44bf4acb 100644
--- a/src/lib/ecore/ecore_private.h
+++ b/src/lib/ecore/ecore_private.h
@@ -88,6 +88,7 @@ typedef struct _Efl_Loop_Future_Scheduler Efl_Loop_Future_Scheduler;
88typedef struct _Efl_Loop_Data Efl_Loop_Data; 88typedef struct _Efl_Loop_Data Efl_Loop_Data;
89 89
90typedef struct _Efl_Task_Data Efl_Task_Data; 90typedef struct _Efl_Task_Data Efl_Task_Data;
91typedef struct _Efl_Appthread_Data Efl_Appthread_Data;
91 92
92typedef struct _Message_Handler Message_Handler; 93typedef struct _Message_Handler Message_Handler;
93typedef struct _Message Message; 94typedef struct _Message Message;
@@ -193,6 +194,18 @@ struct _Efl_Task_Data
193 Eina_Bool exited : 1; 194 Eina_Bool exited : 1;
194}; 195};
195 196
197struct _Efl_Appthread_Data
198{
199 struct {
200 int in, out;
201 Eo *in_handler, *out_handler;
202 Eina_Bool can_read : 1;
203 Eina_Bool eos_read : 1;
204 Eina_Bool can_write : 1;
205 } fd, ctrl;
206 int read_listeners;
207};
208
196 209
197#define EVAS_FRAME_QUEUING 1 /* for test */ 210#define EVAS_FRAME_QUEUING 1 /* for test */
198 211
@@ -325,7 +338,7 @@ _ecore_main_win32_handler_del(Eo *obj,
325 Efl_Loop_Data *pd, 338 Efl_Loop_Data *pd,
326 Ecore_Win32_Handler *win32_handler); 339 Ecore_Win32_Handler *win32_handler);
327 340
328void _ecore_main_content_clear(Efl_Loop_Data *pd); 341void _ecore_main_content_clear(Eo *obj, Efl_Loop_Data *pd);
329void _ecore_main_shutdown(void); 342void _ecore_main_shutdown(void);
330 343
331#if defined (_WIN32) || defined (__lv2ppu__) || defined (HAVE_EXOTIC) 344#if defined (_WIN32) || defined (__lv2ppu__) || defined (HAVE_EXOTIC)
@@ -525,7 +538,7 @@ void ecore_loop_promise_fulfill(Efl_Promise *p);
525// access to direct input cb 538// access to direct input cb
526#define ECORE_EVAS_INTERNAL 539#define ECORE_EVAS_INTERNAL
527 540
528#define EFL_LOOP_DATA efl_data_scope_get(efl_loop_main_get(EFL_LOOP_CLASS), EFL_LOOP_CLASS) 541#define EFL_LOOP_DATA efl_data_scope_get(efl_main_loop_get(), EFL_LOOP_CLASS)
529 542
530EOAPI Eina_Bool efl_loop_message_process(Eo *obj); 543EOAPI Eina_Bool efl_loop_message_process(Eo *obj);
531 544
diff --git a/src/lib/ecore/ecore_signal.c b/src/lib/ecore/ecore_signal.c
index 98934e63b3..616f22b4ee 100644
--- a/src/lib/ecore/ecore_signal.c
+++ b/src/lib/ecore/ecore_signal.c
@@ -78,9 +78,9 @@ _ecore_signal_pipe_read(Eo *obj)
78 if (loop) 78 if (loop)
79 { 79 {
80 if (sdata.sig == SIGUSR1) 80 if (sdata.sig == SIGUSR1)
81 efl_event_callback_call(loop, EFL_LOOP_EVENT_SIGNAL_USR1, NULL); 81 efl_event_callback_call(loop, EFL_APP_EVENT_SIGNAL_USR1, NULL);
82 else 82 else
83 efl_event_callback_call(loop, EFL_LOOP_EVENT_SIGNAL_USR2, NULL); 83 efl_event_callback_call(loop, EFL_APP_EVENT_SIGNAL_USR2, NULL);
84 } 84 }
85 } 85 }
86 break; 86 break;
@@ -95,7 +95,7 @@ _ecore_signal_pipe_read(Eo *obj)
95 } 95 }
96 Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS); 96 Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS);
97 if (loop) 97 if (loop)
98 efl_event_callback_call(loop, EFL_LOOP_EVENT_SIGNAL_HUP, NULL); 98 efl_event_callback_call(loop, EFL_APP_EVENT_SIGNAL_HUP, NULL);
99 } 99 }
100 break; 100 break;
101 case SIGQUIT: 101 case SIGQUIT:
@@ -112,6 +112,9 @@ _ecore_signal_pipe_read(Eo *obj)
112 ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, 112 ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e,
113 _ecore_signal_generic_free, NULL); 113 _ecore_signal_generic_free, NULL);
114 } 114 }
115 Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS);
116 if (loop)
117 efl_event_callback_call(loop, EFL_TASK_EVENT_EXIT, NULL);
115 } 118 }
116 break; 119 break;
117#ifdef SIGPWR 120#ifdef SIGPWR
diff --git a/src/lib/ecore/ecore_timer.c b/src/lib/ecore/ecore_timer.c
index 6ef4ab254c..7805f79de2 100644
--- a/src/lib/ecore/ecore_timer.c
+++ b/src/lib/ecore/ecore_timer.c
@@ -74,7 +74,7 @@ static void
74_check_timer_event_catcher_add(void *data, const Efl_Event *event) 74_check_timer_event_catcher_add(void *data, const Efl_Event *event)
75{ 75{
76 Efl_Loop_Timer_Data *timer = data; 76 Efl_Loop_Timer_Data *timer = data;
77 const Efl_Callback_Array_Item *array = event->info; 77 const Efl_Callback_Array_Item_Full *array = event->info;
78 int i; 78 int i;
79 79
80 for (i = 0; array[i].desc != NULL; i++) 80 for (i = 0; array[i].desc != NULL; i++)
@@ -94,7 +94,7 @@ static void
94_check_timer_event_catcher_del(void *data, const Efl_Event *event) 94_check_timer_event_catcher_del(void *data, const Efl_Event *event)
95{ 95{
96 Efl_Loop_Timer_Data *timer = data; 96 Efl_Loop_Timer_Data *timer = data;
97 const Efl_Callback_Array_Item *array = event->info; 97 const Efl_Callback_Array_Item_Full *array = event->info;
98 int i; 98 int i;
99 99
100 for (i = 0; array[i].desc != NULL; i++) 100 for (i = 0; array[i].desc != NULL; i++)
diff --git a/src/lib/ecore/efl_app.c b/src/lib/ecore/efl_app.c
new file mode 100644
index 0000000000..b6e2b1f29d
--- /dev/null
+++ b/src/lib/ecore/efl_app.c
@@ -0,0 +1,415 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#define EFL_IO_READER_PROTECTED 1
6#define EFL_IO_WRITER_PROTECTED 1
7#define EFL_IO_CLOSER_PROTECTED 1
8
9#include <Ecore.h>
10
11#include "ecore_private.h"
12
13#ifndef _WIN32
14# include <sys/resource.h>
15#endif
16
17#define MY_CLASS EFL_APP_CLASS
18
19typedef struct _Efl_App_Data Efl_App_Data;
20
21struct _Efl_App_Data
22{
23 struct {
24 int in, out;
25 Eo *in_handler, *out_handler;
26 Eina_Bool can_read : 1;
27 Eina_Bool eos_read : 1;
28 Eina_Bool can_write : 1;
29 } fd;
30 int read_listeners;
31};
32
33Efl_Version _app_efl_version = { 0, 0, 0, 0, NULL, NULL };
34
35//////////////////////////////////////////////////////////////////////////
36
37EAPI Eo *
38efl_app_get(void)
39{
40 return efl_main_loop_get();
41}
42
43//////////////////////////////////////////////////////////////////////////
44
45static void
46_parent_read_listeners_modify(Efl_App_Data *pd, int mod)
47{
48 pd->read_listeners += mod;
49
50 if (pd->fd.out_handler)
51 {
52 if ((pd->read_listeners == 0) && (mod < 0))
53 efl_loop_handler_active_set
54 (pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_NONE);
55 else if ((pd->read_listeners == 1) && (mod > 0))
56 efl_loop_handler_active_set
57 (pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_READ);
58 }
59}
60
61static void
62_cb_event_callback_add(void *data, const Efl_Event *event)
63{
64 Efl_App_Data *pd = data;
65 const Efl_Callback_Array_Item_Full *array = event->info;
66 int i;
67
68 for (i = 0; array[i].desc != NULL; i++)
69 {
70 if (array[i].desc == EFL_IO_READER_EVENT_CAN_READ_CHANGED)
71 _parent_read_listeners_modify(pd, 1);
72 }
73}
74
75static void
76_cb_event_callback_del(void *data, const Efl_Event *event)
77{
78 Efl_App_Data *pd = data;
79 const Efl_Callback_Array_Item_Full *array = event->info;
80 int i;
81
82 for (i = 0; array[i].desc != NULL; i++)
83 {
84 if (array[i].desc == EFL_IO_READER_EVENT_CAN_READ_CHANGED)
85 _parent_read_listeners_modify(pd, -1);
86 }
87}
88
89static void
90_cb_out(void *data, const Efl_Event *event EINA_UNUSED)
91{
92 Eo *obj = data;
93 efl_io_reader_can_read_set(obj, EINA_TRUE);
94}
95
96static void
97_cb_in(void *data, const Efl_Event *event EINA_UNUSED)
98{
99 Eo *obj = data;
100 efl_io_writer_can_write_set(obj, EINA_TRUE);
101}
102
103
104EFL_CALLBACKS_ARRAY_DEFINE(_event_callback_watch,
105 { EFL_EVENT_CALLBACK_ADD, _cb_event_callback_add },
106 { EFL_EVENT_CALLBACK_DEL, _cb_event_callback_del });
107
108//////////////////////////////////////////////////////////////////////////
109
110EOLIAN static Efl_Loop *
111_efl_app_loop_main_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED)
112{
113 if (_mainloop_singleton) return _mainloop_singleton;
114 _mainloop_singleton = efl_add(EFL_APP_CLASS, NULL);
115 _mainloop_singleton_data = efl_data_scope_get(_mainloop_singleton, EFL_LOOP_CLASS);
116 return _mainloop_singleton;
117}
118
119EOLIAN static const Efl_Version *
120_efl_app_build_efl_version_get(Eo *obj EINA_UNUSED, Efl_App_Data *pd EINA_UNUSED)
121{
122 return &_app_efl_version;
123}
124
125EOLIAN static const Efl_Version *
126_efl_app_efl_version_get(Eo *obj EINA_UNUSED, Efl_App_Data *pd EINA_UNUSED)
127{
128 /* vanilla EFL: flavor = NULL */
129 static const Efl_Version version = {
130 .major = VMAJ,
131 .minor = VMIN,
132 .micro = VMIC,
133 .revision = VREV,
134 .build_id = EFL_BUILD_ID,
135 .flavor = NULL
136 };
137 return &version;
138}
139
140EOLIAN static Efl_Object *
141_efl_app_efl_object_constructor(Eo *obj, Efl_App_Data *pd)
142{
143 obj = efl_constructor(efl_super(obj, MY_CLASS));
144 efl_event_callback_array_add(obj, _event_callback_watch(), pd);
145 pd->fd.in = 1;
146 pd->fd.out = 0;
147 pd->fd.can_write = EINA_TRUE;
148 pd->fd.in_handler =
149 efl_add(EFL_LOOP_HANDLER_CLASS, obj,
150 efl_loop_handler_fd_set(efl_added, pd->fd.in),
151 efl_event_callback_add
152 (efl_added, EFL_LOOP_HANDLER_EVENT_WRITE, _cb_in, obj));
153 pd->fd.out_handler =
154 efl_add(EFL_LOOP_HANDLER_CLASS, obj,
155 efl_loop_handler_fd_set(efl_added, pd->fd.out),
156 efl_event_callback_add
157 (efl_added, EFL_LOOP_HANDLER_EVENT_READ, _cb_out, obj));
158 return obj;
159}
160
161EOLIAN static void
162_efl_app_efl_object_destructor(Eo *obj, Efl_App_Data *pd)
163{
164 efl_del(pd->fd.in_handler);
165 efl_del(pd->fd.out_handler);
166 pd->fd.in_handler = NULL;
167 pd->fd.out_handler = NULL;
168 pd->fd.in = -1;
169 pd->fd.out = -1;
170 efl_destructor(efl_super(obj, MY_CLASS));
171}
172
173EOLIAN static Eina_Error
174_efl_app_efl_io_closer_close(Eo *obj, Efl_App_Data *pd)
175{
176 EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(obj), EBADF);
177 efl_io_writer_can_write_set(obj, EINA_FALSE);
178 efl_io_reader_can_read_set(obj, EINA_FALSE);
179 efl_io_reader_eos_set(obj, EINA_TRUE);
180 if (pd->fd.in_handler) efl_del(pd->fd.in_handler);
181 if (pd->fd.out_handler) efl_del(pd->fd.out_handler);
182 pd->fd.in = -1;
183 pd->fd.out = -1;
184 pd->fd.in_handler = NULL;
185 pd->fd.out_handler = NULL;
186 return 0;
187}
188
189EOLIAN static Eina_Bool
190_efl_app_efl_io_closer_closed_get(Eo *obj EINA_UNUSED, Efl_App_Data *pd)
191{
192 if ((pd->fd.in == -1) && (pd->fd.out == -1)) return EINA_TRUE;
193 return EINA_FALSE;
194}
195
196EOLIAN static Eina_Error
197_efl_app_efl_io_reader_read(Eo *obj, Efl_App_Data *pd, Eina_Rw_Slice *rw_slice)
198{
199 ssize_t r;
200
201 errno = 0;
202 if (pd->fd.out == -1) goto err;
203
204 do
205 {
206 errno = 0;
207 r = read(pd->fd.out, rw_slice->mem, rw_slice->len);
208 if (r == -1)
209 {
210 if (errno == EINTR) continue;
211 goto err;
212 }
213 }
214 while (r == -1);
215
216 rw_slice->len = r;
217 if (r == 0)
218 {
219 efl_io_reader_can_read_set(obj, EINA_FALSE);
220 efl_io_reader_eos_set(obj, EINA_TRUE);
221 close(pd->fd.out);
222 pd->fd.out = -1;
223 efl_del(pd->fd.out_handler);
224 pd->fd.out_handler = NULL;
225 return EPIPE;
226 }
227 return 0;
228err:
229 if ((pd->fd.out != -1) && (errno != EAGAIN))
230 {
231 close(pd->fd.out);
232 pd->fd.out = -1;
233 efl_del(pd->fd.out_handler);
234 pd->fd.out_handler = NULL;
235 }
236 rw_slice->len = 0;
237 rw_slice->mem = NULL;
238 efl_io_reader_can_read_set(obj, EINA_FALSE);
239 return EINVAL;
240}
241
242EOLIAN static void
243_efl_app_efl_io_reader_can_read_set(Eo *obj, Efl_App_Data *pd, Eina_Bool can_read)
244{
245 Eina_Bool old = efl_io_reader_can_read_get(obj);
246 if (old == can_read) return;
247 pd->fd.can_read = can_read;
248 if (can_read)
249 efl_loop_handler_active_set(pd->fd.in_handler, 0);
250 else
251 efl_loop_handler_active_set(pd->fd.in_handler,
252 EFL_LOOP_HANDLER_FLAGS_READ);
253 efl_event_callback_call(obj, EFL_IO_READER_EVENT_CAN_READ_CHANGED, NULL);
254}
255
256EOLIAN static Eina_Bool
257_efl_app_efl_io_reader_can_read_get(Eo *obj EINA_UNUSED, Efl_App_Data *pd)
258{
259 return pd->fd.can_read;
260}
261
262EOLIAN static void
263_efl_app_efl_io_reader_eos_set(Eo *obj, Efl_App_Data *pd, Eina_Bool is_eos)
264{
265 Eina_Bool old = efl_io_reader_eos_get(obj);
266 if (old == is_eos) return;
267
268 pd->fd.eos_read = is_eos;
269 if (!is_eos) return;
270 if (pd->fd.out_handler)
271 efl_loop_handler_active_set(pd->fd.out_handler, 0);
272 efl_event_callback_call(obj, EFL_IO_READER_EVENT_EOS, NULL);
273}
274
275EOLIAN static Eina_Bool
276_efl_app_efl_io_reader_eos_get(Eo *obj EINA_UNUSED, Efl_App_Data *pd)
277{
278 return pd->fd.eos_read;
279}
280
281EOLIAN static Eina_Error
282_efl_app_efl_io_writer_write(Eo *obj, Efl_App_Data *pd, Eina_Slice *slice, Eina_Slice *remaining)
283{
284 ssize_t r;
285
286 errno = 0;
287 if (pd->fd.in == -1) goto err;
288
289 do
290 {
291 errno = 0;
292 r = write(pd->fd.in, slice->mem, slice->len);
293 if (r == -1)
294 {
295 if (errno == EINTR) continue;
296 goto err;
297 }
298 }
299 while (r == -1);
300
301 if (remaining)
302 {
303 remaining->len = slice->len - r;
304 remaining->bytes = slice->bytes + r;
305 }
306 slice->len = r;
307
308 if ((slice) && (slice->len > 0))
309 efl_io_writer_can_write_set(obj, EINA_FALSE);
310 if (r == 0)
311 {
312 close(pd->fd.in);
313 pd->fd.in = -1;
314 efl_del(pd->fd.in_handler);
315 pd->fd.in_handler = NULL;
316 return EPIPE;
317 }
318 return 0;
319err:
320 if ((pd->fd.in != -1) && (errno != EAGAIN))
321 {
322 close(pd->fd.in);
323 pd->fd.in = -1;
324 efl_del(pd->fd.in_handler);
325 pd->fd.in_handler = NULL;
326 }
327 if (remaining) *remaining = *slice;
328 slice->len = 0;
329 slice->mem = NULL;
330 efl_io_writer_can_write_set(obj, EINA_FALSE);
331 return EINVAL;
332}
333
334EOLIAN static void
335_efl_app_efl_io_writer_can_write_set(Eo *obj, Efl_App_Data *pd, Eina_Bool can_write)
336{
337 Eina_Bool old = efl_io_writer_can_write_get(obj);
338 if (old == can_write) return;
339 pd->fd.can_write = can_write;
340 if (can_write)
341 efl_loop_handler_active_set(pd->fd.in_handler, 0);
342 else
343 efl_loop_handler_active_set(pd->fd.in_handler,
344 EFL_LOOP_HANDLER_FLAGS_WRITE);
345 efl_event_callback_call(obj, EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED, NULL);
346}
347
348EOLIAN static Eina_Bool
349_efl_app_efl_io_writer_can_write_get(Eo *obj EINA_UNUSED, Efl_App_Data *pd)
350{
351 return pd->fd.can_write;
352}
353
354#ifdef _WIN32
355#else
356static const signed char primap[EFL_TASK_PRIORITY_ULTRA + 1] =
357{
358 10, // EFL_TASK_PRIORITY_NORMAL
359 19, // EFL_TASK_PRIORITY_BACKGROUND
360 15, // EFL_TASK_PRIORITY_LOW
361 5, // EFL_TASK_PRIORITY_HIGH
362 0 // EFL_TASK_PRIORITY_ULTRA
363};
364#endif
365
366EOLIAN static void
367_efl_app_efl_task_priority_set(Eo *obj, Efl_App_Data *pd EINA_UNUSED, Efl_Task_Priority priority)
368{
369 efl_task_priority_set(efl_super(obj, MY_CLASS), priority);
370#ifdef _WIN32
371#else
372 // -20 (high) -> 19 (low)
373 int p = 0;
374
375 if ((priority >= EFL_TASK_PRIORITY_NORMAL) &&
376 (priority <= EFL_TASK_PRIORITY_ULTRA))
377 p = primap[priority];
378 setpriority(PRIO_PROCESS, 0, p);
379#endif
380}
381
382EOLIAN static Efl_Task_Priority
383_efl_app_efl_task_priority_get(Eo *obj, Efl_App_Data *pd EINA_UNUSED)
384{
385 Efl_Task_Priority pri = EFL_TASK_PRIORITY_NORMAL;
386#ifdef _WIN32
387#else
388 int p, i, dist = 0x7fffffff, d;
389
390 errno = 0;
391 p = getpriority(PRIO_PROCESS, 0);
392 if (errno != 0)
393 return efl_task_priority_get(efl_super(obj, MY_CLASS));
394
395 // find the closest matching priority in primap
396 for (i = EFL_TASK_PRIORITY_NORMAL; i <= EFL_TASK_PRIORITY_ULTRA; i++)
397 {
398 d = primap[i] - p;
399 if (d < 0) d = -d;
400 if (d < dist)
401 {
402 pri = i;
403 dist = d;
404 }
405 }
406
407 Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS);
408 if (td) td->priority = pri;
409#endif
410 return pri;
411}
412
413//////////////////////////////////////////////////////////////////////////
414
415#include "efl_app.eo.c"
diff --git a/src/lib/ecore/efl_app.eo b/src/lib/ecore/efl_app.eo
new file mode 100644
index 0000000000..97e08957e2
--- /dev/null
+++ b/src/lib/ecore/efl_app.eo
@@ -0,0 +1,57 @@
1import efl_types;
2import eina_types;
3
4class Efl.App (Efl.Loop)
5{
6 [[ ]]
7 methods {
8 @property loop_main @class {
9 [[ Points to the main loop instance of the application. ]]
10 get {}
11 values {
12 main_loop: Efl.Loop; [[Application main loop]]
13 }
14 }
15 @property build_efl_version {
16 [[ Indicates the version of EFL with which this application was
17 compiled against/for.
18
19 This might differ from @.efl_version.
20 ]]
21 get {}
22 values {
23 @cref version: Efl.Version; [[Efl version]]
24 }
25 }
26 @property efl_version {
27 [[ Indicates the currently running version of EFL.
28
29 This might differ from @.build_efl_version.
30 ]]
31 get {}
32 values {
33 @cref version: Efl.Version; [[Efl version]]
34 }
35 }
36 }
37 events {
38 pause; [[Called when the application is not going be displayed or otherwise used by a user for some time]]
39 resume; [[Called before a window is rendered after a pause event]]
40 terminate; [[Called before starting the shutdown of the application]]
41 signal,usr1; [[System specific, but on unix maps to SIGUSR1 signal to the process - only called on main loop object]]
42 signal,usr2; [[System specific, but on unix maps to SIGUSR2 signal to the process - only called on main loop object]]
43 signal,hup; [[System specific, but on unix maps to SIGHUP signal to the process - only called on main loop object]]
44 }
45 implements {
46 Efl.Object.constructor;
47 Efl.Object.destructor;
48 Efl.Io.Closer.close;
49 Efl.Io.Closer.closed { get; }
50 Efl.Io.Reader.read;
51 Efl.Io.Reader.can_read { get; set; }
52 Efl.Io.Reader.eos { get; set; }
53 Efl.Io.Writer.write;
54 Efl.Io.Writer.can_write { get; set; }
55 Efl.Task.priority { get; set; }
56 }
57}
diff --git a/src/lib/ecore/efl_appthread.c b/src/lib/ecore/efl_appthread.c
new file mode 100644
index 0000000000..93de9c0917
--- /dev/null
+++ b/src/lib/ecore/efl_appthread.c
@@ -0,0 +1,245 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#define EFL_IO_READER_PROTECTED 1
6#define EFL_IO_WRITER_PROTECTED 1
7#define EFL_IO_CLOSER_PROTECTED 1
8
9#include <Ecore.h>
10
11#include "ecore_private.h"
12
13#include <unistd.h>
14#include <fcntl.h>
15#include <string.h>
16
17#define MY_CLASS EFL_APPTHREAD_CLASS
18
19//////////////////////////////////////////////////////////////////////////
20
21//////////////////////////////////////////////////////////////////////////
22
23EOLIAN static Efl_Object *
24_efl_appthread_efl_object_constructor(Eo *obj, Efl_Appthread_Data *pd)
25{
26 obj = efl_constructor(efl_super(obj, MY_CLASS));
27 pd->fd.in = -1;
28 pd->fd.out = -1;
29 pd->fd.can_write = EINA_TRUE;
30 pd->ctrl.in = -1;
31 pd->ctrl.out = -1;
32 return obj;
33}
34
35EOLIAN static void
36_efl_appthread_efl_object_destructor(Eo *obj, Efl_Appthread_Data *pd)
37{
38 if (pd->fd.in >= 0)
39 {
40 efl_del(pd->fd.in_handler);
41 efl_del(pd->fd.out_handler);
42 efl_del(pd->ctrl.in_handler);
43 efl_del(pd->ctrl.out_handler);
44 close(pd->fd.in);
45 close(pd->fd.out);
46 close(pd->ctrl.in);
47 close(pd->ctrl.out);
48 pd->fd.in_handler = NULL;
49 pd->fd.out_handler = NULL;
50 pd->ctrl.in_handler = NULL;
51 pd->ctrl.out_handler = NULL;
52 pd->fd.in = -1;
53 pd->fd.out = -1;
54 pd->ctrl.in = -1;
55 pd->ctrl.out = -1;
56 }
57 efl_destructor(efl_super(obj, MY_CLASS));
58}
59
60EOLIAN static Eina_Error
61_efl_appthread_efl_io_closer_close(Eo *obj, Efl_Appthread_Data *pd)
62{
63 EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(obj), EBADF);
64 efl_io_writer_can_write_set(obj, EINA_FALSE);
65 efl_io_reader_can_read_set(obj, EINA_FALSE);
66 efl_io_reader_eos_set(obj, EINA_TRUE);
67 if (pd->fd.in >= 0) close(pd->fd.in);
68 if (pd->fd.out >= 0) close(pd->fd.out);
69 if (pd->fd.in_handler) efl_del(pd->fd.in_handler);
70 if (pd->fd.out_handler) efl_del(pd->fd.out_handler);
71 pd->fd.in = -1;
72 pd->fd.out = -1;
73 pd->fd.in_handler = NULL;
74 pd->fd.out_handler = NULL;
75 return 0;
76}
77
78EOLIAN static Eina_Bool
79_efl_appthread_efl_io_closer_closed_get(Eo *obj EINA_UNUSED, Efl_Appthread_Data *pd)
80{
81 if ((pd->fd.in == -1) && (pd->fd.out == -1)) return EINA_TRUE;
82 return EINA_FALSE;
83}
84
85EOLIAN static Eina_Error
86_efl_appthread_efl_io_reader_read(Eo *obj, Efl_Appthread_Data *pd, Eina_Rw_Slice *rw_slice)
87{
88 ssize_t r;
89
90 errno = 0;
91 if (pd->fd.out == -1) goto err;
92
93 do
94 {
95 errno = 0;
96 r = read(pd->fd.out, rw_slice->mem, rw_slice->len);
97 if (r == -1)
98 {
99 if (errno == EINTR) continue;
100 goto err;
101 }
102 }
103 while (r == -1);
104
105 rw_slice->len = r;
106 if (r == 0)
107 {
108 efl_io_reader_can_read_set(obj, EINA_FALSE);
109 efl_io_reader_eos_set(obj, EINA_TRUE);
110 close(pd->fd.out);
111 pd->fd.out = -1;
112 efl_del(pd->fd.out_handler);
113 pd->fd.out_handler = NULL;
114 return EPIPE;
115 }
116 return 0;
117err:
118 if ((pd->fd.out != -1) && (errno != EAGAIN))
119 {
120 close(pd->fd.out);
121 pd->fd.out = -1;
122 efl_del(pd->fd.out_handler);
123 pd->fd.out_handler = NULL;
124 }
125 rw_slice->len = 0;
126 rw_slice->mem = NULL;
127 efl_io_reader_can_read_set(obj, EINA_FALSE);
128 return EINVAL;
129}
130
131EOLIAN static void
132_efl_appthread_efl_io_reader_can_read_set(Eo *obj, Efl_Appthread_Data *pd, Eina_Bool can_read)
133{
134 Eina_Bool old = efl_io_reader_can_read_get(obj);
135 if (old == can_read) return;
136 pd->fd.can_read = can_read;
137 if (can_read)
138 efl_loop_handler_active_set(pd->fd.in_handler, 0);
139 else
140 efl_loop_handler_active_set(pd->fd.in_handler,
141 EFL_LOOP_HANDLER_FLAGS_READ);
142 efl_event_callback_call(obj, EFL_IO_READER_EVENT_CAN_READ_CHANGED, NULL);
143}
144
145EOLIAN static Eina_Bool
146_efl_appthread_efl_io_reader_can_read_get(Eo *obj EINA_UNUSED, Efl_Appthread_Data *pd)
147{
148 return pd->fd.can_read;
149}
150
151EOLIAN static void
152_efl_appthread_efl_io_reader_eos_set(Eo *obj, Efl_Appthread_Data *pd, Eina_Bool is_eos)
153{
154 Eina_Bool old = efl_io_reader_eos_get(obj);
155 if (old == is_eos) return;
156
157 pd->fd.eos_read = is_eos;
158 if (!is_eos) return;
159 if (pd->fd.out_handler)
160 efl_loop_handler_active_set(pd->fd.out_handler, 0);
161 efl_event_callback_call(obj, EFL_IO_READER_EVENT_EOS, NULL);
162}
163
164EOLIAN static Eina_Bool
165_efl_appthread_efl_io_reader_eos_get(Eo *obj EINA_UNUSED, Efl_Appthread_Data *pd)
166{
167 return pd->fd.eos_read;
168}
169
170EOLIAN static Eina_Error
171_efl_appthread_efl_io_writer_write(Eo *obj, Efl_Appthread_Data *pd, Eina_Slice *slice, Eina_Slice *remaining)
172{
173 ssize_t r;
174
175 errno = 0;
176 if (pd->fd.in == -1) goto err;
177
178 do
179 {
180 errno = 0;
181 r = write(pd->fd.in, slice->mem, slice->len);
182 if (r == -1)
183 {
184 if (errno == EINTR) continue;
185 goto err;
186 }
187 }
188 while (r == -1);
189
190 if (remaining)
191 {
192 remaining->len = slice->len - r;
193 remaining->bytes = slice->bytes + r;
194 }
195 slice->len = r;
196
197 if ((slice) && (slice->len > 0))
198 efl_io_writer_can_write_set(obj, EINA_FALSE);
199 if (r == 0)
200 {
201 close(pd->fd.in);
202 pd->fd.in = -1;
203 efl_del(pd->fd.in_handler);
204 pd->fd.in_handler = NULL;
205 return EPIPE;
206 }
207 return 0;
208err:
209 if ((pd->fd.in != -1) && (errno != EAGAIN))
210 {
211 close(pd->fd.in);
212 pd->fd.in = -1;
213 efl_del(pd->fd.in_handler);
214 pd->fd.in_handler = NULL;
215 }
216 if (remaining) *remaining = *slice;
217 slice->len = 0;
218 slice->mem = NULL;
219 efl_io_writer_can_write_set(obj, EINA_FALSE);
220 return EINVAL;
221}
222
223EOLIAN static void
224_efl_appthread_efl_io_writer_can_write_set(Eo *obj, Efl_Appthread_Data *pd, Eina_Bool can_write)
225{
226 Eina_Bool old = efl_io_writer_can_write_get(obj);
227 if (old == can_write) return;
228 pd->fd.can_write = can_write;
229 if (can_write)
230 efl_loop_handler_active_set(pd->fd.in_handler, 0);
231 else
232 efl_loop_handler_active_set(pd->fd.in_handler,
233 EFL_LOOP_HANDLER_FLAGS_WRITE);
234 efl_event_callback_call(obj, EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED, NULL);
235}
236
237EOLIAN static Eina_Bool
238_efl_appthread_efl_io_writer_can_write_get(Eo *obj EINA_UNUSED, Efl_Appthread_Data *pd)
239{
240 return pd->fd.can_write;
241}
242
243//////////////////////////////////////////////////////////////////////////
244
245#include "efl_appthread.eo.c"
diff --git a/src/lib/ecore/efl_appthread.eo b/src/lib/ecore/efl_appthread.eo
new file mode 100644
index 0000000000..2f5021a720
--- /dev/null
+++ b/src/lib/ecore/efl_appthread.eo
@@ -0,0 +1,22 @@
1import efl_types;
2import eina_types;
3
4class Efl.Appthread (Efl.Loop)
5{
6 [[ ]]
7 methods {
8 }
9 events {
10 }
11 implements {
12 Efl.Object.constructor;
13 Efl.Object.destructor;
14 Efl.Io.Closer.close;
15 Efl.Io.Closer.closed { get; }
16 Efl.Io.Reader.read;
17 Efl.Io.Reader.can_read { get; set; }
18 Efl.Io.Reader.eos { get; set; }
19 Efl.Io.Writer.write;
20 Efl.Io.Writer.can_write { get; set; }
21 }
22}
diff --git a/src/lib/ecore/efl_exe.c b/src/lib/ecore/efl_exe.c
index ed9c53c583..1443bbf071 100644
--- a/src/lib/ecore/efl_exe.c
+++ b/src/lib/ecore/efl_exe.c
@@ -179,15 +179,30 @@ _foreach_env(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, voi
179 return EINA_TRUE; 179 return EINA_TRUE;
180} 180}
181 181
182static Eina_Value
183_efl_loop_task_exit(void *data, const Eina_Value v,
184 const Eina_Future *dead EINA_UNUSED)
185{
186 Eo *obj = data;
187
188 efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL);
189 efl_unref(obj);
190 return v;
191}
192
182static void 193static void
183_exe_exit_eval(Eo *obj, Efl_Exe_Data *pd) 194_exe_exit_eval(Eo *obj, Efl_Exe_Data *pd)
184{ 195{
185 // XXX: defer the below in a job 196 if ((pd->fd.out == -1) && /*(pd->fd.in == -1) &&*/
186 if ((pd->fd.out == -1) && (pd->fd.exited_read == -1) && 197 (pd->fd.exited_read == -1) && (!pd->exit_called))
187 (!pd->exit_called))
188 { 198 {
199 Eina_Future *job;
200 Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS);
201
189 pd->exit_called = EINA_TRUE; 202 pd->exit_called = EINA_TRUE;
190 efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL); 203 efl_ref(obj);
204 job = eina_future_then(efl_loop_job(loop), _efl_loop_task_exit, obj);
205 efl_future_Eina_FutureXXX_then(loop, job);
191 } 206 }
192} 207}
193 208
@@ -666,10 +681,11 @@ _efl_exe_efl_io_reader_can_read_set(Eo *obj, Efl_Exe_Data *pd, Eina_Bool can_rea
666 Eina_Bool old = efl_io_reader_can_read_get(obj); 681 Eina_Bool old = efl_io_reader_can_read_get(obj);
667 if (old == can_read) return; 682 if (old == can_read) return;
668 pd->fd.can_read = can_read; 683 pd->fd.can_read = can_read;
684 if (!pd->fd.out_handler) return;
669 if (can_read) 685 if (can_read)
670 efl_loop_handler_active_set(pd->fd.in_handler, 0); 686 efl_loop_handler_active_set(pd->fd.out_handler, 0);
671 else 687 else
672 efl_loop_handler_active_set(pd->fd.in_handler, 688 efl_loop_handler_active_set(pd->fd.out_handler,
673 EFL_LOOP_HANDLER_FLAGS_READ); 689 EFL_LOOP_HANDLER_FLAGS_READ);
674 efl_event_callback_call(obj, EFL_IO_READER_EVENT_CAN_READ_CHANGED, NULL); 690 efl_event_callback_call(obj, EFL_IO_READER_EVENT_CAN_READ_CHANGED, NULL);
675} 691}
diff --git a/src/lib/ecore/efl_general.h b/src/lib/ecore/efl_general.h
index 256f1065a4..222c799c2c 100644
--- a/src/lib/ecore/efl_general.h
+++ b/src/lib/ecore/efl_general.h
@@ -107,9 +107,9 @@
107#define EFL_MAIN_EX() \ 107#define EFL_MAIN_EX() \
108 EFL_CALLBACKS_ARRAY_DEFINE(_efl_main_ex, \ 108 EFL_CALLBACKS_ARRAY_DEFINE(_efl_main_ex, \
109 { EFL_LOOP_EVENT_ARGUMENTS, efl_main }, \ 109 { EFL_LOOP_EVENT_ARGUMENTS, efl_main }, \
110 { EFL_LOOP_EVENT_PAUSE, efl_pause }, \ 110 { EFL_APP_EVENT_PAUSE, efl_pause }, \
111 { EFL_LOOP_EVENT_RESUME, efl_resume }, \ 111 { EFL_APP_EVENT_RESUME, efl_resume }, \
112 { EFL_LOOP_EVENT_TERMINATE, efl_terminate }); \ 112 { EFL_APP_EVENT_TERMINATE, efl_terminate }); \
113 int main(int argc, char **argv) \ 113 int main(int argc, char **argv) \
114 { \ 114 { \
115 Eina_Value *ret__; \ 115 Eina_Value *ret__; \
diff --git a/src/lib/ecore/efl_loop.c b/src/lib/ecore/efl_loop.c
index 74a12deb50..0ccee1706f 100644
--- a/src/lib/ecore/efl_loop.c
+++ b/src/lib/ecore/efl_loop.c
@@ -8,9 +8,6 @@
8#include <unistd.h> 8#include <unistd.h>
9#include <math.h> 9#include <math.h>
10#include <sys/time.h> 10#include <sys/time.h>
11#ifndef _WIN32
12# include <sys/resource.h>
13#endif
14#include <errno.h> 11#include <errno.h>
15 12
16#include "Ecore.h" 13#include "Ecore.h"
@@ -53,8 +50,6 @@ _efl_loop_message_handler_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Loo
53 return mh.handler; 50 return mh.handler;
54} 51}
55 52
56Efl_Version _app_efl_version = { 0, 0, 0, 0, NULL, NULL };
57
58Eo *_mainloop_singleton = NULL; 53Eo *_mainloop_singleton = NULL;
59Efl_Loop_Data *_mainloop_singleton_data = NULL; 54Efl_Loop_Data *_mainloop_singleton_data = NULL;
60 55
@@ -63,19 +58,10 @@ static Eina_List *_environ_strings_set = NULL;
63 58
64static void _clean_old_environ(void); 59static void _clean_old_environ(void);
65 60
66EOLIAN static Efl_Loop *
67_efl_loop_main_get(Efl_Class *klass EINA_UNUSED, void *_pd EINA_UNUSED)
68{
69 if (_mainloop_singleton) return _mainloop_singleton;
70 _mainloop_singleton = efl_add(EFL_LOOP_CLASS, NULL);
71 _mainloop_singleton_data = efl_data_scope_get(_mainloop_singleton, EFL_LOOP_CLASS);
72 return _mainloop_singleton;
73}
74
75EAPI Eo * 61EAPI Eo *
76efl_main_loop_get(void) 62efl_main_loop_get(void)
77{ 63{
78 return efl_loop_main_get(EFL_LOOP_CLASS); 64 return efl_app_loop_main_get(EFL_APP_CLASS);
79} 65}
80 66
81EOLIAN static void 67EOLIAN static void
@@ -172,8 +158,8 @@ efl_loop_exit_code_process(Eina_Value *value)
172 Eina_Value v = EINA_VALUE_EMPTY; 158 Eina_Value v = EINA_VALUE_EMPTY;
173 159
174 eina_value_setup(&v, EINA_VALUE_TYPE_INT); 160 eina_value_setup(&v, EINA_VALUE_TYPE_INT);
175 if (!eina_value_convert(&v, value)) r = -1; 161 if (!eina_value_convert(value, &v)) r = -1;
176 else eina_value_get(&v, &v); 162 else eina_value_get(&v, &r);
177 } 163 }
178 else 164 else
179 { 165 {
@@ -203,7 +189,7 @@ _poll_trigger(void *data, const Efl_Event *event)
203static void 189static void
204_check_event_catcher_add(void *data, const Efl_Event *event) 190_check_event_catcher_add(void *data, const Efl_Event *event)
205{ 191{
206 const Efl_Callback_Array_Item *array = event->info; 192 const Efl_Callback_Array_Item_Full *array = event->info;
207 Efl_Loop_Data *pd = data; 193 Efl_Loop_Data *pd = data;
208 int i; 194 int i;
209 195
@@ -272,7 +258,7 @@ _check_event_catcher_add(void *data, const Efl_Event *event)
272static void 258static void
273_check_event_catcher_del(void *data, const Efl_Event *event) 259_check_event_catcher_del(void *data, const Efl_Event *event)
274{ 260{
275 const Efl_Callback_Array_Item *array = event->info; 261 const Efl_Callback_Array_Item_Full *array = event->info;
276 Efl_Loop_Data *pd = data; 262 Efl_Loop_Data *pd = data;
277 int i; 263 int i;
278 264
@@ -337,7 +323,7 @@ _efl_loop_efl_object_constructor(Eo *obj, Efl_Loop_Data *pd)
337EOLIAN static void 323EOLIAN static void
338_efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd) 324_efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd)
339{ 325{
340 _ecore_main_content_clear(pd); 326 _ecore_main_content_clear(obj, pd);
341 327
342 pd->future_message_handler = NULL; 328 pd->future_message_handler = NULL;
343 329
@@ -725,6 +711,7 @@ efl_build_version_set(int vmaj, int vmin, int vmic, int revision,
725 _app_efl_version.build_id = build_id ? strdup(build_id) : NULL; 711 _app_efl_version.build_id = build_id ? strdup(build_id) : NULL;
726} 712}
727 713
714/* HHH:
728EOLIAN static const Efl_Version * 715EOLIAN static const Efl_Version *
729_efl_loop_app_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) 716_efl_loop_app_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
730{ 717{
@@ -734,7 +721,7 @@ _efl_loop_app_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED
734EOLIAN static const Efl_Version * 721EOLIAN static const Efl_Version *
735_efl_loop_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) 722_efl_loop_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
736{ 723{
737 /* vanilla EFL: flavor = NULL */ 724 // vanilla EFL: flavor = NULL
738 static const Efl_Version version = { 725 static const Efl_Version version = {
739 .major = VMAJ, 726 .major = VMAJ,
740 .minor = VMIN, 727 .minor = VMIN,
@@ -745,6 +732,7 @@ _efl_loop_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
745 }; 732 };
746 return &version; 733 return &version;
747} 734}
735*/
748 736
749static void 737static void
750_env_sync(Efl_Loop_Data *pd, Efl_Task_Data *td) 738_env_sync(Efl_Loop_Data *pd, Efl_Task_Data *td)
@@ -903,63 +891,23 @@ _efl_loop_efl_task_env_get(Eo *obj, Efl_Loop_Data *pd, const char *var)
903 eina_lock_release(&_environ_lock); 891 eina_lock_release(&_environ_lock);
904 return efl_task_env_get(efl_super(obj, EFL_LOOP_CLASS), var); 892 return efl_task_env_get(efl_super(obj, EFL_LOOP_CLASS), var);
905} 893}
906#ifdef _WIN32 894
907#else 895EOLIAN static Eina_Bool
908static const signed char primap[EFL_TASK_PRIORITY_ULTRA + 1] = 896_efl_loop_efl_task_run(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
909{ 897{
910 10, // EFL_TASK_PRIORITY_NORMAL 898 Eina_Value *ret;
911 19, // EFL_TASK_PRIORITY_BACKGROUND 899 int real;
912 15, // EFL_TASK_PRIORITY_LOW
913 5, // EFL_TASK_PRIORITY_HIGH
914 0 // EFL_TASK_PRIORITY_ULTRA
915};
916#endif
917 900
918EOLIAN static void 901 ret = efl_loop_begin(obj);
919_efl_loop_efl_task_priority_set(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, Efl_Task_Priority priority) 902 real = efl_loop_exit_code_process(ret);
920{ 903 if (real == 0) return EINA_TRUE;
921 efl_task_priority_set(efl_super(obj, EFL_LOOP_CLASS), priority); 904 return EINA_FALSE;
922#ifdef _WIN32
923#else
924 // -20 (high) -> 19 (low)
925 int p = 0;
926
927 if ((priority >= EFL_TASK_PRIORITY_NORMAL) &&
928 (priority <= EFL_TASK_PRIORITY_ULTRA))
929 p = primap[priority];
930 setpriority(PRIO_PROCESS, 0, p);
931#endif
932} 905}
933 906
934EOLIAN static Efl_Task_Priority 907EOLIAN static void
935_efl_loop_efl_task_priority_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) 908_efl_loop_efl_task_end(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
936{ 909{
937 Efl_Task_Priority pri = EFL_TASK_PRIORITY_NORMAL; 910 efl_loop_quit(obj, eina_value_int_init(0));
938#ifdef _WIN32
939#else
940 int p, i, dist = 0x7fffffff, d;
941
942 errno = 0;
943 p = getpriority(PRIO_PROCESS, 0);
944 if (errno != 0)
945 return efl_task_priority_get(efl_super(obj, EFL_LOOP_CLASS));
946
947 // find the closest matching priority in primap
948 for (i = EFL_TASK_PRIORITY_NORMAL; i <= EFL_TASK_PRIORITY_ULTRA; i++)
949 {
950 d = primap[i] - p;
951 if (d < 0) d = -d;
952 if (d < dist)
953 {
954 pri = i;
955 dist = d;
956 }
957 }
958
959 Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS);
960 if (td) td->priority = pri;
961#endif
962 return pri;
963} 911}
964 912
965EAPI Eina_Future_Scheduler * 913EAPI Eina_Future_Scheduler *
diff --git a/src/lib/ecore/efl_loop.eo b/src/lib/ecore/efl_loop.eo
index e6c1229772..1ecdd68538 100644
--- a/src/lib/ecore/efl_loop.eo
+++ b/src/lib/ecore/efl_loop.eo
@@ -20,33 +20,6 @@ class Efl.Loop (Efl.Task)
20 you can provide these if you need to. 20 you can provide these if you need to.
21 ]] 21 ]]
22 methods { 22 methods {
23 @property main @class {
24 [[Points to the main loop instance of the application.]]
25 get {}
26 values {
27 main_loop: Efl.Loop; [[Application main loop]]
28 }
29 }
30 @property app_efl_version {
31 [[Indicates the version of EFL with which this application was compiled.
32
33 This might differ from @.efl_version.
34 ]]
35 get {}
36 values {
37 @cref version: Efl.Version; [[Efl version]]
38 }
39 }
40 @property efl_version {
41 [[Indicates the currently running version of EFL.
42
43 This might differ from @.app_efl_version.
44 ]]
45 get {}
46 values {
47 @cref version: Efl.Version; [[Efl version]]
48 }
49 }
50 iterate { 23 iterate {
51 [[Runs a single iteration of the main loop to process everything on the 24 [[Runs a single iteration of the main loop to process everything on the
52 queue.]] 25 queue.]]
@@ -148,18 +121,13 @@ class Efl.Loop (Efl.Task)
148 poll,high; [[Event occurs multiple times per second. The exact tick is undefined and can be adjusted system wide.]] 121 poll,high; [[Event occurs multiple times per second. The exact tick is undefined and can be adjusted system wide.]]
149 poll,medium; [[Event occurs multiple times per minute. The exact tick is undefined and can be adjusted system wide.]] 122 poll,medium; [[Event occurs multiple times per minute. The exact tick is undefined and can be adjusted system wide.]]
150 poll,low; [[Event occurs multiple times every 15 minutes. The exact tick is undefined and can be adjusted system wide.]] 123 poll,low; [[Event occurs multiple times every 15 minutes. The exact tick is undefined and can be adjusted system wide.]]
151 pause; [[Called when the window is not going be displayed for some time]]
152 resume; [[Called before a window is rendered after a pause event]]
153 terminate; [[Called before starting the shutdown of Elementary]]
154 signal,usr1; [[System specific, but on unix maps to SIGUSR1 signal to the process - only called on main loop object]]
155 signal,usr2; [[System specific, but on unix maps to SIGUSR2 signal to the process - only called on main loop object]]
156 signal,hup; [[System specific, but on unix maps to SIGHUP signal to the process - only called on main loop object]]
157 } 124 }
158 implements { 125 implements {
159 Efl.Object.constructor; 126 Efl.Object.constructor;
160 Efl.Object.destructor; 127 Efl.Object.destructor;
161 Efl.Object.provider_find; 128 Efl.Object.provider_find;
162 Efl.Task.env { set; get; } 129 Efl.Task.env { set; get; }
163 Efl.Task.priority { get; set; } 130 Efl.Task.run;
131 Efl.Task.end;
164 } 132 }
165} 133}
diff --git a/src/lib/ecore/efl_loop_fd.c b/src/lib/ecore/efl_loop_fd.c
index 87cb58c41a..e6ec21d7b9 100644
--- a/src/lib/ecore/efl_loop_fd.c
+++ b/src/lib/ecore/efl_loop_fd.c
@@ -111,7 +111,7 @@ _efl_loop_fd_fd_file_get(Eo *obj EINA_UNUSED, Efl_Loop_Fd_Data *pd)
111static void 111static void
112_check_fd_event_catcher_add(void *data, const Efl_Event *event) 112_check_fd_event_catcher_add(void *data, const Efl_Event *event)
113{ 113{
114 const Efl_Callback_Array_Item *array = event->info; 114 const Efl_Callback_Array_Item_Full *array = event->info;
115 Efl_Loop_Fd_Data *fd = data; 115 Efl_Loop_Fd_Data *fd = data;
116 Eina_Bool need_reset = EINA_FALSE; 116 Eina_Bool need_reset = EINA_FALSE;
117 int i; 117 int i;
@@ -142,7 +142,7 @@ _check_fd_event_catcher_add(void *data, const Efl_Event *event)
142static void 142static void
143_check_fd_event_catcher_del(void *data, const Efl_Event *event) 143_check_fd_event_catcher_del(void *data, const Efl_Event *event)
144{ 144{
145 const Efl_Callback_Array_Item *array = event->info; 145 const Efl_Callback_Array_Item_Full *array = event->info;
146 Efl_Loop_Fd_Data *fd = data; 146 Efl_Loop_Fd_Data *fd = data;
147 Eina_Bool need_reset = EINA_FALSE; 147 Eina_Bool need_reset = EINA_FALSE;
148 int i; 148 int i;
diff --git a/src/lib/ecore/efl_loop_handler.c b/src/lib/ecore/efl_loop_handler.c
index 39d05359dd..34e03a9cc4 100644
--- a/src/lib/ecore/efl_loop_handler.c
+++ b/src/lib/ecore/efl_loop_handler.c
@@ -132,7 +132,7 @@ _handler_reset(Eo *obj, Efl_Loop_Handler_Data *pd)
132static Eina_Bool 132static Eina_Bool
133_event_references_update(Efl_Loop_Handler_Data *pd, const Efl_Event *event, int increment) 133_event_references_update(Efl_Loop_Handler_Data *pd, const Efl_Event *event, int increment)
134{ 134{
135 const Efl_Callback_Array_Item *array = event->info; 135 const Efl_Callback_Array_Item_Full *array = event->info;
136 int i; 136 int i;
137 Eina_Bool need_reset = EINA_FALSE; 137 Eina_Bool need_reset = EINA_FALSE;
138 138
diff --git a/src/lib/ecore/efl_task.c b/src/lib/ecore/efl_task.c
index 18927e843e..9a727743ed 100644
--- a/src/lib/ecore/efl_task.c
+++ b/src/lib/ecore/efl_task.c
@@ -186,8 +186,8 @@ _escape(const char *s)
186 { 186 {
187 *d = '\"'; 187 *d = '\"';
188 d++; 188 d++;
189 *d = 0;
190 } 189 }
190 *d = 0;
191 return s2; 191 return s2;
192} 192}
193 193
@@ -215,7 +215,7 @@ _rebuild_command(Efl_Task_Data *pd)
215 char *str = _escape(arg); 215 char *str = _escape(arg);
216 if (str) 216 if (str)
217 { 217 {
218 if (!have_args) eina_strbuf_append(sb, " "); 218 if (have_args) eina_strbuf_append(sb, " ");
219 eina_strbuf_append(sb, str); 219 eina_strbuf_append(sb, str);
220 free(str); 220 free(str);
221 have_args = EINA_TRUE; 221 have_args = EINA_TRUE;
@@ -272,14 +272,17 @@ _efl_task_arg_value_set(Eo *obj EINA_UNUSED, Efl_Task_Data *pd, unsigned int num
272 272
273 if (!pd->args) pd->args = eina_array_new(16); 273 if (!pd->args) pd->args = eina_array_new(16);
274 count = eina_array_count(pd->args); 274 count = eina_array_count(pd->args);
275 if (count > num) 275 if ((count > 0) && (count > num))
276 parg = eina_array_data_get(pd->args, num); 276 parg = eina_array_data_get(pd->args, num);
277 else 277 else
278 { 278 {
279 unsigned int i; 279 unsigned int i;
280 280
281 for (i = count; i <= num; i++) 281 for (i = count; i <= num; i++)
282 eina_array_push(pd->args, NULL); 282 {
283 eina_array_push(pd->args, "");
284 eina_array_data_set(pd->args, i, NULL);
285 }
283 } 286 }
284 287
285 if (arg) 288 if (arg)
diff --git a/src/lib/ecore/efl_thread.c b/src/lib/ecore/efl_thread.c
new file mode 100644
index 0000000000..ffd4f4756f
--- /dev/null
+++ b/src/lib/ecore/efl_thread.c
@@ -0,0 +1,917 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#define EFL_IO_READER_PROTECTED 1
6#define EFL_IO_WRITER_PROTECTED 1
7#define EFL_IO_CLOSER_PROTECTED 1
8
9#include <Ecore.h>
10
11#include "ecore_private.h"
12
13#include <unistd.h>
14#include <fcntl.h>
15#include <string.h>
16
17#define MY_CLASS EFL_THREAD_CLASS
18
19typedef struct
20{
21 const char *name;
22 struct {
23 int in, out;
24 Eo *in_handler, *out_handler;
25 } fd, ctrl;
26 struct {
27 unsigned int argc;
28 const char **argv;
29 } args;
30 Efl_Callback_Array_Item_Full *event_cb;
31} Thread_Data;
32
33#define CMD_EXIT 1
34#define CMD_EXITED 2
35
36typedef struct
37{
38 int command;
39 int data;
40} Control_Data;
41
42typedef struct _Efl_Thread_Data Efl_Thread_Data;
43
44struct _Efl_Thread_Data
45{
46 struct {
47 int in, out;
48 Eo *in_handler, *out_handler;
49 Eina_Bool can_read : 1;
50 Eina_Bool eos_read : 1;
51 Eina_Bool can_write : 1;
52 } fd, ctrl;
53 int read_listeners;
54 Eo *loop;
55 Thread_Data *thdat;
56 Efl_Callback_Array_Item_Full *event_cb;
57 Eina_Thread thread;
58 Eina_Bool end_sent : 1;
59 Eina_Bool exit_read : 1;
60 Eina_Bool exit_called : 1;
61};
62
63//////////////////////////////////////////////////////////////////////////
64
65static void
66_cb_thread_out(void *data, const Efl_Event *event EINA_UNUSED)
67{
68 Eo *obj = data;
69 efl_io_reader_can_read_set(obj, EINA_TRUE);
70}
71
72static void
73_cb_thread_in(void *data, const Efl_Event *event EINA_UNUSED)
74{
75 Eo *obj = data;
76 efl_io_writer_can_write_set(obj, EINA_TRUE);
77}
78
79static void
80_cb_thread_ctrl_out(void *data, const Efl_Event *event EINA_UNUSED)
81{
82 Eo *obj = data;
83 Control_Data cmd;
84 ssize_t ret;
85 Efl_Appthread_Data *ad;
86
87 ad = efl_data_scope_get(obj, EFL_APPTHREAD_CLASS);
88 cmd.command = 0;
89 cmd.data = 0;
90 ret = read(ad->ctrl.out, &cmd, sizeof(Control_Data));
91 if (ret == sizeof(Control_Data))
92 {
93 if (cmd.command == CMD_EXIT)
94 {
95 efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL);
96 efl_loop_quit(obj, eina_value_int_init(0));
97 }
98 }
99}
100
101static Eina_Value
102_efl_loop_arguments_send(void *data, const Eina_Value v,
103 const Eina_Future *dead EINA_UNUSED)
104
105{
106 Efl_Loop_Arguments arge;
107 Eo *obj = data;
108 Eina_Array *arga;
109 Eina_Stringshare *s;
110 unsigned int argc = efl_task_arg_count_get(obj);
111 unsigned int i;
112
113 arga = eina_array_new(argc);
114 if (v.type == EINA_VALUE_TYPE_ERROR) goto on_error;
115
116 for (i = 0; i < argc; i++)
117 {
118 const char *argv = efl_task_arg_value_get(obj, i);
119 if (argv)
120 eina_array_push(arga, eina_stringshare_add(argv));
121 }
122 arge.argv = arga;
123 arge.initialization = EINA_TRUE;
124 efl_event_callback_call(obj,
125 EFL_LOOP_EVENT_ARGUMENTS, &arge);
126on_error:
127 while ((s = eina_array_pop(arga))) eina_stringshare_del(s);
128 eina_array_free(arga);
129 return v;
130}
131
132static void
133_appthread_parent_read_listeners_modify(Efl_Appthread_Data *ad, int mod)
134{
135 ad->read_listeners += mod;
136
137 if (ad->fd.out_handler)
138 {
139 if ((ad->read_listeners == 0) && (mod < 0))
140 efl_loop_handler_active_set
141 (ad->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_NONE);
142 else if ((ad->read_listeners == 1) && (mod > 0))
143 efl_loop_handler_active_set
144 (ad->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_READ);
145 }
146}
147
148static void
149_cb_appthread_event_callback_add(void *data, const Efl_Event *event)
150{
151 Efl_Appthread_Data *ad = data;
152 const Efl_Callback_Array_Item_Full *array = event->info;
153 int i;
154
155 for (i = 0; array[i].desc != NULL; i++)
156 {
157 if (array[i].desc == EFL_IO_READER_EVENT_CAN_READ_CHANGED)
158 _appthread_parent_read_listeners_modify(ad, 1);
159 }
160}
161
162static void
163_cb_appthread_event_callback_del(void *data, const Efl_Event *event)
164{
165 Efl_Appthread_Data *ad = data;
166 const Efl_Callback_Array_Item_Full *array = event->info;
167 int i;
168
169 for (i = 0; array[i].desc != NULL; i++)
170 {
171 if (array[i].desc == EFL_IO_READER_EVENT_CAN_READ_CHANGED)
172 _appthread_parent_read_listeners_modify(ad, -1);
173 }
174}
175
176EFL_CALLBACKS_ARRAY_DEFINE(_appthread_event_callback_watch,
177 { EFL_EVENT_CALLBACK_ADD, _cb_appthread_event_callback_add },
178 { EFL_EVENT_CALLBACK_DEL, _cb_appthread_event_callback_del });
179
180static void *
181_efl_thread_main(void *data, Eina_Thread t)
182{
183 Efl_Appthread_Data *ad;
184 Thread_Data *thdat = data;
185 Eo *obj;
186 Eina_Value *ret;
187 Control_Data cmd;
188 unsigned int i;
189 int real;
190 Efl_Callback_Array_Item_Full *it;
191 Eina_Future *job;
192
193 if (thdat->name) eina_thread_name_set(t, thdat->name);
194 else eina_thread_name_set(t, "Eflthread");
195
196 obj = efl_add(EFL_APPTHREAD_CLASS, NULL);
197 ad = efl_data_scope_get(obj, EFL_APPTHREAD_CLASS);
198 efl_event_callback_array_add(obj, _appthread_event_callback_watch(), ad);
199
200 // add handlers for "stdio"
201 thdat->fd.in_handler =
202 efl_add(EFL_LOOP_HANDLER_CLASS, obj,
203 efl_loop_handler_fd_set(efl_added, thdat->fd.in),
204 efl_event_callback_add
205 (efl_added, EFL_LOOP_HANDLER_EVENT_WRITE, _cb_thread_in, obj));
206 thdat->fd.out_handler =
207 efl_add(EFL_LOOP_HANDLER_CLASS, obj,
208 efl_loop_handler_fd_set(efl_added, thdat->fd.out),
209 efl_event_callback_add
210 (efl_added, EFL_LOOP_HANDLER_EVENT_READ, _cb_thread_out, obj));
211 // add handlers for control pipes
212 thdat->ctrl.in_handler =
213 efl_add(EFL_LOOP_HANDLER_CLASS, obj,
214 efl_loop_handler_fd_set(efl_added, thdat->ctrl.in));
215 thdat->ctrl.out_handler =
216 efl_add(EFL_LOOP_HANDLER_CLASS, obj,
217 efl_loop_handler_fd_set(efl_added, thdat->ctrl.out),
218 efl_event_callback_add
219 (efl_added, EFL_LOOP_HANDLER_EVENT_READ, _cb_thread_ctrl_out, obj),
220 efl_loop_handler_active_set
221 (efl_added, EFL_LOOP_HANDLER_FLAGS_READ));
222 ad->fd.in = thdat->fd.in;
223 ad->fd.out = thdat->fd.out;
224 ad->ctrl.in = thdat->ctrl.in;
225 ad->ctrl.out = thdat->ctrl.out;
226 ad->fd.in_handler = thdat->fd.in_handler;
227 ad->fd.out_handler = thdat->fd.out_handler;
228 ad->ctrl.in_handler = thdat->ctrl.in_handler;
229 ad->ctrl.out_handler = thdat->ctrl.out_handler;
230
231 if (thdat->event_cb)
232 {
233 for (it = thdat->event_cb; it->func; it++)
234 efl_event_callback_priority_add(obj, it->desc, it->priority,
235 it->func, it->user_data);
236 }
237 for (i = 0; i < thdat->args.argc; i++)
238 efl_task_arg_append(obj, thdat->args.argv[i]);
239 job = eina_future_then(efl_loop_job(obj), _efl_loop_arguments_send, obj);
240 efl_future_Eina_FutureXXX_then(obj, job);
241
242 for (i = 0; i < thdat->args.argc; i++)
243 eina_stringshare_del(thdat->args.argv[i]);
244 free(thdat->args.argv);
245 free(thdat->event_cb);
246 thdat->args.argv = NULL;
247 thdat->event_cb = NULL;
248
249 ret = efl_loop_begin(obj);
250 real = efl_loop_exit_code_process(ret);
251
252 cmd.command = CMD_EXITED;
253 cmd.data = real;
254 write(thdat->ctrl.in, &cmd, sizeof(Control_Data));
255
256 efl_del(obj);
257
258 thdat->fd.in_handler = NULL;
259 thdat->fd.out_handler = NULL;
260 thdat->ctrl.in_handler = NULL;
261 thdat->ctrl.out_handler = NULL;
262 thdat->fd.in = -1;
263 thdat->fd.out = -1;
264 thdat->ctrl.in = -1;
265 thdat->ctrl.out = -1;
266
267 return NULL;
268}
269
270//////////////////////////////////////////////////////////////////////////
271
272static Eina_Value
273_efl_loop_task_exit(void *data, const Eina_Value v,
274 const Eina_Future *dead EINA_UNUSED)
275
276{
277 Eo *obj = data;
278
279 efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL);
280 efl_unref(obj);
281 return v;
282}
283
284static void
285_thread_exit_eval(Eo *obj, Efl_Thread_Data *pd)
286{
287 if ((pd->fd.out == -1) && /*(pd->fd.in == -1) &&*/
288 (pd->exit_read) && (!pd->exit_called))
289 {
290 Eina_Future *job;
291 Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS);
292
293 pd->exit_called = EINA_TRUE;
294 efl_ref(obj);
295 job = eina_future_then(efl_loop_job(loop), _efl_loop_task_exit, obj);
296 efl_future_Eina_FutureXXX_then(loop, job);
297 }
298}
299
300static void
301_cb_thread_parent_out(void *data, const Efl_Event *event EINA_UNUSED)
302{
303 Eo *obj = data;
304 efl_io_reader_can_read_set(obj, EINA_TRUE);
305}
306
307static void
308_cb_thread_parent_in(void *data, const Efl_Event *event EINA_UNUSED)
309{
310 Eo *obj = data;
311 efl_io_writer_can_write_set(obj, EINA_TRUE);
312}
313
314static void
315_cb_thread_parent_ctrl_out(void *data, const Efl_Event *event EINA_UNUSED)
316{
317 Eo *obj = data;
318 Control_Data cmd;
319 ssize_t ret;
320 Efl_Thread_Data *pd = efl_data_scope_get(obj, MY_CLASS);
321
322 if (!pd) return;
323
324 cmd.command = 0;
325 cmd.data = 0;
326 ret = read(pd->ctrl.out, &cmd, sizeof(Control_Data));
327 if (ret == sizeof(Control_Data))
328 {
329 if (cmd.command == CMD_EXITED)
330 {
331 if (!pd->exit_read)
332 {
333 Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS);
334
335 if (td) td->exit_code = cmd.data;
336 pd->exit_read = EINA_TRUE;
337 _thread_exit_eval(obj, pd);
338 }
339 }
340 }
341}
342
343//////////////////////////////////////////////////////////////////////////
344
345static void
346_thread_parent_read_listeners_modify(Efl_Thread_Data *pd, int mod)
347{
348 pd->read_listeners += mod;
349
350 if (pd->fd.out_handler)
351 {
352 if ((pd->read_listeners == 0) && (mod < 0))
353 efl_loop_handler_active_set
354 (pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_NONE);
355 else if ((pd->read_listeners == 1) && (mod > 0))
356 efl_loop_handler_active_set
357 (pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_READ);
358 }
359}
360
361static void
362_cb_event_callback_add(void *data, const Efl_Event *event)
363{
364 Efl_Thread_Data *pd = data;
365 const Efl_Callback_Array_Item_Full *array = event->info;
366 int i;
367
368 for (i = 0; array[i].desc != NULL; i++)
369 {
370 if (array[i].desc == EFL_LOOP_EVENT_ARGUMENTS)
371 {
372 Efl_Callback_Array_Item_Full *event_cb, *it;
373 int num;
374
375 num = 0;
376 if (pd->event_cb)
377 {
378 for (it = pd->event_cb; it->func; it++) num++;
379 }
380 num++;
381 event_cb = realloc(pd->event_cb, (num + 1) * sizeof(Efl_Callback_Array_Item_Full));
382 if (event_cb)
383 {
384 pd->event_cb = event_cb;
385 event_cb[num - 1] = array[i];
386 event_cb[num].desc = NULL;
387 event_cb[num].priority = 0;
388 event_cb[num].func = NULL;
389 event_cb[num].user_data = NULL;
390 }
391 }
392 else if (array[i].desc == EFL_IO_READER_EVENT_CAN_READ_CHANGED)
393 _thread_parent_read_listeners_modify(pd, 1);
394 }
395}
396
397static void
398_cb_event_callback_del(void *data, const Efl_Event *event)
399{
400 Efl_Thread_Data *pd = data;
401 const Efl_Callback_Array_Item_Full *array = event->info;
402 int i;
403
404 for (i = 0; array[i].desc != NULL; i++)
405 {
406 if (array[i].desc == EFL_LOOP_EVENT_ARGUMENTS)
407 {
408 Efl_Callback_Array_Item_Full *it;
409
410 if (pd->event_cb)
411 {
412 Eina_Bool shuffle_down = EINA_FALSE;
413
414 for (it = pd->event_cb; it->func; it++)
415 {
416 if ((it->desc == array[i].desc) &&
417 (it->priority == array[i].priority) &&
418 (it->func == array[i].func) &&
419 (it->user_data == array[i].user_data))
420 shuffle_down = EINA_TRUE;
421 if (shuffle_down) it[0] = it[1];
422 }
423 }
424 }
425 else if (array[i].desc == EFL_IO_READER_EVENT_CAN_READ_CHANGED)
426 _thread_parent_read_listeners_modify(pd, -1);
427 }
428}
429
430EFL_CALLBACKS_ARRAY_DEFINE(_event_callback_watch,
431 { EFL_EVENT_CALLBACK_ADD, _cb_event_callback_add },
432 { EFL_EVENT_CALLBACK_DEL, _cb_event_callback_del });
433
434//////////////////////////////////////////////////////////////////////////
435
436EOLIAN static Efl_Object *
437_efl_thread_efl_object_constructor(Eo *obj, Efl_Thread_Data *pd)
438{
439 obj = efl_constructor(efl_super(obj, MY_CLASS));
440 efl_event_callback_array_add(obj, _event_callback_watch(), pd);
441 pd->fd.in = -1;
442 pd->fd.out = -1;
443 pd->fd.can_write = EINA_TRUE;
444 pd->ctrl.in = -1;
445 pd->ctrl.out = -1;
446 return obj;
447}
448
449EOLIAN static void
450_efl_thread_efl_object_destructor(Eo *obj, Efl_Thread_Data *pd)
451{
452 if (pd->thdat)
453 {
454/* we probably shouldn't do this... this simply has to orphan threads if they
455 * lose their parent. this stops shutdown from blocking.
456 // if exit response not read yet, read until fetched
457 if (!pd->exit_read)
458 {
459 Control_Data cmd;
460 ssize_t ret;
461
462 // if it hasn't been asked to exit... ask it
463 if (!pd->end_sent) efl_task_end(obj);
464 cmd.command = 0;
465 cmd.data = 0;
466 ret = read(pd->ctrl.out, &cmd, sizeof(Control_Data));
467 while (ret == sizeof(Control_Data))
468 {
469 if (cmd.command == CMD_EXITED)
470 {
471 if (!pd->exit_read)
472 {
473 Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS);
474
475 if (td) td->exit_code = cmd.data;
476 pd->exit_read = EINA_TRUE;
477 efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL);
478 break;
479 }
480 }
481 ret = read(pd->ctrl.out, &cmd, sizeof(Control_Data));
482 }
483 }
484 */
485 // stop and wait for thread to exit/join here
486 eina_thread_join(pd->thread);
487 efl_del(pd->fd.in_handler);
488 efl_del(pd->fd.out_handler);
489 efl_del(pd->ctrl.in_handler);
490 efl_del(pd->ctrl.out_handler);
491 close(pd->fd.in);
492 close(pd->fd.out);
493 close(pd->ctrl.in);
494 close(pd->ctrl.out);
495 pd->fd.in_handler = NULL;
496 pd->fd.out_handler = NULL;
497 pd->ctrl.in_handler = NULL;
498 pd->ctrl.out_handler = NULL;
499 pd->fd.in = -1;
500 pd->fd.out = -1;
501 pd->ctrl.in = -1;
502 pd->ctrl.out = -1;
503 free(pd->thdat);
504 }
505 free(pd->event_cb);
506 pd->event_cb = NULL;
507 efl_destructor(efl_super(obj, MY_CLASS));
508}
509
510EOLIAN static void
511_efl_thread_efl_object_parent_set(Eo *obj, Efl_Thread_Data *pd, Efl_Object *parent)
512{
513 efl_parent_set(efl_super(obj, MY_CLASS), parent);
514 pd->loop = efl_provider_find(parent, EFL_LOOP_CLASS);
515}
516
517EOLIAN static Eina_Bool
518_efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd)
519{
520 Eina_Thread_Priority pri;
521 Thread_Data *thdat;
522 const char *name;
523 int pipe_to_thread[2];
524 int pipe_from_thread[2];
525 unsigned int argc, i, num;
526 Efl_Callback_Array_Item_Full *it;
527
528 thdat = calloc(1, sizeof(Thread_Data));
529 if (!thdat) return EINA_FALSE;
530 thdat->fd.in = -1;
531 thdat->fd.out = -1;
532 thdat->ctrl.in = -1;
533 thdat->ctrl.out = -1;
534
535 if (pipe(pipe_to_thread) != 0)
536 {
537 ERR("Can't create to_thread pipe");
538 free(thdat);
539 return EINA_FALSE;
540 }
541 if (pipe(pipe_from_thread) != 0)
542 {
543 ERR("Can't create from_thread pipe");
544 close(pipe_to_thread[0]);
545 close(pipe_to_thread[1]);
546 free(thdat);
547 return EINA_FALSE;
548 }
549 thdat->fd.in = pipe_from_thread[1]; // write - input to parent
550 thdat->fd.out = pipe_to_thread [0]; // read - output from parent
551 pd->fd.in = pipe_to_thread [1]; // write - input to child
552 pd->fd.out = pipe_from_thread[0]; // read - output from child
553 eina_file_close_on_exec(pd->fd.in, EINA_TRUE);
554 eina_file_close_on_exec(pd->fd.out, EINA_TRUE);
555 eina_file_close_on_exec(thdat->fd.in, EINA_TRUE);
556 eina_file_close_on_exec(thdat->fd.out, EINA_TRUE);
557 fcntl(pd->fd.in, F_SETFL, O_NONBLOCK);
558 fcntl(pd->fd.out, F_SETFL, O_NONBLOCK);
559 fcntl(thdat->fd.in, F_SETFL, O_NONBLOCK);
560 fcntl(thdat->fd.out, F_SETFL, O_NONBLOCK);
561 pd->fd.in_handler =
562 efl_add(EFL_LOOP_HANDLER_CLASS, obj,
563 efl_loop_handler_fd_set(efl_added, pd->fd.in),
564 efl_event_callback_add
565 (efl_added, EFL_LOOP_HANDLER_EVENT_WRITE, _cb_thread_parent_in, obj));
566 pd->fd.out_handler =
567 efl_add(EFL_LOOP_HANDLER_CLASS, obj,
568 efl_loop_handler_fd_set(efl_added, pd->fd.out),
569 efl_event_callback_add
570 (efl_added, EFL_LOOP_HANDLER_EVENT_READ, _cb_thread_parent_out, obj));
571 if (pd->read_listeners > 0)
572 efl_loop_handler_active_set(pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_READ);
573
574 if (pipe(pipe_to_thread) != 0)
575 {
576 ERR("Can't create to_thread control pipe");
577 efl_del(pd->fd.in_handler);
578 efl_del(pd->fd.out_handler);
579 close(thdat->fd.in);
580 close(thdat->fd.out);
581 close(pd->fd.in);
582 close(pd->fd.out);
583 pd->fd.in_handler = NULL;
584 pd->fd.out_handler = NULL;
585 pd->fd.in = -1;
586 pd->fd.out = -1;
587 free(thdat);
588 return EINA_FALSE;
589 }
590 if (pipe(pipe_from_thread) != 0)
591 {
592 ERR("Can't create from_thread control pipe");
593 efl_del(pd->fd.in_handler);
594 efl_del(pd->fd.out_handler);
595 close(pipe_to_thread[0]);
596 close(pipe_to_thread[1]);
597 close(thdat->fd.in);
598 close(thdat->fd.out);
599 close(pd->fd.in);
600 close(pd->fd.out);
601 pd->fd.in_handler = NULL;
602 pd->fd.out_handler = NULL;
603 pd->fd.in = -1;
604 pd->fd.out = -1;
605 free(thdat);
606 return EINA_FALSE;
607 }
608 thdat->ctrl.in = pipe_from_thread[1]; // write - input to parent
609 thdat->ctrl.out = pipe_to_thread [0]; // read - output from parent
610 pd->ctrl.in = pipe_to_thread [1]; // write - input to child
611 pd->ctrl.out = pipe_from_thread[0]; // read - output from child
612 // yes - these are blocking because we write and read very little
613 eina_file_close_on_exec(pd->ctrl.in, EINA_TRUE);
614 eina_file_close_on_exec(pd->ctrl.out, EINA_TRUE);
615 eina_file_close_on_exec(thdat->ctrl.in, EINA_TRUE);
616 eina_file_close_on_exec(thdat->ctrl.out, EINA_TRUE);
617 pd->ctrl.in_handler =
618 efl_add(EFL_LOOP_HANDLER_CLASS, obj,
619 efl_loop_handler_fd_set(efl_added, pd->ctrl.in));
620 pd->ctrl.out_handler =
621 efl_add(EFL_LOOP_HANDLER_CLASS, obj,
622 efl_loop_handler_fd_set(efl_added, pd->ctrl.out),
623 efl_event_callback_add
624 (efl_added, EFL_LOOP_HANDLER_EVENT_READ, _cb_thread_parent_ctrl_out, obj),
625 efl_loop_handler_active_set
626 (efl_added, EFL_LOOP_HANDLER_FLAGS_READ));
627
628 switch (efl_task_priority_get(obj))
629 {
630 case EFL_TASK_PRIORITY_BACKGROUND:
631 pri = EINA_THREAD_IDLE;
632 break;
633 case EFL_TASK_PRIORITY_HIGH:
634 case EFL_TASK_PRIORITY_ULTRA:
635 pri = EINA_THREAD_URGENT;
636 break;
637 case EFL_TASK_PRIORITY_LOW:
638 pri = EINA_THREAD_BACKGROUND;
639 break;
640 case EFL_TASK_PRIORITY_NORMAL:
641 default:
642 pri = EINA_THREAD_NORMAL;
643 break;
644 }
645 name = efl_name_get(obj);
646 if (name) thdat->name = eina_stringshare_add(name);
647
648 argc = efl_task_arg_count_get(obj);
649 if (argc > 0)
650 {
651 thdat->args.argc = argc;
652 thdat->args.argv = malloc(argc * sizeof(char *));
653 if (thdat->args.argv)
654 {
655 for (i = 0; i < argc; i++)
656 {
657 const char *argv = efl_task_arg_value_get(obj, i);
658 if (argv)
659 thdat->args.argv[i] = eina_stringshare_add(argv);
660 else
661 thdat->args.argv[i] = NULL;
662 }
663 }
664 // XXX: if malloc fails?
665 }
666 if (pd->event_cb)
667 {
668 num = 0;
669 for (it = pd->event_cb; it->func; it++) num++;
670 thdat->event_cb = malloc((num + 1) * sizeof(Efl_Callback_Array_Item_Full));
671 if (thdat->event_cb)
672 memcpy(thdat->event_cb, pd->event_cb,
673 (num + 1) * sizeof(Efl_Callback_Array_Item_Full));
674 // XXX: if malloc fails?
675 }
676
677 // env data - ignore as other end will share same env
678
679 if (!eina_thread_create(&(pd->thread), pri, -1, _efl_thread_main, thdat))
680 {
681 for (i = 0; i < thdat->args.argc; i++)
682 eina_stringshare_del(thdat->args.argv[i]);
683 free(thdat->args.argv);
684 efl_del(pd->fd.in_handler);
685 efl_del(pd->fd.out_handler);
686 efl_del(pd->ctrl.in_handler);
687 efl_del(pd->ctrl.out_handler);
688 close(pd->fd.in);
689 close(pd->fd.out);
690 close(pd->ctrl.in);
691 close(pd->ctrl.out);
692 close(thdat->fd.in);
693 close(thdat->fd.out);
694 close(thdat->ctrl.in);
695 close(thdat->ctrl.out);
696 free(thdat);
697 pd->fd.in_handler = NULL;
698 pd->fd.out_handler = NULL;
699 pd->ctrl.in_handler = NULL;
700 pd->ctrl.out_handler = NULL;
701 pd->fd.in = -1;
702 pd->fd.out = -1;
703 pd->ctrl.in = -1;
704 pd->ctrl.out = -1;
705 return EINA_FALSE;
706 }
707 pd->thdat = thdat;
708 return EINA_TRUE;
709}
710
711EOLIAN static void
712_efl_thread_efl_task_end(Eo *obj EINA_UNUSED, Efl_Thread_Data *pd)
713{
714 if (pd->end_sent) return;
715 if (pd->thdat)
716 {
717 Control_Data cmd;
718
719 pd->end_sent = EINA_TRUE;
720 cmd.command = CMD_EXIT;
721 cmd.data = 0;
722 write(pd->ctrl.in, &cmd, sizeof(Control_Data));
723 }
724}
725
726EOLIAN static Eina_Error
727_efl_thread_efl_io_closer_close(Eo *obj, Efl_Thread_Data *pd)
728{
729 if (!pd->thdat) return 0;
730 EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(obj), EBADF);
731 efl_io_writer_can_write_set(obj, EINA_FALSE);
732 efl_io_reader_can_read_set(obj, EINA_FALSE);
733 efl_io_reader_eos_set(obj, EINA_TRUE);
734 if (pd->fd.in >= 0) close(pd->fd.in);
735 if (pd->fd.out >= 0) close(pd->fd.out);
736 if (pd->fd.in_handler) efl_del(pd->fd.in_handler);
737 if (pd->fd.out_handler) efl_del(pd->fd.out_handler);
738 pd->fd.in = -1;
739 pd->fd.out = -1;
740 pd->fd.in_handler = NULL;
741 pd->fd.out_handler = NULL;
742 return 0;
743}
744
745EOLIAN static Eina_Bool
746_efl_thread_efl_io_closer_closed_get(Eo *obj EINA_UNUSED, Efl_Thread_Data *pd)
747{
748 if ((pd->fd.in == -1) && (pd->fd.out == -1)) return EINA_TRUE;
749 return EINA_FALSE;
750}
751
752EOLIAN static Eina_Error
753_efl_thread_efl_io_reader_read(Eo *obj, Efl_Thread_Data *pd, Eina_Rw_Slice *rw_slice)
754{
755 ssize_t r;
756
757 errno = 0;
758 if (pd->fd.out == -1) goto err;
759
760 do
761 {
762 errno = 0;
763 r = read(pd->fd.out, rw_slice->mem, rw_slice->len);
764 if (r == -1)
765 {
766 if (errno == EINTR) continue;
767 goto err;
768 }
769 }
770 while (r == -1);
771
772 rw_slice->len = r;
773 if (r == 0)
774 {
775 efl_io_reader_can_read_set(obj, EINA_FALSE);
776 efl_io_reader_eos_set(obj, EINA_TRUE);
777 close(pd->fd.out);
778 pd->fd.out = -1;
779 efl_del(pd->fd.out_handler);
780 pd->fd.out_handler = NULL;
781 _thread_exit_eval(obj, pd);
782 return EPIPE;
783 }
784 return 0;
785err:
786 if ((pd->fd.out != -1) && (errno != EAGAIN))
787 {
788 close(pd->fd.out);
789 pd->fd.out = -1;
790 efl_del(pd->fd.out_handler);
791 pd->fd.out_handler = NULL;
792 }
793 rw_slice->len = 0;
794 rw_slice->mem = NULL;
795 efl_io_reader_can_read_set(obj, EINA_FALSE);
796 _thread_exit_eval(obj, pd);
797 return EINVAL;
798}
799
800EOLIAN static void
801_efl_thread_efl_io_reader_can_read_set(Eo *obj, Efl_Thread_Data *pd, Eina_Bool can_read)
802{
803 Eina_Bool old = efl_io_reader_can_read_get(obj);
804 if (old == can_read) return;
805 pd->fd.can_read = can_read;
806 if (!pd->fd.out_handler) return;
807 if (can_read)
808 efl_loop_handler_active_set(pd->fd.out_handler, 0);
809 else
810 efl_loop_handler_active_set(pd->fd.out_handler,
811 EFL_LOOP_HANDLER_FLAGS_READ);
812 efl_event_callback_call(obj, EFL_IO_READER_EVENT_CAN_READ_CHANGED, NULL);
813}
814
815EOLIAN static Eina_Bool
816_efl_thread_efl_io_reader_can_read_get(Eo *obj EINA_UNUSED, Efl_Thread_Data *pd)
817{
818 return pd->fd.can_read;
819}
820
821EOLIAN static void
822_efl_thread_efl_io_reader_eos_set(Eo *obj, Efl_Thread_Data *pd, Eina_Bool is_eos)
823{
824 Eina_Bool old = efl_io_reader_eos_get(obj);
825 if (old == is_eos) return;
826
827 pd->fd.eos_read = is_eos;
828 if (!is_eos) return;
829 if (pd->fd.out_handler)
830 efl_loop_handler_active_set(pd->fd.out_handler, 0);
831 efl_event_callback_call(obj, EFL_IO_READER_EVENT_EOS, NULL);
832}
833
834EOLIAN static Eina_Bool
835_efl_thread_efl_io_reader_eos_get(Eo *obj EINA_UNUSED, Efl_Thread_Data *pd)
836{
837 return pd->fd.eos_read;
838}
839
840EOLIAN static Eina_Error
841_efl_thread_efl_io_writer_write(Eo *obj, Efl_Thread_Data *pd, Eina_Slice *slice, Eina_Slice *remaining)
842{
843 ssize_t r;
844
845 errno = 0;
846 if (pd->fd.in == -1) goto err;
847
848 do
849 {
850 errno = 0;
851 r = write(pd->fd.in, slice->mem, slice->len);
852 if (r == -1)
853 {
854 if (errno == EINTR) continue;
855 goto err;
856 }
857 }
858 while (r == -1);
859
860 if (remaining)
861 {
862 remaining->len = slice->len - r;
863 remaining->bytes = slice->bytes + r;
864 }
865 slice->len = r;
866
867 if ((slice) && (slice->len > 0))
868 efl_io_writer_can_write_set(obj, EINA_FALSE);
869 if (r == 0)
870 {
871 close(pd->fd.in);
872 pd->fd.in = -1;
873 efl_del(pd->fd.in_handler);
874 pd->fd.in_handler = NULL;
875 _thread_exit_eval(obj, pd);
876 return EPIPE;
877 }
878 return 0;
879err:
880 if ((pd->fd.in != -1) && (errno != EAGAIN))
881 {
882 close(pd->fd.in);
883 pd->fd.in = -1;
884 efl_del(pd->fd.in_handler);
885 pd->fd.in_handler = NULL;
886 }
887 if (remaining) *remaining = *slice;
888 slice->len = 0;
889 slice->mem = NULL;
890 efl_io_writer_can_write_set(obj, EINA_FALSE);
891 _thread_exit_eval(obj, pd);
892 return EINVAL;
893}
894
895EOLIAN static void
896_efl_thread_efl_io_writer_can_write_set(Eo *obj, Efl_Thread_Data *pd, Eina_Bool can_write)
897{
898 Eina_Bool old = efl_io_writer_can_write_get(obj);
899 if (old == can_write) return;
900 pd->fd.can_write = can_write;
901 if (can_write)
902 efl_loop_handler_active_set(pd->fd.in_handler, 0);
903 else
904 efl_loop_handler_active_set(pd->fd.in_handler,
905 EFL_LOOP_HANDLER_FLAGS_WRITE);
906 efl_event_callback_call(obj, EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED, NULL);
907}
908
909EOLIAN static Eina_Bool
910_efl_thread_efl_io_writer_can_write_get(Eo *obj EINA_UNUSED, Efl_Thread_Data *pd)
911{
912 return pd->fd.can_write;
913}
914
915//////////////////////////////////////////////////////////////////////////
916
917#include "efl_thread.eo.c"
diff --git a/src/lib/ecore/efl_thread.eo b/src/lib/ecore/efl_thread.eo
index 63b7292131..214c0fd07f 100644
--- a/src/lib/ecore/efl_thread.eo
+++ b/src/lib/ecore/efl_thread.eo
@@ -8,5 +8,15 @@ class Efl.Thread (Efl.Task)
8 implements { 8 implements {
9 Efl.Object.constructor; 9 Efl.Object.constructor;
10 Efl.Object.destructor; 10 Efl.Object.destructor;
11 Efl.Object.parent { set; }
12 Efl.Task.run;
13 Efl.Task.end;
14 Efl.Io.Closer.close;
15 Efl.Io.Closer.closed { get; }
16 Efl.Io.Reader.read;
17 Efl.Io.Reader.can_read { get; set; }
18 Efl.Io.Reader.eos { get; set; }
19 Efl.Io.Writer.write;
20 Efl.Io.Writer.can_write { get; set; }
11 } 21 }
12} 22}
diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c
index 67ab7e9fd0..4348da8084 100644
--- a/src/lib/ecore_evas/ecore_evas.c
+++ b/src/lib/ecore_evas/ecore_evas.c
@@ -3195,7 +3195,7 @@ _ecore_evas_animator_fallback(void *data)
3195static void 3195static void
3196_check_animator_event_catcher_add(void *data, const Efl_Event *event) 3196_check_animator_event_catcher_add(void *data, const Efl_Event *event)
3197{ 3197{
3198 const Efl_Callback_Array_Item *array = event->info; 3198 const Efl_Callback_Array_Item_Full *array = event->info;
3199 Ecore_Evas *ee = data; 3199 Ecore_Evas *ee = data;
3200 int i; 3200 int i;
3201 3201
@@ -3229,7 +3229,7 @@ _check_animator_event_catcher_add(void *data, const Efl_Event *event)
3229static void 3229static void
3230_check_animator_event_catcher_del(void *data, const Efl_Event *event) 3230_check_animator_event_catcher_del(void *data, const Efl_Event *event)
3231{ 3231{
3232 const Efl_Callback_Array_Item *array = event->info; 3232 const Efl_Callback_Array_Item_Full *array = event->info;
3233 Ecore_Evas *ee = data; 3233 Ecore_Evas *ee = data;
3234 int i; 3234 int i;
3235 3235
diff --git a/src/lib/eina/eina_internal.h b/src/lib/eina/eina_internal.h
index 9324118c91..83e6f5da61 100644
--- a/src/lib/eina/eina_internal.h
+++ b/src/lib/eina/eina_internal.h
@@ -71,6 +71,8 @@ struct _Eina_Vpath_Interface_User
71 */ 71 */
72EAPI void __eina_promise_cancel_all(void); 72EAPI void __eina_promise_cancel_all(void);
73 73
74EAPI void __eina_promise_cancel_data(void *data);
75
74/** 76/**
75 * Make the app specific paths accessable as virtual path 77 * Make the app specific paths accessable as virtual path
76 * 78 *
diff --git a/src/lib/eina/eina_promise.c b/src/lib/eina/eina_promise.c
index c3b488d223..93e091bd9e 100644
--- a/src/lib/eina/eina_promise.c
+++ b/src/lib/eina/eina_promise.c
@@ -566,6 +566,27 @@ __eina_promise_cancel_all(void)
566 eina_lock_release(&_pending_futures_lock); 566 eina_lock_release(&_pending_futures_lock);
567} 567}
568 568
569EAPI void
570__eina_promise_cancel_data(void *data)
571{
572 Eina_List *del = NULL, *l;
573 Eina_Future *f;
574
575 eina_lock_take(&_pending_futures_lock);
576 EINA_LIST_FOREACH(_pending_futures, l, f)
577 {
578 if (f->data == data)
579 {
580 del = eina_list_append(del, f);
581 }
582 }
583 EINA_LIST_FREE(del, f)
584 {
585 _eina_future_cancel(f, ECANCELED);
586 }
587 eina_lock_release(&_pending_futures_lock);
588}
589
569Eina_Bool 590Eina_Bool
570eina_promise_shutdown(void) 591eina_promise_shutdown(void)
571{ 592{
diff --git a/src/lib/elementary/efl_ui_text.c b/src/lib/elementary/efl_ui_text.c
index 98dda2afea..b8fa0ea20e 100644
--- a/src/lib/elementary/efl_ui_text.c
+++ b/src/lib/elementary/efl_ui_text.c
@@ -2975,9 +2975,10 @@ _efl_ui_text_efl_canvas_group_group_member_add(Eo *obj, Efl_Ui_Text_Data *sd, Ev
2975static void 2975static void
2976_cb_added(void *data EINA_UNUSED, const Efl_Event *ev) 2976_cb_added(void *data EINA_UNUSED, const Efl_Event *ev)
2977{ 2977{
2978 const Efl_Callback_Array_Item *event = ev->info; 2978 const Efl_Callback_Array_Item_Full *event = ev->info;
2979 2979
2980 EFL_UI_TEXT_DATA_GET(ev->object, sd); 2980 EFL_UI_TEXT_DATA_GET(ev->object, sd);
2981 // XXX: BUG - not walking the array until a NULL entry
2981 if (event->desc == EFL_UI_TEXT_EVENT_VALIDATE) 2982 if (event->desc == EFL_UI_TEXT_EVENT_VALIDATE)
2982 sd->validators++; 2983 sd->validators++;
2983} 2984}
@@ -2985,9 +2986,10 @@ _cb_added(void *data EINA_UNUSED, const Efl_Event *ev)
2985static void 2986static void
2986_cb_deleted(void *data EINA_UNUSED, const Efl_Event *ev) 2987_cb_deleted(void *data EINA_UNUSED, const Efl_Event *ev)
2987{ 2988{
2988 const Efl_Callback_Array_Item *event = ev->info; 2989 const Efl_Callback_Array_Item_Full *event = ev->info;
2989 2990
2990 EFL_UI_TEXT_DATA_GET(ev->object, sd); 2991 EFL_UI_TEXT_DATA_GET(ev->object, sd);
2992 // XXX: BUG - not walking the array until a NULL entry
2991 if (event->desc == EFL_UI_TEXT_EVENT_VALIDATE) 2993 if (event->desc == EFL_UI_TEXT_EVENT_VALIDATE)
2992 sd->validators--; 2994 sd->validators--;
2993 return; 2995 return;
diff --git a/src/lib/elementary/efl_ui_win.c b/src/lib/elementary/efl_ui_win.c
index f9f9723d8e..0059cfb9b0 100644
--- a/src/lib/elementary/efl_ui_win.c
+++ b/src/lib/elementary/efl_ui_win.c
@@ -1904,7 +1904,7 @@ _elm_win_evas_device_changed(void *data,
1904static void 1904static void
1905_win_event_add_cb(void *data, const Efl_Event *ev) 1905_win_event_add_cb(void *data, const Efl_Event *ev)
1906{ 1906{
1907 const Efl_Callback_Array_Item *array = ev->info; 1907 const Efl_Callback_Array_Item_Full *array = ev->info;
1908 Efl_Ui_Win_Data *sd = data; 1908 Efl_Ui_Win_Data *sd = data;
1909 Efl_Ui_Win *win = ev->object; 1909 Efl_Ui_Win *win = ev->object;
1910 int i; 1910 int i;
@@ -2035,7 +2035,7 @@ _win_event_add_cb(void *data, const Efl_Event *ev)
2035static void 2035static void
2036_win_event_del_cb(void *data, const Efl_Event *ev) 2036_win_event_del_cb(void *data, const Efl_Event *ev)
2037{ 2037{
2038 const Efl_Callback_Array_Item *array = ev->info; 2038 const Efl_Callback_Array_Item_Full *array = ev->info;
2039 Efl_Ui_Win_Data *sd = data; 2039 Efl_Ui_Win_Data *sd = data;
2040 Efl_Ui_Win *win = ev->object; 2040 Efl_Ui_Win *win = ev->object;
2041 int i; 2041 int i;
@@ -2177,7 +2177,7 @@ _win_paused(void *data, const Efl_Event *ev)
2177 _paused_windows++; 2177 _paused_windows++;
2178 2178
2179 if (_elm_win_count == _paused_windows) 2179 if (_elm_win_count == _paused_windows)
2180 efl_event_callback_call(efl_loop_get(ev->object), EFL_LOOP_EVENT_PAUSE, NULL); 2180 efl_event_callback_call(efl_loop_get(ev->object), EFL_APP_EVENT_PAUSE, NULL);
2181} 2181}
2182 2182
2183EFL_CALLBACKS_ARRAY_DEFINE(_elm_win_tracking, 2183EFL_CALLBACKS_ARRAY_DEFINE(_elm_win_tracking,
@@ -2205,7 +2205,7 @@ _elm_win_resume(void *data, const Efl_Event *ev)
2205 sd->paused = EINA_FALSE; 2205 sd->paused = EINA_FALSE;
2206 2206
2207 if (_elm_win_count == _paused_windows) 2207 if (_elm_win_count == _paused_windows)
2208 efl_event_callback_call(efl_loop_get(ev->object), EFL_LOOP_EVENT_RESUME, NULL); 2208 efl_event_callback_call(efl_loop_get(ev->object), EFL_APP_EVENT_RESUME, NULL);
2209 2209
2210 _paused_windows--; 2210 _paused_windows--;
2211} 2211}
@@ -2831,7 +2831,7 @@ _efl_ui_win_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Win_Data *sd)
2831 _elm_win_state_eval_queue(); 2831 _elm_win_state_eval_queue();
2832 2832
2833 if (_elm_win_count == _paused_windows) 2833 if (_elm_win_count == _paused_windows)
2834 efl_event_callback_call(efl_loop_get(obj), EFL_LOOP_EVENT_PAUSE, NULL); 2834 efl_event_callback_call(efl_loop_get(obj), EFL_APP_EVENT_PAUSE, NULL);
2835 2835
2836 if (sd->ee) 2836 if (sd->ee)
2837 { 2837 {
@@ -5474,7 +5474,7 @@ _efl_ui_win_efl_object_finalize(Eo *obj, Efl_Ui_Win_Data *sd)
5474 obj = _elm_win_finalize_internal(obj, sd, sd->name, sd->type); 5474 obj = _elm_win_finalize_internal(obj, sd, sd->name, sd->type);
5475 if (!obj) return NULL; 5475 if (!obj) return NULL;
5476 obj = efl_finalize(efl_super(obj, MY_CLASS)); 5476 obj = efl_finalize(efl_super(obj, MY_CLASS));
5477 if (obj && resume) efl_event_callback_call(efl_loop_get(obj), EFL_LOOP_EVENT_RESUME, NULL); 5477 if (obj && resume) efl_event_callback_call(efl_loop_get(obj), EFL_APP_EVENT_RESUME, NULL);
5478 return obj; 5478 return obj;
5479} 5479}
5480 5480
diff --git a/src/lib/elementary/elm_entry.c b/src/lib/elementary/elm_entry.c
index 0b61f24124..eff0bbfa65 100644
--- a/src/lib/elementary/elm_entry.c
+++ b/src/lib/elementary/elm_entry.c
@@ -4061,9 +4061,10 @@ elm_entry_add(Evas_Object *parent)
4061static void 4061static void
4062_cb_added(void *data EINA_UNUSED, const Efl_Event *ev) 4062_cb_added(void *data EINA_UNUSED, const Efl_Event *ev)
4063{ 4063{
4064 const Efl_Callback_Array_Item *event = ev->info; 4064 const Efl_Callback_Array_Item_Full *event = ev->info;
4065 4065
4066 ELM_ENTRY_DATA_GET(ev->object, sd); 4066 ELM_ENTRY_DATA_GET(ev->object, sd);
4067 // XXX: BUG - not walking the array until a NULL entry
4067 if (event->desc == ELM_ENTRY_EVENT_VALIDATE) 4068 if (event->desc == ELM_ENTRY_EVENT_VALIDATE)
4068 sd->validators++; 4069 sd->validators++;
4069} 4070}
@@ -4071,9 +4072,10 @@ _cb_added(void *data EINA_UNUSED, const Efl_Event *ev)
4071static void 4072static void
4072_cb_deleted(void *data EINA_UNUSED, const Efl_Event *ev) 4073_cb_deleted(void *data EINA_UNUSED, const Efl_Event *ev)
4073{ 4074{
4074 const Efl_Callback_Array_Item *event = ev->info; 4075 const Efl_Callback_Array_Item_Full *event = ev->info;
4075 4076
4076 ELM_ENTRY_DATA_GET(ev->object, sd); 4077 ELM_ENTRY_DATA_GET(ev->object, sd);
4078 // XXX: BUG - not walking the array until a NULL entry
4077 if (event->desc == ELM_ENTRY_EVENT_VALIDATE) 4079 if (event->desc == ELM_ENTRY_EVENT_VALIDATE)
4078 sd->validators--; 4080 sd->validators--;
4079 return; 4081 return;
diff --git a/src/lib/elementary/elm_main.c b/src/lib/elementary/elm_main.c
index 646b2ee474..82efe0a3c7 100644
--- a/src/lib/elementary/elm_main.c
+++ b/src/lib/elementary/elm_main.c
@@ -927,8 +927,8 @@ static void (*qre_terminate)(void *data,
927 927
928EFL_CALLBACKS_ARRAY_DEFINE(_qre_main_ex, 928EFL_CALLBACKS_ARRAY_DEFINE(_qre_main_ex,
929 { EFL_LOOP_EVENT_ARGUMENTS, qre_main }, 929 { EFL_LOOP_EVENT_ARGUMENTS, qre_main },
930 { EFL_LOOP_EVENT_PAUSE, qre_pause }, 930 { EFL_APP_EVENT_PAUSE, qre_pause },
931 { EFL_LOOP_EVENT_RESUME, qre_resume }, 931 { EFL_APP_EVENT_RESUME, qre_resume },
932 { EFL_EVENT_DEL, qre_terminate }); 932 { EFL_EVENT_DEL, qre_terminate });
933 933
934EAPI Eina_Bool 934EAPI Eina_Bool
@@ -1304,12 +1304,12 @@ elm_policy_set(unsigned int policy,
1304 { 1304 {
1305 if (value == ELM_POLICY_EXIT_WINDOWS_DEL) 1305 if (value == ELM_POLICY_EXIT_WINDOWS_DEL)
1306 { 1306 {
1307 efl_event_callback_add(efl_main_loop_get(), EFL_LOOP_EVENT_TERMINATE, 1307 efl_event_callback_add(efl_main_loop_get(), EFL_APP_EVENT_TERMINATE,
1308 _on_terminate, NULL); 1308 _on_terminate, NULL);
1309 } 1309 }
1310 else 1310 else
1311 { 1311 {
1312 efl_event_callback_del(efl_main_loop_get(), EFL_LOOP_EVENT_TERMINATE, 1312 efl_event_callback_del(efl_main_loop_get(), EFL_APP_EVENT_TERMINATE,
1313 _on_terminate, NULL); 1313 _on_terminate, NULL);
1314 } 1314 }
1315 } 1315 }
diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
index 441b3789fc..7c20daaccb 100644
--- a/src/lib/eo/Eo.h
+++ b/src/lib/eo/Eo.h
@@ -241,10 +241,25 @@ typedef short Efl_Callback_Priority;
241 */ 241 */
242typedef struct _Efl_Callback_Array_Item 242typedef struct _Efl_Callback_Array_Item
243{ 243{
244 const Efl_Event_Description *desc; /**< The event description. */ 244 const Efl_Event_Description *desc; /**< The event description. */
245 Efl_Event_Cb func; /**< The callback function. */ 245 Efl_Event_Cb func; /**< The callback function. */
246} Efl_Callback_Array_Item; 246} Efl_Callback_Array_Item;
247 247
248
249/**
250 * @struct _Efl_Callback_Array_Item_Full
251 * @brief An item provided by EFL_EVENT_CALLBACK_ADD/EFL_EVENT_CALLBACK_DEL.
252 *
253 * See also EFL_EVENT_CALLBACK_ADD EFL_EVENT_CALLBACK_DEL.
254 */
255typedef struct _Efl_Callback_Array_Item_Full
256{
257 const Efl_Event_Description *desc; /**< The event description. */
258 Efl_Callback_Priority priority; /** < The priorit of the event */
259 Efl_Event_Cb func; /**< The callback function. */
260 void *user_data; /**< The user data pointer to be passed to the func */
261} Efl_Callback_Array_Item_Full;
262
248/** 263/**
249 * @brief Add a callback for an event with a specific priority. 264 * @brief Add a callback for an event with a specific priority.
250 * 265 *
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index ca38e7b171..f1eff91f3e 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -1228,7 +1228,8 @@ _efl_object_event_callback_priority_add(Eo *obj, Efl_Object_Data *pd,
1228 Efl_Event_Cb func, 1228 Efl_Event_Cb func,
1229 const void *user_data) 1229 const void *user_data)
1230{ 1230{
1231 const Efl_Callback_Array_Item arr[] = { {desc, func}, {NULL, NULL}}; 1231 const Efl_Callback_Array_Item_Full arr[] =
1232 { {desc, priority, func, (void *)user_data}, {NULL, 0, NULL, NULL}};
1232 Eo_Callback_Description *cb = _eo_callback_new(); 1233 Eo_Callback_Description *cb = _eo_callback_new();
1233 1234
1234 // very unlikely so improve l1 instr cache by using goto 1235 // very unlikely so improve l1 instr cache by using goto
@@ -1265,7 +1266,7 @@ EOAPI EFL_FUNC_BODYV(efl_event_callback_priority_add,
1265 1266
1266static void 1267static void
1267_efl_object_event_callback_clean(Eo *obj, Efl_Object_Data *pd, 1268_efl_object_event_callback_clean(Eo *obj, Efl_Object_Data *pd,
1268 const Efl_Callback_Array_Item *array, 1269 const Efl_Callback_Array_Item_Full *array,
1269 Eo_Callback_Description **cb) 1270 Eo_Callback_Description **cb)
1270{ 1271{
1271 (*cb)->delete_me = EINA_TRUE; 1272 (*cb)->delete_me = EINA_TRUE;
@@ -1295,7 +1296,8 @@ _efl_object_event_callback_del(Eo *obj, Efl_Object_Data *pd,
1295 ((*cb)->items.item.func == func) && 1296 ((*cb)->items.item.func == func) &&
1296 ((*cb)->func_data == user_data)) 1297 ((*cb)->func_data == user_data))
1297 { 1298 {
1298 const Efl_Callback_Array_Item arr[] = { {desc, func}, {NULL, NULL}}; 1299 const Efl_Callback_Array_Item_Full arr[] =
1300 { {desc, (*cb)->priority, func, (*cb)->func_data}, {NULL, 0, NULL, NULL}};
1299 1301
1300 _efl_object_event_callback_clean(obj, pd, arr, cb); 1302 _efl_object_event_callback_clean(obj, pd, arr, cb);
1301 return EINA_TRUE; 1303 return EINA_TRUE;
@@ -1318,9 +1320,9 @@ _efl_object_event_callback_array_priority_add(Eo *obj, Efl_Object_Data *pd,
1318 const void *user_data) 1320 const void *user_data)
1319{ 1321{
1320 Eo_Callback_Description *cb = _eo_callback_new(); 1322 Eo_Callback_Description *cb = _eo_callback_new();
1321#if defined(EFL_EVENT_SPECIAL_SKIP) || defined(EO_DEBUG)
1322 const Efl_Callback_Array_Item *it; 1323 const Efl_Callback_Array_Item *it;
1323#endif 1324 unsigned int num, i;
1325 Efl_Callback_Array_Item_Full *ev_array;
1324#ifdef EO_DEBUG 1326#ifdef EO_DEBUG
1325 const Efl_Callback_Array_Item *prev; 1327 const Efl_Callback_Array_Item *prev;
1326#endif 1328#endif
@@ -1363,7 +1365,21 @@ _efl_object_event_callback_array_priority_add(Eo *obj, Efl_Object_Data *pd,
1363 } 1365 }
1364#endif 1366#endif
1365 1367
1366 efl_event_callback_call(obj, EFL_EVENT_CALLBACK_ADD, (void *)array); 1368 num = 0;
1369 for (it = cb->items.item_array; it->func; it++) num++;
1370 ev_array = alloca((num + 1) * sizeof(Efl_Callback_Array_Item_Full));
1371 for (i = 0, it = cb->items.item_array; it->func; it++, i++)
1372 {
1373 ev_array[i].desc = cb->items.item_array[i].desc;
1374 ev_array[i].priority = cb->priority;
1375 ev_array[i].func = cb->items.item_array[i].func;
1376 ev_array[i].user_data = cb->func_data;
1377 }
1378 ev_array[i].desc = NULL;
1379 ev_array[i].priority = 0;
1380 ev_array[i].func = NULL;
1381 ev_array[i].user_data = NULL;
1382 efl_event_callback_call(obj, EFL_EVENT_CALLBACK_ADD, ev_array);
1367 1383
1368 return EINA_TRUE; 1384 return EINA_TRUE;
1369 1385
@@ -1384,17 +1400,35 @@ _efl_object_event_callback_array_del(Eo *obj, Efl_Object_Data *pd,
1384 const void *user_data) 1400 const void *user_data)
1385{ 1401{
1386 Eo_Callback_Description **cb; 1402 Eo_Callback_Description **cb;
1387 unsigned int i; 1403 unsigned int j;
1388 1404
1389 for (cb = pd->callbacks, i = 0; 1405 for (cb = pd->callbacks, j = 0;
1390 i < pd->callbacks_count; 1406 j < pd->callbacks_count;
1391 cb++, i++) 1407 cb++, j++)
1392 { 1408 {
1393 if (!(*cb)->delete_me && 1409 if (!(*cb)->delete_me &&
1394 ((*cb)->items.item_array == array) && 1410 ((*cb)->items.item_array == array) &&
1395 ((*cb)->func_data == user_data)) 1411 ((*cb)->func_data == user_data))
1396 { 1412 {
1397 _efl_object_event_callback_clean(obj, pd, array, cb); 1413 const Efl_Callback_Array_Item *it;
1414 unsigned int num, i;
1415 Efl_Callback_Array_Item_Full *ev_array;
1416
1417 num = 0;
1418 for (it = (*cb)->items.item_array; it->func; it++) num++;
1419 ev_array = alloca((num + 1) * sizeof(Efl_Callback_Array_Item_Full));
1420 for (i = 0, it = (*cb)->items.item_array; it->func; it++, i++)
1421 {
1422 ev_array[i].desc = (*cb)->items.item_array[i].desc;
1423 ev_array[i].priority = (*cb)->priority;
1424 ev_array[i].func = (*cb)->items.item_array[i].func;
1425 ev_array[i].user_data = (*cb)->func_data;
1426 }
1427 ev_array[i].desc = NULL;
1428 ev_array[i].priority = 0;
1429 ev_array[i].func = NULL;
1430 ev_array[i].user_data = NULL;
1431 _efl_object_event_callback_clean(obj, pd, ev_array, cb);
1398 return EINA_TRUE; 1432 return EINA_TRUE;
1399 } 1433 }
1400 } 1434 }
diff --git a/src/lib/evas/canvas/evas_callbacks.c b/src/lib/evas/canvas/evas_callbacks.c
index 4f63c2323d..8896dea691 100644
--- a/src/lib/evas/canvas/evas_callbacks.c
+++ b/src/lib/evas/canvas/evas_callbacks.c
@@ -700,7 +700,7 @@ _animator_repeater(void *data, const Efl_Event *event)
700static void 700static void
701_check_event_catcher_add(void *data, const Efl_Event *event) 701_check_event_catcher_add(void *data, const Efl_Event *event)
702{ 702{
703 const Efl_Callback_Array_Item *array = event->info; 703 const Efl_Callback_Array_Item_Full *array = event->info;
704 Evas_Object_Protected_Data *obj = data; 704 Evas_Object_Protected_Data *obj = data;
705 Evas_Callback_Type type = EVAS_CALLBACK_LAST; 705 Evas_Callback_Type type = EVAS_CALLBACK_LAST;
706 int i; 706 int i;
@@ -728,7 +728,7 @@ _check_event_catcher_add(void *data, const Efl_Event *event)
728static void 728static void
729_check_event_catcher_del(void *data, const Efl_Event *event) 729_check_event_catcher_del(void *data, const Efl_Event *event)
730{ 730{
731 const Efl_Callback_Array_Item *array = event->info; 731 const Efl_Callback_Array_Item_Full *array = event->info;
732 Evas_Object_Protected_Data *obj = data; 732 Evas_Object_Protected_Data *obj = data;
733 int i; 733 int i;
734 734
diff --git a/src/tests/ecore/ecore_test_ecore.c b/src/tests/ecore/ecore_test_ecore.c
index 492c2aa033..6fd95738f4 100644
--- a/src/tests/ecore/ecore_test_ecore.c
+++ b/src/tests/ecore/ecore_test_ecore.c
@@ -896,11 +896,11 @@ START_TEST(ecore_test_efl_app_version)
896 896
897 ecore_init(); 897 ecore_init();
898 898
899 loop = efl_loop_main_get(EFL_LOOP_CLASS); 899 loop = efl_app_loop_main_get(EFL_APP_CLASS);
900 fail_if(!efl_isa(loop, EFL_LOOP_CLASS)); 900 fail_if(!efl_isa(loop, EFL_LOOP_CLASS));
901 901
902 efl_build_version_set(EFL_VERSION_MAJOR, EFL_VERSION_MINOR, 0, 0, NULL, EFL_BUILD_ID); 902 efl_build_version_set(EFL_VERSION_MAJOR, EFL_VERSION_MINOR, 0, 0, NULL, EFL_BUILD_ID);
903 ver = efl_loop_app_efl_version_get(loop); 903 ver = efl_app_build_efl_version_get(loop);
904 fail_if(!ver); 904 fail_if(!ver);
905 fail_if(ver->major != EFL_VERSION_MAJOR); 905 fail_if(ver->major != EFL_VERSION_MAJOR);
906 fail_if(ver->minor != EFL_VERSION_MINOR); 906 fail_if(ver->minor != EFL_VERSION_MINOR);
@@ -909,7 +909,7 @@ START_TEST(ecore_test_efl_app_version)
909 fail_if(ver->flavor); 909 fail_if(ver->flavor);
910 fail_if(!eina_streq(ver->build_id, EFL_BUILD_ID)); 910 fail_if(!eina_streq(ver->build_id, EFL_BUILD_ID));
911 911
912 ver = efl_loop_efl_version_get(loop); 912 ver = efl_app_efl_version_get(loop);
913 fail_if(!ver); 913 fail_if(!ver);
914 fail_if(ver->major != EFL_VERSION_MAJOR); 914 fail_if(ver->major != EFL_VERSION_MAJOR);
915 fail_if(ver->minor != EFL_VERSION_MINOR); 915 fail_if(ver->minor != EFL_VERSION_MINOR);
diff --git a/src/tests/elementary/efl_ui_suite.c b/src/tests/elementary/efl_ui_suite.c
index 629bb10faa..d2269b68a7 100644
--- a/src/tests/elementary/efl_ui_suite.c
+++ b/src/tests/elementary/efl_ui_suite.c
@@ -32,10 +32,10 @@ START_TEST(efl_ui_test_init)
32 _efl_startup_time = ecore_time_unix_get(); 32 _efl_startup_time = ecore_time_unix_get();
33 _EFL_APP_VERSION_SET(); 33 _EFL_APP_VERSION_SET();
34 fail_if(!ecore_init()); 34 fail_if(!ecore_init());
35 efl_event_callback_add(efl_app_main_loop_get(efl_app_get()), EFL_LOOP_EVENT_ARGUMENTS, efl_main, NULL); 35 efl_event_callback_add(efl_app_get(), EFL_LOOP_EVENT_ARGUMENTS, efl_main, NULL);
36 fail_if(!ecore_init_ex(argc, argv)); 36 fail_if(!ecore_init_ex(argc, argv));
37 __EFL_MAIN_CONSTRUCTOR; 37 __EFL_MAIN_CONSTRUCTOR;
38 ret__ = efl_loop_begin(efl_app_main_loop_get(efl_app_get())); 38 ret__ = efl_loop_begin(efl_app_get());
39 real__ = efl_loop_exit_code_process(ret__); 39 real__ = efl_loop_exit_code_process(ret__);
40 __EFL_MAIN_DESTRUCTOR; 40 __EFL_MAIN_DESTRUCTOR;
41 ecore_shutdown_ex(); 41 ecore_shutdown_ex();
diff --git a/src/tests/eo/signals/signals_simple.c b/src/tests/eo/signals/signals_simple.c
index 9449c3f8c0..0e016dc550 100644
--- a/src/tests/eo/signals/signals_simple.c
+++ b/src/tests/eo/signals/signals_simple.c
@@ -32,7 +32,7 @@ void
32_cb_added(void *data EINA_UNUSED, const Efl_Event *event) 32_cb_added(void *data EINA_UNUSED, const Efl_Event *event)
33{ 33{
34 Simple_Public_Data *pd = efl_data_scope_get(event->object, MY_CLASS); 34 Simple_Public_Data *pd = efl_data_scope_get(event->object, MY_CLASS);
35 const Efl_Callback_Array_Item *callback_array = event->info; 35 const Efl_Callback_Array_Item_Full *callback_array = event->info;
36 36
37 if (callback_array->desc != EV_A_CHANGED) 37 if (callback_array->desc != EV_A_CHANGED)
38 return; 38 return;
@@ -46,7 +46,7 @@ void
46_cb_deled(void *data EINA_UNUSED, const Efl_Event *event) 46_cb_deled(void *data EINA_UNUSED, const Efl_Event *event)
47{ 47{
48 Simple_Public_Data *pd = efl_data_scope_get(event->object, MY_CLASS); 48 Simple_Public_Data *pd = efl_data_scope_get(event->object, MY_CLASS);
49 const Efl_Callback_Array_Item *callback_array = event->info; 49 const Efl_Callback_Array_Item_Full *callback_array = event->info;
50 50
51 if (callback_array->desc != EV_A_CHANGED) 51 if (callback_array->desc != EV_A_CHANGED)
52 return; 52 return;
diff --git a/src/tests/eo/suite/eo_test_general.c b/src/tests/eo/suite/eo_test_general.c
index e475889e95..18684f1ad2 100644
--- a/src/tests/eo/suite/eo_test_general.c
+++ b/src/tests/eo/suite/eo_test_general.c
@@ -181,11 +181,9 @@ _eo_signals_efl_del_cb(void *_data EINA_UNUSED, const Efl_Event *event EINA_UNUS
181void 181void
182_eo_signals_cb_added_deled(void *data, const Efl_Event *event) 182_eo_signals_cb_added_deled(void *data, const Efl_Event *event)
183{ 183{
184 const Efl_Callback_Array_Item *callback_array = event->info; 184 const Efl_Callback_Array_Item_Full *callback_array = event->info;
185 const Efl_Callback_Array_Item *(*callback_data)(void) = data;
186 185
187 fail_if((callback_data() != callback_array) && 186 fail_if(callback_array->func != _eo_signals_cb_added_deled);
188 (callback_array->func != _eo_signals_cb_added_deled));
189} 187}
190 188
191EFL_CALLBACKS_ARRAY_DEFINE(_eo_signals_callbacks, 189EFL_CALLBACKS_ARRAY_DEFINE(_eo_signals_callbacks,