diff options
author | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2017-11-09 15:59:04 +0900 |
---|---|---|
committer | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2017-12-15 14:16:53 +0900 |
commit | 5dd52fd09b7d79c70b3134423a87aa6400a2d994 (patch) | |
tree | 5b4b8823f857fc2188e14c861af4b21fe356ee45 /src | |
parent | ccfa9ae2201a6b567859f8d16d2674c3be7b81f6 (diff) |
ecore - begin moving data into the efl loop data in the object
we really should have data inside the loop object, so begin moving it
one small thing at a time. this is the basics that will allow multiple
efl loops. make an eo efl object and class for fd handlers that is efl loop
bound make fd handlers really bound to their parent loop and not global as
well as have a nice class/obj. create an message queue per loop and
put legacy ecore events on top of it... and a lot more.
this is not 100% done, but it's a lot of the core and groundwork.
various ecore_timer_add(), ecore_diler_add() etc. need changes.
The following still need doing:
ecore_timer (internal usage for sure)
ecore_idler (internal usage for sure)
ecore_idle_enterer
ecore_idle_exiter
ecore_pollers? (is the new efl loop stuff ok?)
ecore_exe (fork/spawn from any thread and track exe from that thread?)
ecore_signal code
ecore_throttle (should we have a single global too? we have per loop)
ecore_app ? (should every loop be given its own argv/argc?)
Lots of internal ecore code uses/calls these legacy calls and we
should have efl loop replacements and/or use the ones we have
The following will bedifferently designed for loop to loop
control/messaging/ipc:
ecore_thread
ecore_pipe
Diffstat (limited to 'src')
32 files changed, 5063 insertions, 3973 deletions
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am index f96773852a..d0680de060 100644 --- a/src/Makefile_Ecore.am +++ b/src/Makefile_Ecore.am | |||
@@ -3,12 +3,17 @@ | |||
3 | 3 | ||
4 | ecore_eolian_files_legacy = \ | 4 | ecore_eolian_files_legacy = \ |
5 | lib/ecore/ecore_exe.eo \ | 5 | lib/ecore/ecore_exe.eo \ |
6 | lib/ecore/ecore_event_message.eo \ | ||
7 | lib/ecore/ecore_event_message_handler.eo \ | ||
6 | lib/ecore/efl_loop_timer.eo | 8 | lib/ecore/efl_loop_timer.eo |
7 | 9 | ||
8 | ecore_eolian_files_public = \ | 10 | ecore_eolian_files_public = \ |
9 | lib/ecore/efl_loop.eo \ | 11 | lib/ecore/efl_loop.eo \ |
10 | lib/ecore/efl_loop_consumer.eo \ | 12 | lib/ecore/efl_loop_consumer.eo \ |
11 | lib/ecore/efl_loop_fd.eo \ | 13 | lib/ecore/efl_loop_fd.eo \ |
14 | lib/ecore/efl_loop_handler.eo \ | ||
15 | lib/ecore/efl_loop_message.eo \ | ||
16 | lib/ecore/efl_loop_message_handler.eo \ | ||
12 | lib/ecore/efl_io_closer_fd.eo \ | 17 | lib/ecore/efl_io_closer_fd.eo \ |
13 | lib/ecore/efl_io_positioner_fd.eo \ | 18 | lib/ecore/efl_io_positioner_fd.eo \ |
14 | lib/ecore/efl_io_reader_fd.eo \ | 19 | lib/ecore/efl_io_reader_fd.eo \ |
@@ -84,8 +89,14 @@ lib/ecore/ecore_idle_exiter.c \ | |||
84 | lib/ecore/ecore_idler.c \ | 89 | lib/ecore/ecore_idler.c \ |
85 | lib/ecore/ecore_job.c \ | 90 | lib/ecore/ecore_job.c \ |
86 | lib/ecore/ecore_main.c \ | 91 | lib/ecore/ecore_main.c \ |
92 | lib/ecore/ecore_event_message.c \ | ||
93 | lib/ecore/ecore_event_message_handler.c \ | ||
94 | lib/ecore/efl_loop.c \ | ||
87 | lib/ecore/efl_loop_consumer.c \ | 95 | lib/ecore/efl_loop_consumer.c \ |
88 | lib/ecore/efl_loop_fd.c \ | 96 | lib/ecore/efl_loop_fd.c \ |
97 | lib/ecore/efl_loop_handler.c \ | ||
98 | lib/ecore/efl_loop_message.c \ | ||
99 | lib/ecore/efl_loop_message_handler.c \ | ||
89 | lib/ecore/efl_io_closer_fd.c \ | 100 | lib/ecore/efl_io_closer_fd.c \ |
90 | lib/ecore/efl_io_positioner_fd.c \ | 101 | lib/ecore/efl_io_positioner_fd.c \ |
91 | lib/ecore/efl_io_reader_fd.c \ | 102 | lib/ecore/efl_io_reader_fd.c \ |
@@ -115,6 +126,7 @@ lib/ecore/efl_interpolator_divisor.c \ | |||
115 | lib/ecore/efl_interpolator_bounce.c \ | 126 | lib/ecore/efl_interpolator_bounce.c \ |
116 | lib/ecore/efl_interpolator_spring.c \ | 127 | lib/ecore/efl_interpolator_spring.c \ |
117 | lib/ecore/efl_interpolator_cubic_bezier.c \ | 128 | lib/ecore/efl_interpolator_cubic_bezier.c \ |
129 | lib/ecore/ecore_main_timechanges.c \ | ||
118 | lib/ecore/ecore_pipe.c \ | 130 | lib/ecore/ecore_pipe.c \ |
119 | lib/ecore/ecore_poller.c \ | 131 | lib/ecore/ecore_poller.c \ |
120 | lib/ecore/ecore_time.c \ | 132 | lib/ecore/ecore_time.c \ |
@@ -124,7 +136,9 @@ lib/ecore/ecore_throttle.c \ | |||
124 | lib/ecore/ecore_exe.c \ | 136 | lib/ecore/ecore_exe.c \ |
125 | lib/ecore/ecore_exe_private.h \ | 137 | lib/ecore/ecore_exe_private.h \ |
126 | lib/ecore/ecore_private.h \ | 138 | lib/ecore/ecore_private.h \ |
127 | lib/ecore/ecore_internal.h | 139 | lib/ecore/ecore_internal.h \ |
140 | lib/ecore/ecore_main_common.h | ||
141 | |||
128 | 142 | ||
129 | if HAVE_WIN32 | 143 | if HAVE_WIN32 |
130 | lib_ecore_libecore_la_SOURCES += lib/ecore/ecore_exe_win32.c | 144 | lib_ecore_libecore_la_SOURCES += lib/ecore/ecore_exe_win32.c |
diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h index 9203bf1e4d..be1929aa42 100644 --- a/src/lib/ecore/Ecore_Eo.h +++ b/src/lib/ecore/Ecore_Eo.h | |||
@@ -29,12 +29,18 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | 31 | ||
32 | #include "ecore_event_message.eo.h" | ||
33 | #include "ecore_event_message_handler.eo.h" | ||
34 | |||
32 | /** | 35 | /** |
33 | * @ingroup Ecore_MainLoop_Group | 36 | * @ingroup Ecore_MainLoop_Group |
34 | * | 37 | * |
35 | * @{ | 38 | * @{ |
36 | */ | 39 | */ |
37 | 40 | ||
41 | #include "efl_loop_message.eo.h" | ||
42 | #include "efl_loop_message_handler.eo.h" | ||
43 | |||
38 | #include "efl_loop.eo.h" | 44 | #include "efl_loop.eo.h" |
39 | 45 | ||
40 | /** | 46 | /** |
@@ -56,6 +62,7 @@ EAPI int efl_loop_exit_code_process(Eina_Value *value); | |||
56 | EAPI Eina_Future_Scheduler *efl_loop_future_scheduler_get(Eo *obj); | 62 | EAPI Eina_Future_Scheduler *efl_loop_future_scheduler_get(Eo *obj); |
57 | 63 | ||
58 | #include "efl_loop_fd.eo.h" | 64 | #include "efl_loop_fd.eo.h" |
65 | #include "efl_loop_handler.eo.h" | ||
59 | 66 | ||
60 | #include "efl_promise.eo.h" | 67 | #include "efl_promise.eo.h" |
61 | 68 | ||
diff --git a/src/lib/ecore/ecore.c b/src/lib/ecore/ecore.c index 97dc4b2aa3..0c19d4b482 100644 --- a/src/lib/ecore/ecore.c +++ b/src/lib/ecore/ecore.c | |||
@@ -273,14 +273,12 @@ ecore_init(void) | |||
273 | if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1; | 273 | if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1; |
274 | if (_ecore_fps_debug) _ecore_fps_debug_init(); | 274 | if (_ecore_fps_debug) _ecore_fps_debug_init(); |
275 | if (!ecore_mempool_init()) goto shutdown_mempool; | 275 | if (!ecore_mempool_init()) goto shutdown_mempool; |
276 | if (!_ecore_event_init()) goto shutdown_mempool; | ||
277 | _ecore_main_loop_init(); | 276 | _ecore_main_loop_init(); |
277 | if (!_ecore_event_init()) goto shutdown_event; | ||
278 | 278 | ||
279 | vpath = efl_add(EFL_VPATH_CORE_CLASS, NULL); | 279 | vpath = efl_add(EFL_VPATH_CORE_CLASS, NULL); |
280 | if (vpath) efl_vpath_manager_register(EFL_VPATH_MANAGER_CLASS, 0, vpath); | 280 | if (vpath) efl_vpath_manager_register(EFL_VPATH_MANAGER_CLASS, 0, vpath); |
281 | 281 | ||
282 | _mainloop_singleton = efl_add(EFL_LOOP_CLASS, NULL); | ||
283 | |||
284 | _ecore_signal_init(); | 282 | _ecore_signal_init(); |
285 | #ifndef HAVE_EXOTIC | 283 | #ifndef HAVE_EXOTIC |
286 | _ecore_exe_init(); | 284 | _ecore_exe_init(); |
@@ -359,6 +357,9 @@ ecore_init(void) | |||
359 | 357 | ||
360 | return _ecore_init_count; | 358 | return _ecore_init_count; |
361 | 359 | ||
360 | shutdown_event: | ||
361 | _ecore_event_shutdown(); | ||
362 | _ecore_main_shutdown(); | ||
362 | shutdown_mempool: | 363 | shutdown_mempool: |
363 | ecore_mempool_shutdown(); | 364 | ecore_mempool_shutdown(); |
364 | efl_object_shutdown(); | 365 | efl_object_shutdown(); |
@@ -403,9 +404,6 @@ ecore_shutdown(void) | |||
403 | } | 404 | } |
404 | #endif | 405 | #endif |
405 | 406 | ||
406 | efl_del(_mainloop_singleton); | ||
407 | _mainloop_singleton = NULL; | ||
408 | |||
409 | if (_ecore_fps_debug) _ecore_fps_debug_shutdown(); | 407 | if (_ecore_fps_debug) _ecore_fps_debug_shutdown(); |
410 | _ecore_poller_shutdown(); | 408 | _ecore_poller_shutdown(); |
411 | _ecore_animator_shutdown(); | 409 | _ecore_animator_shutdown(); |
@@ -442,7 +440,6 @@ ecore_shutdown(void) | |||
442 | #ifndef HAVE_EXOTIC | 440 | #ifndef HAVE_EXOTIC |
443 | _ecore_exe_shutdown(); | 441 | _ecore_exe_shutdown(); |
444 | #endif | 442 | #endif |
445 | _efl_loop_timer_shutdown(); | ||
446 | _ecore_event_shutdown(); | 443 | _ecore_event_shutdown(); |
447 | _ecore_main_shutdown(); | 444 | _ecore_main_shutdown(); |
448 | _ecore_signal_shutdown(); | 445 | _ecore_signal_shutdown(); |
diff --git a/src/lib/ecore/ecore_alloc.c b/src/lib/ecore/ecore_alloc.c index 3196b82a2d..c98ef92335 100644 --- a/src/lib/ecore/ecore_alloc.c +++ b/src/lib/ecore/ecore_alloc.c | |||
@@ -33,9 +33,9 @@ struct _Ecore_Mempool | |||
33 | } | 33 | } |
34 | 34 | ||
35 | //GENERIC_ALLOC_FREE(Ecore_Animator, ecore_animator); | 35 | //GENERIC_ALLOC_FREE(Ecore_Animator, ecore_animator); |
36 | GENERIC_ALLOC_FREE(Ecore_Event_Handler, ecore_event_handler); | 36 | //GENERIC_ALLOC_FREE(Ecore_Event_Handler, ecore_event_handler); |
37 | GENERIC_ALLOC_FREE(Ecore_Event_Filter, ecore_event_filter); | 37 | //GENERIC_ALLOC_FREE(Ecore_Event_Filter, ecore_event_filter); |
38 | GENERIC_ALLOC_FREE(Ecore_Event, ecore_event); | 38 | //GENERIC_ALLOC_FREE(Ecore_Event, ecore_event); |
39 | //GENERIC_ALLOC_FREE(Ecore_Idle_Exiter, ecore_idle_exiter); | 39 | //GENERIC_ALLOC_FREE(Ecore_Idle_Exiter, ecore_idle_exiter); |
40 | //GENERIC_ALLOC_FREE(Ecore_Idle_Enterer, ecore_idle_enterer); | 40 | //GENERIC_ALLOC_FREE(Ecore_Idle_Enterer, ecore_idle_enterer); |
41 | //GENERIC_ALLOC_FREE(Ecore_Idler, ecore_idler); | 41 | //GENERIC_ALLOC_FREE(Ecore_Idler, ecore_idler); |
@@ -51,9 +51,9 @@ GENERIC_ALLOC_FREE(Ecore_Win32_Handler, ecore_win32_handler); | |||
51 | 51 | ||
52 | static Ecore_Mempool *mempool_array[] = { | 52 | static Ecore_Mempool *mempool_array[] = { |
53 | // &ecore_animator_mp, | 53 | // &ecore_animator_mp, |
54 | &ecore_event_handler_mp, | 54 | // &ecore_event_handler_mp, |
55 | &ecore_event_filter_mp, | 55 | // &ecore_event_filter_mp, |
56 | &ecore_event_mp, | 56 | // &ecore_event_mp, |
57 | // &ecore_idle_exiter_mp, | 57 | // &ecore_idle_exiter_mp, |
58 | // &ecore_idle_enterer_mp, | 58 | // &ecore_idle_enterer_mp, |
59 | // &ecore_idler_mp, | 59 | // &ecore_idler_mp, |
@@ -78,9 +78,9 @@ ecore_mempool_init(void) | |||
78 | Type##_mp.size = _ecore_sizeof_##TYPE | 78 | Type##_mp.size = _ecore_sizeof_##TYPE |
79 | 79 | ||
80 | // MP_SIZE_INIT(Ecore_Animator, ecore_animator); | 80 | // MP_SIZE_INIT(Ecore_Animator, ecore_animator); |
81 | MP_SIZE_INIT(Ecore_Event_Handler, ecore_event_handler); | 81 | // MP_SIZE_INIT(Ecore_Event_Handler, ecore_event_handler); |
82 | MP_SIZE_INIT(Ecore_Event_Filter, ecore_event_filter); | 82 | // MP_SIZE_INIT(Ecore_Event_Filter, ecore_event_filter); |
83 | MP_SIZE_INIT(Ecore_Event, ecore_event); | 83 | // MP_SIZE_INIT(Ecore_Event, ecore_event); |
84 | // MP_SIZE_INIT(Ecore_Idle_Exiter, ecore_idle_exiter); | 84 | // MP_SIZE_INIT(Ecore_Idle_Exiter, ecore_idle_exiter); |
85 | // MP_SIZE_INIT(Ecore_Idle_Enterer, ecore_idle_enterer); | 85 | // MP_SIZE_INIT(Ecore_Idle_Enterer, ecore_idle_enterer); |
86 | // MP_SIZE_INIT(Ecore_Idler, ecore_idler); | 86 | // MP_SIZE_INIT(Ecore_Idler, ecore_idler); |
diff --git a/src/lib/ecore/ecore_event_message.c b/src/lib/ecore/ecore_event_message.c new file mode 100644 index 0000000000..ca072f8524 --- /dev/null +++ b/src/lib/ecore/ecore_event_message.c | |||
@@ -0,0 +1,81 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <Ecore.h> | ||
6 | |||
7 | #include "ecore_private.h" | ||
8 | |||
9 | #define MY_CLASS ECORE_EVENT_MESSAGE_CLASS | ||
10 | |||
11 | ////////////////////////////////////////////////////////////////////////// | ||
12 | |||
13 | typedef struct _Ecore_Event_Message_Data Ecore_Event_Message_Data; | ||
14 | |||
15 | struct _Ecore_Event_Message_Data | ||
16 | { | ||
17 | int type; | ||
18 | void *ev; | ||
19 | Ecore_End_Cb free_func; | ||
20 | void *data; | ||
21 | }; | ||
22 | |||
23 | ////////////////////////////////////////////////////////////////////////// | ||
24 | |||
25 | EOLIAN static void | ||
26 | _ecore_event_message_data_set(Eo *obj EINA_UNUSED, Ecore_Event_Message_Data *pd, int type, void *data, void *free_func, void *free_data) | ||
27 | { | ||
28 | pd->type = type; | ||
29 | pd->ev = data; | ||
30 | pd->free_func = free_func; | ||
31 | pd->data = free_data; | ||
32 | } | ||
33 | |||
34 | EOLIAN static void | ||
35 | _ecore_event_message_data_get(Eo *obj EINA_UNUSED, Ecore_Event_Message_Data *pd, int *type, void **data, void **free_func, void **free_data) | ||
36 | { | ||
37 | if (type) *type = pd->type; | ||
38 | if (data) *data = pd->ev; | ||
39 | if (free_func) *free_func = pd->free_func; | ||
40 | if (free_data) *free_data = pd->data; | ||
41 | } | ||
42 | |||
43 | EOLIAN static void | ||
44 | _ecore_event_message_data_steal(Eo *obj EINA_UNUSED, Ecore_Event_Message_Data *pd, int *type, void **data, void **free_func, void **free_data) | ||
45 | { | ||
46 | if (type) *type = pd->type; | ||
47 | if (data) *data = pd->ev; | ||
48 | if (free_func) *free_func = pd->free_func; | ||
49 | if (free_data) *free_data = pd->data; | ||
50 | pd->type = -1; | ||
51 | pd->ev = NULL; | ||
52 | pd->free_func = NULL; | ||
53 | pd->data = NULL; | ||
54 | } | ||
55 | |||
56 | EOLIAN static Efl_Object * | ||
57 | _ecore_event_message_efl_object_constructor(Eo *obj, Ecore_Event_Message_Data *pd EINA_UNUSED) | ||
58 | { | ||
59 | obj = efl_constructor(efl_super(obj, MY_CLASS)); | ||
60 | pd->type = -1; | ||
61 | return obj; | ||
62 | } | ||
63 | |||
64 | EOLIAN static void | ||
65 | _ecore_event_message_efl_object_destructor(Eo *obj EINA_UNUSED, Ecore_Event_Message_Data *pd EINA_UNUSED) | ||
66 | { | ||
67 | if (pd->ev) | ||
68 | { | ||
69 | Ecore_End_Cb fn_free = pd->free_func; | ||
70 | void *ev = pd->ev; | ||
71 | |||
72 | pd->ev = NULL; | ||
73 | if (fn_free) fn_free(pd->data, ev); | ||
74 | else free(ev); | ||
75 | } | ||
76 | efl_destructor(efl_super(obj, MY_CLASS)); | ||
77 | } | ||
78 | |||
79 | ////////////////////////////////////////////////////////////////////////// | ||
80 | |||
81 | #include "ecore_event_message.eo.c" | ||
diff --git a/src/lib/ecore/ecore_event_message.eo b/src/lib/ecore/ecore_event_message.eo new file mode 100644 index 0000000000..002197a122 --- /dev/null +++ b/src/lib/ecore/ecore_event_message.eo | |||
@@ -0,0 +1,34 @@ | |||
1 | import efl_types; | ||
2 | import eina_types; | ||
3 | |||
4 | class Ecore.Event.Message (Efl.Loop.Message) | ||
5 | { | ||
6 | [[ For Legacy API usage Only. Legacy Ecore Events ]] | ||
7 | methods { | ||
8 | @property data { | ||
9 | [[ Property of the legacy event - set and get it ]] | ||
10 | set { } | ||
11 | get { } | ||
12 | values { | ||
13 | type: int; [[ The event type ]] | ||
14 | data: void_ptr; [[ The event data ]] | ||
15 | free_func: void_ptr; [[ Being lazy for legacy ]] | ||
16 | free_data: void_ptr; [[ Free func data ]] | ||
17 | } | ||
18 | } | ||
19 | data_steal { | ||
20 | [[ Steal the data out and set internal values to -1 | ||
21 | for type and NULL for other vals ]] | ||
22 | params { | ||
23 | @out type: int; [[ The event type ]] | ||
24 | @out data: void_ptr; [[ The event data ]] | ||
25 | @out free_func: void_ptr; [[ Being lazy for legacy ]] | ||
26 | @out free_data: void_ptr; [[ Free func data ]] | ||
27 | } | ||
28 | } | ||
29 | } | ||
30 | implements { | ||
31 | Efl.Object.constructor; | ||
32 | Efl.Object.destructor; | ||
33 | } | ||
34 | } | ||
diff --git a/src/lib/ecore/ecore_event_message_handler.c b/src/lib/ecore/ecore_event_message_handler.c new file mode 100644 index 0000000000..3879c3c78e --- /dev/null +++ b/src/lib/ecore/ecore_event_message_handler.c | |||
@@ -0,0 +1,414 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <Ecore.h> | ||
6 | |||
7 | #include "ecore_private.h" | ||
8 | |||
9 | #define MY_CLASS ECORE_EVENT_MESSAGE_HANDLER_CLASS | ||
10 | |||
11 | ////////////////////////////////////////////////////////////////////////// | ||
12 | |||
13 | typedef struct _Handler Handler; | ||
14 | typedef struct _Filter Filter; | ||
15 | |||
16 | struct _Handler | ||
17 | { | ||
18 | EINA_INLIST; | ||
19 | Ecore_Event_Handler_Cb func; | ||
20 | void *data; | ||
21 | int type; | ||
22 | Eina_Bool delete_me : 1; | ||
23 | Eina_Bool to_add : 1; | ||
24 | }; | ||
25 | |||
26 | struct _Filter | ||
27 | { | ||
28 | EINA_INLIST; | ||
29 | Ecore_Data_Cb func_start; | ||
30 | Ecore_Filter_Cb func_filter; | ||
31 | Ecore_End_Cb func_end; | ||
32 | void *data; | ||
33 | void *loop_data; | ||
34 | Eina_Bool delete_me : 1; | ||
35 | }; | ||
36 | |||
37 | typedef struct _Ecore_Event_Message_Handler_Data Ecore_Event_Message_Handler_Data; | ||
38 | |||
39 | struct _Ecore_Event_Message_Handler_Data | ||
40 | { | ||
41 | int event_type_count; | ||
42 | Eina_Inlist **handlers; // array of event_type_count inlists of handlers | ||
43 | Eina_Inlist *filters; | ||
44 | Eina_List *handlers_delete; | ||
45 | Eina_List *handlers_add; | ||
46 | Eina_List *filters_delete; | ||
47 | Eina_List *filters_add; | ||
48 | void *current_event_data; | ||
49 | int current_event_type; | ||
50 | int handlers_walking; | ||
51 | int filters_walking; | ||
52 | }; | ||
53 | |||
54 | ////////////////////////////////////////////////////////////////////////// | ||
55 | |||
56 | Eina_Bool | ||
57 | _ecore_event_do_filter(void *handler_pd, Eo *msg_handler, Eo *msg) | ||
58 | { | ||
59 | Filter *f; | ||
60 | void *ev; | ||
61 | int type; | ||
62 | Ecore_Event_Message_Handler_Data *eemhd = handler_pd; | ||
63 | |||
64 | if (!eemhd->filters) return EINA_TRUE; | ||
65 | if (!efl_isa(msg_handler, MY_CLASS)) return EINA_TRUE; | ||
66 | eemhd->filters_walking++; | ||
67 | EINA_INLIST_FOREACH(eemhd->filters, f) | ||
68 | { | ||
69 | if (f->delete_me) continue; | ||
70 | type = -1; | ||
71 | ev = NULL; | ||
72 | ecore_event_message_data_get(msg, &type, &ev, NULL, NULL); | ||
73 | if (type >= 0) | ||
74 | { | ||
75 | if (!f->func_filter(f->data, f->loop_data, type, ev)) | ||
76 | _efl_loop_message_unsend(msg); | ||
77 | } | ||
78 | } | ||
79 | eemhd->filters_walking--; | ||
80 | return EINA_TRUE; | ||
81 | } | ||
82 | |||
83 | void | ||
84 | _ecore_event_filters_call(Eo *obj, Efl_Loop_Data *pd) | ||
85 | { | ||
86 | Filter *f; | ||
87 | Ecore_Event_Message_Handler_Data *eemhd; | ||
88 | Eo *ecore_event_handler = efl_loop_message_handler_get | ||
89 | (EFL_LOOP_CLASS, obj, ECORE_EVENT_MESSAGE_HANDLER_CLASS); | ||
90 | |||
91 | if (!ecore_event_handler) return; | ||
92 | eemhd = efl_data_scope_get(ecore_event_handler, MY_CLASS); | ||
93 | if (!eemhd) return; | ||
94 | if (!eemhd->filters) return; | ||
95 | eemhd->filters_walking++; | ||
96 | EINA_INLIST_FOREACH(eemhd->filters, f) | ||
97 | { | ||
98 | if (f->delete_me) continue; | ||
99 | if (f->func_start) f->loop_data = f->func_start(f->data); | ||
100 | } | ||
101 | _efl_loop_messages_filter(obj, pd, eemhd); | ||
102 | EINA_INLIST_FOREACH(eemhd->filters, f) | ||
103 | { | ||
104 | if (f->delete_me) continue; | ||
105 | if (f->func_end) f->func_end(f->data, f->loop_data); | ||
106 | } | ||
107 | eemhd->filters_walking--; | ||
108 | if (eemhd->filters_walking == 0) | ||
109 | { | ||
110 | EINA_LIST_FREE(eemhd->filters_delete, f) | ||
111 | { | ||
112 | free(f); | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | |||
117 | ////////////////////////////////////////////////////////////////////////// | ||
118 | |||
119 | EOLIAN static Ecore_Event_Message * | ||
120 | _ecore_event_message_handler_message_type_add(Eo *obj, Ecore_Event_Message_Handler_Data *pd EINA_UNUSED) | ||
121 | { | ||
122 | // XXX: implemented event obj cache | ||
123 | return efl_add(ECORE_EVENT_MESSAGE_CLASS, obj); | ||
124 | } | ||
125 | |||
126 | EOLIAN static int | ||
127 | _ecore_event_message_handler_type_new(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd) | ||
128 | { | ||
129 | Eina_Inlist **tmp; | ||
130 | int evnum; | ||
131 | |||
132 | evnum = pd->event_type_count + 1; | ||
133 | tmp = realloc(pd->handlers, sizeof(Eina_Inlist *) * (evnum + 1)); | ||
134 | if (!tmp) return 0; | ||
135 | pd->handlers = tmp; | ||
136 | pd->handlers[evnum] = NULL; | ||
137 | pd->event_type_count = evnum; | ||
138 | return evnum; | ||
139 | } | ||
140 | |||
141 | EOLIAN static void * | ||
142 | _ecore_event_message_handler_handler_add(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd, int type, void *func, void *data) | ||
143 | { | ||
144 | Handler *h; | ||
145 | |||
146 | if ((type < 0) || (type > pd->event_type_count) || (!func)) return NULL; | ||
147 | h = calloc(1, sizeof(Handler)); | ||
148 | if (!h) return NULL; | ||
149 | h->func = func; | ||
150 | h->data = data; | ||
151 | h->type = type; | ||
152 | if (pd->current_event_type == type) | ||
153 | { | ||
154 | h->to_add = EINA_TRUE; | ||
155 | pd->handlers_add = eina_list_append(pd->handlers_add, h); | ||
156 | } | ||
157 | else | ||
158 | pd->handlers[type] = eina_inlist_append(pd->handlers[type], | ||
159 | EINA_INLIST_GET(h)); | ||
160 | return h; | ||
161 | } | ||
162 | |||
163 | EOLIAN static void * | ||
164 | _ecore_event_message_handler_handler_del(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd, void *handler) | ||
165 | { | ||
166 | Handler *h = handler; | ||
167 | void *data; | ||
168 | |||
169 | if (!h) return NULL; | ||
170 | if ((h->type < 0) || (h->type > pd->event_type_count)) return NULL; | ||
171 | data = h->data; | ||
172 | if (pd->handlers_walking > 0) | ||
173 | { | ||
174 | h->delete_me = EINA_TRUE; | ||
175 | pd->handlers_delete = eina_list_append(pd->handlers_delete, h); | ||
176 | } | ||
177 | else | ||
178 | { | ||
179 | if (h->to_add) | ||
180 | pd->handlers_add = eina_list_remove(pd->handlers_add, h); | ||
181 | else | ||
182 | pd->handlers[h->type] = eina_inlist_remove(pd->handlers[h->type], | ||
183 | EINA_INLIST_GET(h)); | ||
184 | free(h); | ||
185 | } | ||
186 | return data; | ||
187 | } | ||
188 | |||
189 | EOLIAN static void * | ||
190 | _ecore_event_message_handler_handler_data_get(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd EINA_UNUSED, void *handler) | ||
191 | { | ||
192 | Handler *h = handler; | ||
193 | |||
194 | if (!h) return NULL; | ||
195 | return h->data; | ||
196 | } | ||
197 | |||
198 | EOLIAN static void * | ||
199 | _ecore_event_message_handler_handler_data_set(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd EINA_UNUSED, void *handler, void *data) | ||
200 | { | ||
201 | Handler *h = handler; | ||
202 | void *prev_data; | ||
203 | |||
204 | if (!h) return NULL; | ||
205 | prev_data = h->data; | ||
206 | h->data = data; | ||
207 | return prev_data; | ||
208 | } | ||
209 | |||
210 | EOLIAN static void * | ||
211 | _ecore_event_message_handler_filter_add(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd, void *func_start, void *func_filter, void *func_end, void *data) | ||
212 | { | ||
213 | Filter *f; | ||
214 | |||
215 | if (!func_filter) return NULL; | ||
216 | f = calloc(1, sizeof(Filter)); | ||
217 | if (!f) return NULL; | ||
218 | f->func_start = func_start; | ||
219 | f->func_filter = func_filter; | ||
220 | f->func_end = func_end; | ||
221 | f->data = data; | ||
222 | pd->filters = eina_inlist_append(pd->filters, EINA_INLIST_GET(f)); | ||
223 | return f; | ||
224 | } | ||
225 | |||
226 | EOLIAN static void * | ||
227 | _ecore_event_message_handler_filter_del(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd, void *filter) | ||
228 | { | ||
229 | Filter *f = filter; | ||
230 | void *data; | ||
231 | |||
232 | if (!f) return NULL; | ||
233 | data = f->data; | ||
234 | if (pd->filters_walking > 0) | ||
235 | { | ||
236 | f->delete_me = EINA_TRUE; | ||
237 | pd->filters_delete = eina_list_append(pd->filters_delete, f); | ||
238 | } | ||
239 | else | ||
240 | { | ||
241 | pd->filters = eina_inlist_remove(pd->filters, EINA_INLIST_GET(f)); | ||
242 | free(f); | ||
243 | } | ||
244 | return data; | ||
245 | } | ||
246 | |||
247 | EOLIAN static int | ||
248 | _ecore_event_message_handler_current_type_get(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd) | ||
249 | { | ||
250 | return pd->current_event_type; | ||
251 | } | ||
252 | |||
253 | EOLIAN static void * | ||
254 | _ecore_event_message_handler_current_event_get(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd) | ||
255 | { | ||
256 | return pd->current_event_data; | ||
257 | } | ||
258 | |||
259 | EOLIAN static Efl_Object * | ||
260 | _ecore_event_message_handler_efl_object_constructor(Eo *obj, Ecore_Event_Message_Handler_Data *pd) | ||
261 | { | ||
262 | obj = efl_constructor(efl_super(obj, MY_CLASS)); | ||
263 | pd->event_type_count = -1; | ||
264 | pd->current_event_type = -1; | ||
265 | return obj; | ||
266 | } | ||
267 | |||
268 | EOLIAN static void | ||
269 | _ecore_event_message_handler_efl_object_destructor(Eo *obj, Ecore_Event_Message_Handler_Data *pd) | ||
270 | { | ||
271 | Handler *h; | ||
272 | int i; | ||
273 | |||
274 | if (pd->handlers_walking == 0) | ||
275 | { | ||
276 | EINA_LIST_FREE(pd->handlers_delete, h) | ||
277 | { | ||
278 | pd->handlers[h->type] = | ||
279 | eina_inlist_remove(pd->handlers[h->type], | ||
280 | EINA_INLIST_GET(h)); | ||
281 | free(h); | ||
282 | } | ||
283 | EINA_LIST_FREE(pd->handlers_add, h) | ||
284 | { | ||
285 | free(h); | ||
286 | } | ||
287 | for (i = 0; i < pd->event_type_count; i++) | ||
288 | { | ||
289 | EINA_INLIST_FREE(pd->handlers[i], h) free(h); | ||
290 | } | ||
291 | free(pd->handlers); | ||
292 | pd->handlers = NULL; | ||
293 | } | ||
294 | else | ||
295 | { | ||
296 | ERR("Destruction of ecore_event_message_handler while walking events"); | ||
297 | } | ||
298 | efl_destructor(efl_super(obj, MY_CLASS)); | ||
299 | } | ||
300 | |||
301 | EOLIAN static void | ||
302 | _ecore_event_message_handler_efl_loop_message_handler_message_call(Eo *obj, Ecore_Event_Message_Handler_Data *pd, Efl_Loop_Message *message) | ||
303 | { | ||
304 | Handler *h; | ||
305 | int type = -1; | ||
306 | void *data = NULL, *free_func = NULL, *free_data = NULL; | ||
307 | Ecore_End_Cb fn_free = NULL; | ||
308 | Eina_List *l, *l2; | ||
309 | int handled = 0; | ||
310 | |||
311 | // call legacy handlers which are controled by this class' custom api | ||
312 | ecore_event_message_data_steal | ||
313 | (message, &type, &data, &free_func, &free_data); | ||
314 | if ((type >= 0) && (type <= pd->event_type_count)) | ||
315 | { | ||
316 | if (free_func) fn_free = free_func; | ||
317 | pd->current_event_data = data; | ||
318 | pd->current_event_type = type; | ||
319 | pd->handlers_walking++; | ||
320 | EINA_INLIST_FOREACH(pd->handlers[type], h) | ||
321 | { | ||
322 | if (h->delete_me) continue; | ||
323 | handled++; | ||
324 | if (!h->func(h->data, h->type, data)) break; | ||
325 | } | ||
326 | pd->handlers_walking--; | ||
327 | pd->current_event_data = NULL; | ||
328 | pd->current_event_type = -1; | ||
329 | EINA_LIST_FOREACH_SAFE(pd->handlers_add, l, l2, h) | ||
330 | { | ||
331 | if (h->type == type) | ||
332 | { | ||
333 | h->to_add = EINA_FALSE; | ||
334 | pd->handlers_add = | ||
335 | eina_list_remove_list(pd->handlers_add, l); | ||
336 | pd->handlers[type] = | ||
337 | eina_inlist_append(pd->handlers[type], EINA_INLIST_GET(h)); | ||
338 | } | ||
339 | } | ||
340 | if (pd->handlers_walking == 0) | ||
341 | { | ||
342 | EINA_LIST_FREE(pd->handlers_delete, h) | ||
343 | { | ||
344 | if (h->to_add) | ||
345 | pd->handlers_add = eina_list_remove(pd->handlers_add, h); | ||
346 | else | ||
347 | pd->handlers[h->type] = | ||
348 | eina_inlist_remove(pd->handlers[h->type], | ||
349 | EINA_INLIST_GET(h)); | ||
350 | free(h); | ||
351 | } | ||
352 | } | ||
353 | if ((type == ECORE_EVENT_SIGNAL_EXIT) && (handled == 0)) | ||
354 | { | ||
355 | Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS); | ||
356 | |||
357 | if (loop) | ||
358 | { | ||
359 | Eina_Value v = EINA_VALUE_EMPTY; | ||
360 | int val = 0; | ||
361 | |||
362 | eina_value_setup(&v, EINA_VALUE_TYPE_INT); | ||
363 | eina_value_set(&v, &val); | ||
364 | efl_loop_quit(loop, v); | ||
365 | } | ||
366 | } | ||
367 | } | ||
368 | |||
369 | efl_event_callback_call | ||
370 | (obj, ECORE_EVENT_MESSAGE_HANDLER_EVENT_MESSAGE_ECORE_EVENT, message); | ||
371 | efl_loop_message_handler_message_call | ||
372 | (efl_super(obj, MY_CLASS), message); | ||
373 | |||
374 | if (data) | ||
375 | { | ||
376 | if (fn_free) fn_free(free_data, data); | ||
377 | else free(data); | ||
378 | } | ||
379 | } | ||
380 | |||
381 | static Eina_Bool | ||
382 | _flush_cb(void *data, void *handler EINA_UNUSED, void *message) | ||
383 | { | ||
384 | int *type = data; | ||
385 | int evtype = -1; | ||
386 | void *evdata = NULL, *free_func = NULL, *free_data = NULL; | ||
387 | Ecore_End_Cb fn_free = NULL; | ||
388 | |||
389 | if (!efl_isa(message, ECORE_EVENT_MESSAGE_CLASS)) return EINA_TRUE; | ||
390 | ecore_event_message_data_steal(message, &evtype, &evdata, &free_func, &free_data); | ||
391 | if (*type != evtype) return EINA_TRUE; | ||
392 | if (free_func) | ||
393 | { | ||
394 | fn_free = free_func; | ||
395 | fn_free(free_data, evdata); | ||
396 | } | ||
397 | return EINA_FALSE; | ||
398 | } | ||
399 | |||
400 | EOLIAN static void | ||
401 | _ecore_event_message_handler_type_flush(Eo *obj, Ecore_Event_Message_Handler_Data *pd EINA_UNUSED, int type) | ||
402 | { | ||
403 | Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS); | ||
404 | Efl_Loop_Data *loop_data = efl_data_scope_get(loop, EFL_LOOP_CLASS); | ||
405 | |||
406 | if (loop && loop_data) | ||
407 | { | ||
408 | _efl_loop_messages_call(loop, loop_data, _flush_cb, &type); | ||
409 | } | ||
410 | } | ||
411 | |||
412 | ////////////////////////////////////////////////////////////////////////// | ||
413 | |||
414 | #include "ecore_event_message_handler.eo.c" | ||
diff --git a/src/lib/ecore/ecore_event_message_handler.eo b/src/lib/ecore/ecore_event_message_handler.eo new file mode 100644 index 0000000000..78047164ca --- /dev/null +++ b/src/lib/ecore/ecore_event_message_handler.eo | |||
@@ -0,0 +1,86 @@ | |||
1 | import efl_types; | ||
2 | import eina_types; | ||
3 | |||
4 | class Ecore.Event.Message.Handler (Efl.Loop.Message.Handler) | ||
5 | { | ||
6 | [[ For Legacy API usage Only | ||
7 | This class is rather hacky/messy as it's really internal glue | ||
8 | to handle legacy ecore events alongside the new loop message | ||
9 | stuff merged together. This is ugly as it's internal only | ||
10 | to quickly glue things together and is destined for death in | ||
11 | EFL 2.0 or when we dump legacy. | ||
12 | ]] | ||
13 | methods { | ||
14 | message_type_add { | ||
15 | [[ ]] | ||
16 | return: Ecore.Event.Message; [[ ]] | ||
17 | } | ||
18 | type_new { | ||
19 | [[ ]] | ||
20 | return: int; [[ ]] | ||
21 | } | ||
22 | handler_add { | ||
23 | [[ Legacy list of callback handlers so they can return false ]] | ||
24 | params { | ||
25 | type: int; | ||
26 | func: void_ptr; | ||
27 | data: void_ptr; | ||
28 | } | ||
29 | return: void_ptr; [[ Lazy return handle ]] | ||
30 | } | ||
31 | handler_del { | ||
32 | params { | ||
33 | handler: void_ptr; [[ handler returned from handler_add() ]] | ||
34 | } | ||
35 | return: void_ptr; [[ handler data ptr ]] | ||
36 | } | ||
37 | handler_data_get { | ||
38 | params { | ||
39 | handler: void_ptr; [[ handler returned from handler_add() ]] | ||
40 | } | ||
41 | return: void_ptr; [[ handler data ptr ]] | ||
42 | } | ||
43 | handler_data_set { | ||
44 | params { | ||
45 | handler: void_ptr; [[ handler returned from handler_add() ]] | ||
46 | data: void_ptr; | ||
47 | } | ||
48 | return: void_ptr; [[ prev handler data ptr ]] | ||
49 | } | ||
50 | filter_add { | ||
51 | [[ Legacy event filter ]] | ||
52 | params { | ||
53 | func_start: void_ptr; | ||
54 | func_filter: void_ptr; | ||
55 | func_end: void_ptr; | ||
56 | data: void_ptr; | ||
57 | } | ||
58 | return: void_ptr; [[ Lazy return filter handle ]] | ||
59 | } | ||
60 | filter_del { | ||
61 | params { | ||
62 | filter: void_ptr; [[ filter returned from filter_add() ]] | ||
63 | } | ||
64 | return: void_ptr; [[ filter data ptr ]] | ||
65 | } | ||
66 | current_type_get { | ||
67 | return: int; [[ ]] | ||
68 | } | ||
69 | current_event_get { | ||
70 | return: void_ptr; [[ ]] | ||
71 | } | ||
72 | type_flush { | ||
73 | params { | ||
74 | type: int; [[ the event type to flush ]] | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | events { | ||
79 | message,ecore,event: Ecore.Event.Message; [[ Sample - override this ]] | ||
80 | } | ||
81 | implements { | ||
82 | Efl.Object.constructor; | ||
83 | Efl.Object.destructor; | ||
84 | Efl.Loop.Message.Handler.message_call; [[ Sample - override this ]] | ||
85 | } | ||
86 | } | ||
diff --git a/src/lib/ecore/ecore_events.c b/src/lib/ecore/ecore_events.c index ed405edb39..2a123a58fe 100644 --- a/src/lib/ecore/ecore_events.c +++ b/src/lib/ecore/ecore_events.c | |||
@@ -7,47 +7,6 @@ | |||
7 | #include "Ecore.h" | 7 | #include "Ecore.h" |
8 | #include "ecore_private.h" | 8 | #include "ecore_private.h" |
9 | 9 | ||
10 | static int inpurge = 0; | ||
11 | |||
12 | struct _Ecore_Event_Handler | ||
13 | { | ||
14 | EINA_INLIST; | ||
15 | ECORE_MAGIC; | ||
16 | int type; | ||
17 | Ecore_Event_Handler_Cb func; | ||
18 | void *data; | ||
19 | int references; | ||
20 | Eina_Bool delete_me : 1; | ||
21 | }; | ||
22 | GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event_Handler); | ||
23 | |||
24 | struct _Ecore_Event_Filter | ||
25 | { | ||
26 | EINA_INLIST; | ||
27 | ECORE_MAGIC; | ||
28 | Ecore_Data_Cb func_start; | ||
29 | Ecore_Filter_Cb func_filter; | ||
30 | Ecore_End_Cb func_end; | ||
31 | void *loop_data; | ||
32 | void *data; | ||
33 | int references; | ||
34 | Eina_Bool delete_me : 1; | ||
35 | }; | ||
36 | GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event_Filter); | ||
37 | |||
38 | struct _Ecore_Event | ||
39 | { | ||
40 | EINA_INLIST; | ||
41 | ECORE_MAGIC; | ||
42 | int type; | ||
43 | void *event; | ||
44 | Ecore_End_Cb func_free; | ||
45 | void *data; | ||
46 | int references; | ||
47 | Eina_Bool delete_me : 1; | ||
48 | }; | ||
49 | GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event); | ||
50 | |||
51 | typedef struct _Ecore_Future_Schedule_Entry | 10 | typedef struct _Ecore_Future_Schedule_Entry |
52 | { | 11 | { |
53 | Eina_Future_Schedule_Entry base; | 12 | Eina_Future_Schedule_Entry base; |
@@ -57,131 +16,45 @@ typedef struct _Ecore_Future_Schedule_Entry | |||
57 | Eina_Value value; | 16 | Eina_Value value; |
58 | } Ecore_Future_Schedule_Entry; | 17 | } Ecore_Future_Schedule_Entry; |
59 | 18 | ||
60 | static int events_num = 0; | 19 | ////// |
61 | static Ecore_Event *events = NULL; | 20 | // XXX: still using legacy ecore events |
62 | static Ecore_Event *event_current = NULL; | 21 | static Ecore_Event_Handler *future_handler = NULL; |
63 | static Ecore_Event *purge_events = NULL; | 22 | static Eina_Bool shutting_down = EINA_FALSE; |
64 | 23 | static Eina_Mempool *mp_future_schedule_entry = NULL; | |
65 | static Ecore_Event_Handler **event_handlers = NULL; | 24 | static int ECORE_EV_FUTURE_ID = -1; |
66 | static Ecore_Event_Handler *event_handler_current = NULL; | 25 | // |
67 | static int event_handlers_num = 0; | 26 | ////// |
68 | static int event_handlers_alloc_num = 0; | 27 | |
69 | static Eina_List *event_handlers_delete_list = NULL; | 28 | static Ecore_Event_Message_Handler *_event_msg_handler = NULL; |
70 | |||
71 | static Ecore_Event_Handler *event_handlers_add_list = NULL; | ||
72 | |||
73 | static Ecore_Event_Filter *event_filters = NULL; | ||
74 | static Ecore_Event_Filter *event_filter_current = NULL; | ||
75 | static Ecore_Event *event_filter_event_current = NULL; | ||
76 | static int event_filters_delete_me = 0; | ||
77 | static int event_id_max = ECORE_EVENT_COUNT; | ||
78 | static int ecore_raw_event_type = ECORE_EVENT_NONE; | ||
79 | static void *ecore_raw_event_event = NULL; | ||
80 | static Ecore_Event_Handler *future_handler = NULL; | ||
81 | static int ECORE_EV_FUTURE_ID = -1; | ||
82 | static Eina_Mempool *mp_future_schedule_entry = NULL; | ||
83 | static Eina_Bool shutting_down = EINA_FALSE; | ||
84 | |||
85 | static void _ecore_event_purge_deleted(void); | ||
86 | static void *_ecore_event_del(Ecore_Event *event); | ||
87 | 29 | ||
88 | EAPI Ecore_Event_Handler * | 30 | EAPI Ecore_Event_Handler * |
89 | ecore_event_handler_add(int type, | 31 | ecore_event_handler_add(int type, |
90 | Ecore_Event_Handler_Cb func, | 32 | Ecore_Event_Handler_Cb func, |
91 | const void *data) | 33 | const void *data) |
92 | { | 34 | { |
93 | Ecore_Event_Handler *eh = NULL; | 35 | return ecore_event_message_handler_add(_event_msg_handler, |
94 | 36 | type, func, (void *)data); | |
95 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | ||
96 | |||
97 | if (!func) return NULL; | ||
98 | if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) return NULL; | ||
99 | eh = ecore_event_handler_calloc(1); | ||
100 | if (!eh) return NULL; | ||
101 | ECORE_MAGIC_SET(eh, ECORE_MAGIC_EVENT_HANDLER); | ||
102 | eh->type = type; | ||
103 | eh->func = func; | ||
104 | eh->data = (void *)data; | ||
105 | if (type >= (event_handlers_num - 1)) | ||
106 | { | ||
107 | int p_alloc_num; | ||
108 | |||
109 | p_alloc_num = event_handlers_alloc_num; | ||
110 | event_handlers_num = type + 1; | ||
111 | if (event_handlers_num > event_handlers_alloc_num) | ||
112 | { | ||
113 | Ecore_Event_Handler **new_handlers; | ||
114 | int i; | ||
115 | |||
116 | event_handlers_alloc_num = ((event_handlers_num + 16) / 16) * 16; | ||
117 | new_handlers = realloc(event_handlers, event_handlers_alloc_num * sizeof(Ecore_Event_Handler *)); | ||
118 | if (!new_handlers) | ||
119 | { | ||
120 | ecore_event_handler_mp_free(eh); | ||
121 | return NULL; | ||
122 | } | ||
123 | event_handlers = new_handlers; | ||
124 | for (i = p_alloc_num; i < event_handlers_alloc_num; i++) | ||
125 | event_handlers[i] = NULL; | ||
126 | } | ||
127 | } | ||
128 | if (ecore_raw_event_type == type) | ||
129 | event_handlers_add_list = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers_add_list), EINA_INLIST_GET(eh)); | ||
130 | else if (type < event_handlers_alloc_num) | ||
131 | event_handlers[type] = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers[type]), EINA_INLIST_GET(eh)); | ||
132 | |||
133 | return eh; | ||
134 | } | 37 | } |
135 | 38 | ||
136 | EAPI void * | 39 | EAPI void * |
137 | ecore_event_handler_del(Ecore_Event_Handler *event_handler) | 40 | ecore_event_handler_del(Ecore_Event_Handler *event_handler) |
138 | { | 41 | { |
139 | if (!event_handler) return NULL; | 42 | return ecore_event_message_handler_del(_event_msg_handler, |
140 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 43 | event_handler); |
141 | if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER)) | ||
142 | { | ||
143 | ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER, | ||
144 | "ecore_event_handler_del"); | ||
145 | return NULL; | ||
146 | } | ||
147 | return _ecore_event_handler_del(event_handler); | ||
148 | } | 44 | } |
149 | 45 | ||
150 | EAPI void * | 46 | EAPI void * |
151 | ecore_event_handler_data_get(Ecore_Event_Handler *eh) | 47 | ecore_event_handler_data_get(Ecore_Event_Handler *eh) |
152 | { | 48 | { |
153 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 49 | return ecore_event_message_handler_data_get(_event_msg_handler, eh); |
154 | if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER)) | ||
155 | { | ||
156 | ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_get"); | ||
157 | return NULL; | ||
158 | } | ||
159 | return eh->data; | ||
160 | } | 50 | } |
161 | 51 | ||
162 | EAPI void * | 52 | EAPI void * |
163 | ecore_event_handler_data_set(Ecore_Event_Handler *eh, | 53 | ecore_event_handler_data_set(Ecore_Event_Handler *eh, |
164 | const void *data) | 54 | const void *data) |
165 | { | 55 | { |
166 | void *old = NULL; | 56 | return ecore_event_message_handler_data_set(_event_msg_handler, eh, |
167 | 57 | (void *)data); | |
168 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | ||
169 | if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER)) | ||
170 | { | ||
171 | ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_set"); | ||
172 | return NULL; | ||
173 | } | ||
174 | old = eh->data; | ||
175 | eh->data = (void *)data; | ||
176 | |||
177 | return old; | ||
178 | } | ||
179 | |||
180 | static void | ||
181 | _ecore_event_generic_free(void *data EINA_UNUSED, | ||
182 | void *event) | ||
183 | { /* DO NOT MEMPOOL FREE THIS */ | ||
184 | free(event); | ||
185 | } | 58 | } |
186 | 59 | ||
187 | EAPI Ecore_Event * | 60 | EAPI Ecore_Event * |
@@ -190,34 +63,27 @@ ecore_event_add(int type, | |||
190 | Ecore_End_Cb func_free, | 63 | Ecore_End_Cb func_free, |
191 | void *data) | 64 | void *data) |
192 | { | 65 | { |
193 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 66 | Ecore_Event_Message *msg; |
194 | 67 | ||
195 | if (type <= ECORE_EVENT_NONE) return NULL; | 68 | msg = ecore_event_message_handler_message_type_add(_event_msg_handler); |
196 | if (type >= event_id_max) return NULL; | 69 | ecore_event_message_data_set(msg, type, ev, func_free, data); |
197 | if ((ev) && (!func_free)) func_free = _ecore_event_generic_free; | 70 | efl_loop_message_handler_message_send(_event_msg_handler, msg); |
198 | return _ecore_event_add(type, ev, func_free, data); | 71 | return (Ecore_Event *)msg; |
199 | } | 72 | } |
200 | 73 | ||
201 | EAPI void * | 74 | EAPI void * |
202 | ecore_event_del(Ecore_Event *event) | 75 | ecore_event_del(Ecore_Event *event) |
203 | { | 76 | { |
204 | if (!event) return NULL; | 77 | void *data = NULL; |
205 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 78 | ecore_event_message_data_get((Eo *)event, NULL, &data, NULL, NULL); |
206 | if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT)) | 79 | _efl_loop_message_unsend((Eo *)event); |
207 | { | 80 | return data; |
208 | ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT, "ecore_event_del"); | ||
209 | return NULL; | ||
210 | } | ||
211 | EINA_SAFETY_ON_TRUE_RETURN_VAL(event->delete_me, NULL); | ||
212 | event->delete_me = 1; | ||
213 | return event->data; | ||
214 | } | 81 | } |
215 | 82 | ||
216 | EAPI int | 83 | EAPI int |
217 | ecore_event_type_new(void) | 84 | ecore_event_type_new(void) |
218 | { | 85 | { |
219 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); | 86 | return ecore_event_message_handler_type_new(_event_msg_handler); |
220 | return event_id_max++; | ||
221 | } | 87 | } |
222 | 88 | ||
223 | EAPI Ecore_Event_Filter * | 89 | EAPI Ecore_Event_Filter * |
@@ -226,59 +92,27 @@ ecore_event_filter_add(Ecore_Data_Cb func_start, | |||
226 | Ecore_End_Cb func_end, | 92 | Ecore_End_Cb func_end, |
227 | const void *data) | 93 | const void *data) |
228 | { | 94 | { |
229 | Ecore_Event_Filter *ef = NULL; | 95 | return ecore_event_message_handler_filter_add(_event_msg_handler, |
230 | 96 | func_start, func_filter, | |
231 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 97 | func_end, (void *)data); |
232 | if (!func_filter) return NULL; | ||
233 | ef = ecore_event_filter_calloc(1); | ||
234 | if (!ef) return NULL; | ||
235 | ECORE_MAGIC_SET(ef, ECORE_MAGIC_EVENT_FILTER); | ||
236 | ef->func_start = func_start; | ||
237 | ef->func_filter = func_filter; | ||
238 | ef->func_end = func_end; | ||
239 | ef->data = (void *)data; | ||
240 | event_filters = (Ecore_Event_Filter *)eina_inlist_append(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef)); | ||
241 | |||
242 | return ef; | ||
243 | } | 98 | } |
244 | 99 | ||
245 | EAPI void * | 100 | EAPI void * |
246 | ecore_event_filter_del(Ecore_Event_Filter *ef) | 101 | ecore_event_filter_del(Ecore_Event_Filter *ef) |
247 | { | 102 | { |
248 | if (!ef) return NULL; | 103 | return ecore_event_message_handler_filter_del(_event_msg_handler, ef); |
249 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | ||
250 | if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER)) | ||
251 | { | ||
252 | ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, "ecore_event_filter_del"); | ||
253 | return NULL; | ||
254 | } | ||
255 | EINA_SAFETY_ON_TRUE_RETURN_VAL(ef->delete_me, NULL); | ||
256 | ef->delete_me = 1; | ||
257 | event_filters_delete_me = 1; | ||
258 | return ef->data; | ||
259 | } | 104 | } |
260 | 105 | ||
261 | EAPI int | 106 | EAPI int |
262 | ecore_event_current_type_get(void) | 107 | ecore_event_current_type_get(void) |
263 | { | 108 | { |
264 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); | 109 | return ecore_event_message_handler_current_type_get(_event_msg_handler); |
265 | return ecore_raw_event_type; | ||
266 | } | 110 | } |
267 | 111 | ||
268 | EAPI void * | 112 | EAPI void * |
269 | ecore_event_current_event_get(void) | 113 | ecore_event_current_event_get(void) |
270 | { | 114 | { |
271 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 115 | return ecore_event_message_handler_current_event_get(_event_msg_handler); |
272 | return ecore_raw_event_event; | ||
273 | } | ||
274 | |||
275 | EAPI void * | ||
276 | _ecore_event_handler_del(Ecore_Event_Handler *event_handler) | ||
277 | { | ||
278 | EINA_SAFETY_ON_TRUE_RETURN_VAL(event_handler->delete_me, NULL); | ||
279 | event_handler->delete_me = 1; | ||
280 | event_handlers_delete_list = eina_list_append(event_handlers_delete_list, event_handler); | ||
281 | return event_handler->data; | ||
282 | } | 116 | } |
283 | 117 | ||
284 | static Eina_Bool | 118 | static Eina_Bool |
@@ -294,12 +128,6 @@ static void | |||
294 | ecore_future_free(void *user_data, void *func_data EINA_UNUSED) | 128 | ecore_future_free(void *user_data, void *func_data EINA_UNUSED) |
295 | { | 129 | { |
296 | Ecore_Future_Schedule_Entry *entry = user_data; | 130 | Ecore_Future_Schedule_Entry *entry = user_data; |
297 | /* | ||
298 | In case entry->event is not NULL, it means | ||
299 | that ecore is shutting down. In this case, | ||
300 | we must cancel the future otherwise Eina may | ||
301 | try to use it and lead to crashes. | ||
302 | */ | ||
303 | if (entry->event) | 131 | if (entry->event) |
304 | { | 132 | { |
305 | eina_future_cancel(entry->future); | 133 | eina_future_cancel(entry->future); |
@@ -355,6 +183,44 @@ _ecore_event_init(void) | |||
355 | const char *choice = getenv("EINA_MEMPOOL"); | 183 | const char *choice = getenv("EINA_MEMPOOL"); |
356 | if ((!choice) || (!choice[0])) choice = "chained_mempool"; | 184 | if ((!choice) || (!choice[0])) choice = "chained_mempool"; |
357 | 185 | ||
186 | _event_msg_handler = | ||
187 | efl_loop_message_handler_get(EFL_LOOP_CLASS, | ||
188 | _mainloop_singleton, | ||
189 | ECORE_EVENT_MESSAGE_HANDLER_CLASS); | ||
190 | if (!_event_msg_handler) | ||
191 | { | ||
192 | ERR("Cannot create legacy ecore event message handler"); | ||
193 | return EINA_FALSE; | ||
194 | } | ||
195 | // init some core legacy event types in t he same order and numbering as before | ||
196 | // ECORE_EVENT_NONE 0 | ||
197 | // no need to do as ev types start at 1 | ||
198 | |||
199 | // ECORE_EVENT_SIGNAL_USER 1 | ||
200 | ecore_event_message_handler_type_new(_event_msg_handler); | ||
201 | // ECORE_EVENT_SIGNAL_HUP 2 | ||
202 | ecore_event_message_handler_type_new(_event_msg_handler); | ||
203 | // ECORE_EVENT_SIGNAL_EXIT 3 | ||
204 | ecore_event_message_handler_type_new(_event_msg_handler); | ||
205 | // ECORE_EVENT_SIGNAL_POWER 4 | ||
206 | ecore_event_message_handler_type_new(_event_msg_handler); | ||
207 | // ECORE_EVENT_SIGNAL_REALTIME 5 | ||
208 | ecore_event_message_handler_type_new(_event_msg_handler); | ||
209 | // ECORE_EVENT_MEMORY_STATE 6 | ||
210 | ecore_event_message_handler_type_new(_event_msg_handler); | ||
211 | // ECORE_EVENT_POWER_STATE 7 | ||
212 | ecore_event_message_handler_type_new(_event_msg_handler); | ||
213 | // ECORE_EVENT_LOCALE_CHANGED 8 | ||
214 | ecore_event_message_handler_type_new(_event_msg_handler); | ||
215 | // ECORE_EVENT_HOSTNAME_CHANGED 9 | ||
216 | ecore_event_message_handler_type_new(_event_msg_handler); | ||
217 | // ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED 10 | ||
218 | ecore_event_message_handler_type_new(_event_msg_handler); | ||
219 | // ECORE_EVENT_COUNT 11 | ||
220 | // no need to do as it was a count, nto an event | ||
221 | |||
222 | ////// | ||
223 | // XXX: ecore future still using legacy... | ||
358 | shutting_down = EINA_FALSE; | 224 | shutting_down = EINA_FALSE; |
359 | ECORE_EV_FUTURE_ID = ecore_event_type_new(); | 225 | ECORE_EV_FUTURE_ID = ecore_event_type_new(); |
360 | future_handler = ecore_event_handler_add(ECORE_EV_FUTURE_ID, ecore_future_dispatched, NULL); | 226 | future_handler = ecore_event_handler_add(ECORE_EV_FUTURE_ID, ecore_future_dispatched, NULL); |
@@ -364,6 +230,8 @@ _ecore_event_init(void) | |||
364 | NULL, sizeof(Ecore_Future_Schedule_Entry), | 230 | NULL, sizeof(Ecore_Future_Schedule_Entry), |
365 | 512); | 231 | 512); |
366 | EINA_SAFETY_ON_NULL_GOTO(mp_future_schedule_entry, err_pool); | 232 | EINA_SAFETY_ON_NULL_GOTO(mp_future_schedule_entry, err_pool); |
233 | // | ||
234 | ////// | ||
367 | 235 | ||
368 | return EINA_TRUE; | 236 | return EINA_TRUE; |
369 | 237 | ||
@@ -378,337 +246,42 @@ _ecore_event_init(void) | |||
378 | void | 246 | void |
379 | _ecore_event_shutdown(void) | 247 | _ecore_event_shutdown(void) |
380 | { | 248 | { |
381 | int i; | ||
382 | Ecore_Event_Handler *eh; | ||
383 | Ecore_Event_Filter *ef; | ||
384 | |||
385 | shutting_down = EINA_TRUE; | 249 | shutting_down = EINA_TRUE; |
250 | |||
251 | ////// | ||
252 | // XXX: ecore future still using legacy... | ||
386 | ecore_event_handler_del(future_handler); | 253 | ecore_event_handler_del(future_handler); |
387 | future_handler = NULL; | 254 | future_handler = NULL; |
388 | while (events) _ecore_event_del(events); | ||
389 | event_current = NULL; | ||
390 | for (i = 0; i < event_handlers_num; i++) | ||
391 | { | ||
392 | while ((eh = event_handlers[i])) | ||
393 | { | ||
394 | event_handlers[i] = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers[i]), EINA_INLIST_GET(event_handlers[i])); | ||
395 | ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE); | ||
396 | if (!eh->delete_me) ecore_event_handler_mp_free(eh); | ||
397 | } | ||
398 | } | ||
399 | EINA_LIST_FREE(event_handlers_delete_list, eh) | ||
400 | ecore_event_handler_mp_free(eh); | ||
401 | if (event_handlers) free(event_handlers); | ||
402 | event_handlers = NULL; | ||
403 | event_handlers_num = 0; | ||
404 | event_handlers_alloc_num = 0; | ||
405 | while ((ef = event_filters)) | ||
406 | { | ||
407 | event_filters = (Ecore_Event_Filter *)eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(event_filters)); | ||
408 | ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE); | ||
409 | ecore_event_filter_mp_free(ef); | ||
410 | } | ||
411 | event_filters_delete_me = 0; | ||
412 | event_filter_current = NULL; | ||
413 | event_filter_event_current = NULL; | ||
414 | ECORE_EV_FUTURE_ID = -1; | 255 | ECORE_EV_FUTURE_ID = -1; |
415 | } | 256 | // |
416 | 257 | ////// | |
417 | int | ||
418 | _ecore_event_exist(void) | ||
419 | { | ||
420 | Ecore_Event *e; | ||
421 | EINA_INLIST_FOREACH(events, e) | ||
422 | if (!e->delete_me) return 1; | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | Ecore_Event * | ||
427 | _ecore_event_add(int type, | ||
428 | void *ev, | ||
429 | Ecore_End_Cb func_free, | ||
430 | void *data) | ||
431 | { | ||
432 | Ecore_Event *e; | ||
433 | |||
434 | e = ecore_event_calloc(1); | ||
435 | if (!e) return NULL; | ||
436 | ECORE_MAGIC_SET(e, ECORE_MAGIC_EVENT); | ||
437 | e->type = type; | ||
438 | e->event = ev; | ||
439 | e->func_free = func_free; | ||
440 | e->data = data; | ||
441 | if (inpurge > 0) | ||
442 | { | ||
443 | purge_events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(e)); | ||
444 | events_num++; | ||
445 | } | ||
446 | else | ||
447 | { | ||
448 | events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e)); | ||
449 | events_num++; | ||
450 | } | ||
451 | return e; | ||
452 | } | ||
453 | |||
454 | void * | ||
455 | _ecore_event_del(Ecore_Event *event) | ||
456 | { | ||
457 | void *data; | ||
458 | |||
459 | data = event->data; | ||
460 | if (event->func_free) _ecore_call_end_cb(event->func_free, event->data, event->event); | ||
461 | events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(events), EINA_INLIST_GET(event)); | ||
462 | ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE); | ||
463 | ecore_event_mp_free(event); | ||
464 | events_num--; | ||
465 | return data; | ||
466 | } | ||
467 | |||
468 | static void | ||
469 | _ecore_event_purge_deleted(void) | ||
470 | { | ||
471 | Ecore_Event *itr = events; | ||
472 | 258 | ||
473 | inpurge++; | 259 | efl_loop_message_handler_message_clear(_event_msg_handler); |
474 | while (itr) | 260 | _event_msg_handler = NULL; |
475 | { | ||
476 | Ecore_Event *next = (Ecore_Event *)EINA_INLIST_GET(itr)->next; | ||
477 | if ((!itr->references) && (itr->delete_me)) | ||
478 | _ecore_event_del(itr); | ||
479 | itr = next; | ||
480 | } | ||
481 | inpurge--; | ||
482 | while (purge_events) | ||
483 | { | ||
484 | Ecore_Event *e = purge_events; | ||
485 | purge_events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(purge_events)); | ||
486 | events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e)); | ||
487 | } | ||
488 | } | ||
489 | |||
490 | static inline void | ||
491 | _ecore_event_filters_apply(void) | ||
492 | { | ||
493 | if (!event_filter_current) | ||
494 | { | ||
495 | /* regular main loop, start from head */ | ||
496 | event_filter_current = event_filters; | ||
497 | } | ||
498 | else | ||
499 | { | ||
500 | /* recursive main loop, continue from where we were */ | ||
501 | event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next; | ||
502 | } | ||
503 | if ((!event_filter_current) && (!event_filters_delete_me) && (!purge_events)) return; | ||
504 | eina_evlog("+event_filter", NULL, 0.0, NULL); | ||
505 | while (event_filter_current) | ||
506 | { | ||
507 | Ecore_Event_Filter *ef = event_filter_current; | ||
508 | |||
509 | if (!ef->delete_me) | ||
510 | { | ||
511 | ef->references++; | ||
512 | |||
513 | if (ef->func_start) | ||
514 | ef->loop_data = _ecore_call_data_cb(ef->func_start, ef->data); | ||
515 | |||
516 | if (!event_filter_event_current) | ||
517 | { | ||
518 | /* regular main loop, start from head */ | ||
519 | event_filter_event_current = events; | ||
520 | } | ||
521 | else | ||
522 | { | ||
523 | /* recursive main loop, continue from where we were */ | ||
524 | event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next; | ||
525 | } | ||
526 | |||
527 | while (event_filter_event_current) | ||
528 | { | ||
529 | Ecore_Event *e = event_filter_event_current; | ||
530 | |||
531 | if (!_ecore_call_filter_cb(ef->func_filter, ef->data, | ||
532 | ef->loop_data, e->type, e->event)) | ||
533 | { | ||
534 | ecore_event_del(e); | ||
535 | } | ||
536 | |||
537 | if (event_filter_event_current) /* may have changed in recursive main loops */ | ||
538 | event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next; | ||
539 | } | ||
540 | if (ef->func_end) | ||
541 | _ecore_call_end_cb(ef->func_end, ef->data, ef->loop_data); | ||
542 | |||
543 | ef->references--; | ||
544 | } | ||
545 | |||
546 | if (event_filter_current) /* may have changed in recursive main loops */ | ||
547 | event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next; | ||
548 | } | ||
549 | eina_evlog("-event_filter", NULL, 0.0, NULL); | ||
550 | if (event_filters_delete_me) | ||
551 | { | ||
552 | int deleted_in_use = 0; | ||
553 | Ecore_Event_Filter *l; | ||
554 | for (l = event_filters; l; ) | ||
555 | { | ||
556 | Ecore_Event_Filter *ef = l; | ||
557 | l = (Ecore_Event_Filter *)EINA_INLIST_GET(l)->next; | ||
558 | if (ef->delete_me) | ||
559 | { | ||
560 | if (ef->references) | ||
561 | { | ||
562 | deleted_in_use++; | ||
563 | continue; | ||
564 | } | ||
565 | |||
566 | event_filters = (Ecore_Event_Filter *)eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef)); | ||
567 | ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE); | ||
568 | ecore_event_filter_mp_free(ef); | ||
569 | } | ||
570 | } | ||
571 | if (!deleted_in_use) | ||
572 | event_filters_delete_me = 0; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | void | ||
577 | _ecore_event_call(void) | ||
578 | { | ||
579 | Eina_List *l, *l_next; | ||
580 | Ecore_Event_Handler *eh; | ||
581 | |||
582 | _ecore_event_filters_apply(); | ||
583 | |||
584 | if (!event_current) | ||
585 | { | ||
586 | /* regular main loop, start from head */ | ||
587 | event_current = events; | ||
588 | event_handler_current = NULL; | ||
589 | } | ||
590 | if ((!event_current) && (!event_handlers_delete_list)) return; | ||
591 | eina_evlog("+events", NULL, 0.0, NULL); | ||
592 | while (event_current) | ||
593 | { | ||
594 | Ecore_Event *e = event_current; | ||
595 | int handle_count = 0; | ||
596 | |||
597 | if (e->delete_me) | ||
598 | { | ||
599 | event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next; | ||
600 | continue; | ||
601 | } | ||
602 | |||
603 | ecore_raw_event_type = e->type; | ||
604 | ecore_raw_event_event = e->event; | ||
605 | e->references++; | ||
606 | if ((e->type >= 0) && (e->type < event_handlers_num)) | ||
607 | { | ||
608 | if (!event_handler_current) | ||
609 | { | ||
610 | /* regular main loop, start from head */ | ||
611 | event_handler_current = event_handlers[e->type]; | ||
612 | } | ||
613 | else | ||
614 | { | ||
615 | /* recursive main loop, continue from where we were */ | ||
616 | event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next; | ||
617 | } | ||
618 | |||
619 | while ((event_handler_current) && (!e->delete_me)) | ||
620 | { | ||
621 | eh = event_handler_current; | ||
622 | if (!eh->delete_me) | ||
623 | { | ||
624 | Eina_Bool ret; | ||
625 | |||
626 | handle_count++; | ||
627 | |||
628 | eh->references++; | ||
629 | ret = _ecore_call_handler_cb(eh->func, eh->data, e->type, e->event); | ||
630 | eh->references--; | ||
631 | |||
632 | if (!ret) | ||
633 | { | ||
634 | event_handler_current = NULL; | ||
635 | break; /* 0 == "call no further handlers" */ | ||
636 | } | ||
637 | } | ||
638 | |||
639 | if (event_handler_current) /* may have changed in recursive main loops */ | ||
640 | event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next; | ||
641 | } | ||
642 | } | ||
643 | while (event_handlers_add_list) | ||
644 | { | ||
645 | eh = event_handlers_add_list; | ||
646 | event_handlers_add_list = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers_add_list), EINA_INLIST_GET(eh)); | ||
647 | event_handlers[eh->type] = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh)); | ||
648 | } | ||
649 | /* if no handlers were set for EXIT signal - then default is */ | ||
650 | /* to quit the main loop */ | ||
651 | if ((e->type == ECORE_EVENT_SIGNAL_EXIT) && (handle_count == 0)) | ||
652 | ecore_main_loop_quit(); | ||
653 | e->references--; | ||
654 | e->delete_me = 1; | ||
655 | |||
656 | if (event_current) /* may have changed in recursive main loops */ | ||
657 | event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next; | ||
658 | } | ||
659 | eina_evlog("-events", NULL, 0.0, NULL); | ||
660 | |||
661 | ecore_raw_event_type = ECORE_EVENT_NONE; | ||
662 | ecore_raw_event_event = NULL; | ||
663 | |||
664 | _ecore_event_purge_deleted(); | ||
665 | |||
666 | EINA_LIST_FOREACH_SAFE(event_handlers_delete_list, l, l_next, eh) | ||
667 | { | ||
668 | if (eh->references) continue; | ||
669 | |||
670 | event_handlers_delete_list = eina_list_remove_list(event_handlers_delete_list, l); | ||
671 | |||
672 | event_handlers[eh->type] = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh)); | ||
673 | ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE); | ||
674 | ecore_event_handler_mp_free(eh); | ||
675 | } | ||
676 | } | 261 | } |
677 | 262 | ||
678 | void * | 263 | void * |
679 | _ecore_event_signal_user_new(void) | 264 | _ecore_event_signal_user_new(void) |
680 | { | 265 | { |
681 | Ecore_Event_Signal_User *e; | 266 | return calloc(1, sizeof(Ecore_Event_Signal_User)); |
682 | |||
683 | e = calloc(1, sizeof(Ecore_Event_Signal_User)); | ||
684 | return e; | ||
685 | } | 267 | } |
686 | 268 | ||
687 | void * | 269 | void * |
688 | _ecore_event_signal_hup_new(void) | 270 | _ecore_event_signal_hup_new(void) |
689 | { | 271 | { |
690 | Ecore_Event_Signal_Hup *e; | 272 | return calloc(1, sizeof(Ecore_Event_Signal_Hup)); |
691 | |||
692 | e = calloc(1, sizeof(Ecore_Event_Signal_Hup)); | ||
693 | return e; | ||
694 | } | 273 | } |
695 | 274 | ||
696 | void * | 275 | void * |
697 | _ecore_event_signal_exit_new(void) | 276 | _ecore_event_signal_exit_new(void) |
698 | { | 277 | { |
699 | Ecore_Event_Signal_Exit *e; | 278 | return calloc(1, sizeof(Ecore_Event_Signal_Exit)); |
700 | |||
701 | e = calloc(1, sizeof(Ecore_Event_Signal_Exit)); | ||
702 | return e; | ||
703 | } | 279 | } |
704 | 280 | ||
705 | void * | 281 | void * |
706 | _ecore_event_signal_power_new(void) | 282 | _ecore_event_signal_power_new(void) |
707 | { | 283 | { |
708 | Ecore_Event_Signal_Power *e; | 284 | return calloc(1, sizeof(Ecore_Event_Signal_Power)); |
709 | |||
710 | e = calloc(1, sizeof(Ecore_Event_Signal_Power)); | ||
711 | return e; | ||
712 | } | 285 | } |
713 | 286 | ||
714 | void * | 287 | void * |
@@ -720,58 +293,17 @@ _ecore_event_signal_realtime_new(void) | |||
720 | EAPI void | 293 | EAPI void |
721 | ecore_event_type_flush_internal(int type, ...) | 294 | ecore_event_type_flush_internal(int type, ...) |
722 | { | 295 | { |
723 | Eina_Inarray types; | ||
724 | Ecore_Event *event; | ||
725 | Eina_Inlist *l; | ||
726 | int *itr; | ||
727 | va_list args; | 296 | va_list args; |
728 | Eina_Bool wrong_type = EINA_FALSE; | ||
729 | 297 | ||
730 | // In case of an empty list of event | ||
731 | if (type == ECORE_EVENT_NONE) return; | 298 | if (type == ECORE_EVENT_NONE) return; |
732 | 299 | ecore_event_message_handler_type_flush(_event_msg_handler, type); | |
733 | eina_inarray_step_set(&types, sizeof (Eina_Inarray), sizeof (int), 4); | ||
734 | |||
735 | eina_inarray_push(&types, &type); | ||
736 | 300 | ||
737 | va_start(args, type); | 301 | va_start(args, type); |
738 | do | 302 | for (;;) |
739 | { | 303 | { |
740 | type = va_arg(args, int); | 304 | type = va_arg(args, int); |
741 | if (type == ECORE_EVENT_NONE) break ; | 305 | if (type == ECORE_EVENT_NONE) break; |
742 | eina_inarray_push(&types, &type); | 306 | ecore_event_message_handler_type_flush(_event_msg_handler, type); |
743 | } | 307 | } |
744 | while (1); | ||
745 | va_end(args); | 308 | va_end(args); |
746 | |||
747 | EINA_INARRAY_FOREACH(&types, itr) | ||
748 | { | ||
749 | if (*itr >= 0 && *itr < event_id_max) continue; | ||
750 | |||
751 | ERR("Invalid event flush requested: %i", *itr); | ||
752 | wrong_type = EINA_TRUE; | ||
753 | } | ||
754 | |||
755 | if (wrong_type) | ||
756 | { | ||
757 | eina_inarray_flush(&types); | ||
758 | return ; | ||
759 | } | ||
760 | |||
761 | EINA_INLIST_FOREACH_SAFE((Eina_Inlist *) events, l, event) | ||
762 | { | ||
763 | Eina_Bool found = EINA_FALSE; | ||
764 | |||
765 | EINA_INARRAY_FOREACH(&types, itr) | ||
766 | if (event->type == *itr) | ||
767 | found = EINA_TRUE; | ||
768 | if (!found) continue ; | ||
769 | |||
770 | if (event->delete_me) continue ; | ||
771 | event->delete_me = 1; | ||
772 | } | ||
773 | |||
774 | _ecore_event_purge_deleted(); | ||
775 | |||
776 | eina_inarray_flush(&types); | ||
777 | } | 309 | } |
diff --git a/src/lib/ecore/ecore_exe.c b/src/lib/ecore/ecore_exe.c index 22486cd609..908f677539 100644 --- a/src/lib/ecore/ecore_exe.c +++ b/src/lib/ecore/ecore_exe.c | |||
@@ -38,8 +38,6 @@ EAPI int ECORE_EXE_EVENT_DEL = 0; | |||
38 | EAPI int ECORE_EXE_EVENT_DATA = 0; | 38 | EAPI int ECORE_EXE_EVENT_DATA = 0; |
39 | EAPI int ECORE_EXE_EVENT_ERROR = 0; | 39 | EAPI int ECORE_EXE_EVENT_ERROR = 0; |
40 | 40 | ||
41 | Eina_List *_ecore_exe_exes = NULL; | ||
42 | |||
43 | EAPI void | 41 | EAPI void |
44 | ecore_exe_run_priority_set(int pri) | 42 | ecore_exe_run_priority_set(int pri) |
45 | { | 43 | { |
@@ -63,18 +61,19 @@ ecore_exe_run(const char *exe_cmd, | |||
63 | } | 61 | } |
64 | 62 | ||
65 | EAPI Ecore_Exe * | 63 | EAPI Ecore_Exe * |
66 | ecore_exe_pipe_run(const char *exe_cmd, | 64 | ecore_exe_pipe_run(const char *exe_cmd, |
67 | Ecore_Exe_Flags flags, | 65 | Ecore_Exe_Flags flags, |
68 | const void *data) | 66 | const void *data) |
69 | { | 67 | { |
70 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 68 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); |
71 | Ecore_Exe *ret = efl_add(MY_CLASS, NULL, ecore_obj_exe_command_set(efl_added, exe_cmd, flags)); | 69 | Ecore_Exe *ret = efl_add(MY_CLASS, efl_loop_main_get(EFL_LOOP_CLASS), |
70 | ecore_obj_exe_command_set(efl_added, exe_cmd, | ||
71 | flags)); | ||
72 | if (ret) | 72 | if (ret) |
73 | { | 73 | { |
74 | Ecore_Exe_Data *pd = efl_data_scope_get(ret, MY_CLASS); | 74 | Ecore_Exe_Data *pd = efl_data_scope_get(ret, MY_CLASS); |
75 | pd->data = (void *) data; | 75 | pd->data = (void *) data; |
76 | } | 76 | } |
77 | |||
78 | return ret; | 77 | return ret; |
79 | } | 78 | } |
80 | 79 | ||
@@ -98,10 +97,7 @@ _ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe) | |||
98 | { | 97 | { |
99 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 98 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); |
100 | obj = efl_finalize(efl_super(obj, MY_CLASS)); | 99 | obj = efl_finalize(efl_super(obj, MY_CLASS)); |
101 | 100 | if (!obj) return obj; | |
102 | if (!obj) | ||
103 | return obj; | ||
104 | |||
105 | return _impl_ecore_exe_efl_object_finalize(obj, exe); | 101 | return _impl_ecore_exe_efl_object_finalize(obj, exe); |
106 | } | 102 | } |
107 | 103 | ||
@@ -111,8 +107,7 @@ ecore_exe_callback_pre_free_set(Ecore_Exe *obj, | |||
111 | { | 107 | { |
112 | EINA_MAIN_LOOP_CHECK_RETURN; | 108 | EINA_MAIN_LOOP_CHECK_RETURN; |
113 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 109 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
114 | if (!efl_isa(obj, MY_CLASS)) | 110 | if (!efl_isa(obj, MY_CLASS)) return; |
115 | return; | ||
116 | exe->pre_free_cb = func; | 111 | exe->pre_free_cb = func; |
117 | } | 112 | } |
118 | 113 | ||
@@ -123,18 +118,15 @@ ecore_exe_send(Ecore_Exe *obj, | |||
123 | { | 118 | { |
124 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); | 119 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); |
125 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 120 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
126 | if (!efl_isa(obj, MY_CLASS)) | 121 | if (!efl_isa(obj, MY_CLASS)) return EINA_FALSE; |
127 | return EINA_FALSE; | ||
128 | 122 | ||
129 | EINA_SAFETY_ON_TRUE_RETURN_VAL(size == 0, EINA_TRUE); | 123 | EINA_SAFETY_ON_TRUE_RETURN_VAL(size == 0, EINA_TRUE); |
130 | |||
131 | if (exe->close_stdin) | 124 | if (exe->close_stdin) |
132 | { | 125 | { |
133 | ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p", | 126 | ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p", |
134 | exe, size, data); | 127 | exe, size, data); |
135 | return EINA_FALSE; | 128 | return EINA_FALSE; |
136 | } | 129 | } |
137 | |||
138 | return _impl_ecore_exe_send(obj, exe, data, size); | 130 | return _impl_ecore_exe_send(obj, exe, data, size); |
139 | } | 131 | } |
140 | 132 | ||
@@ -143,9 +135,7 @@ ecore_exe_close_stdin(Ecore_Exe *obj) | |||
143 | { | 135 | { |
144 | EINA_MAIN_LOOP_CHECK_RETURN; | 136 | EINA_MAIN_LOOP_CHECK_RETURN; |
145 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 137 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
146 | if (!efl_isa(obj, MY_CLASS)) | 138 | if (!efl_isa(obj, MY_CLASS)) return; |
147 | return; | ||
148 | |||
149 | exe->close_stdin = 1; | 139 | exe->close_stdin = 1; |
150 | } | 140 | } |
151 | 141 | ||
@@ -158,10 +148,9 @@ ecore_exe_auto_limits_set(Ecore_Exe *obj, | |||
158 | { | 148 | { |
159 | EINA_MAIN_LOOP_CHECK_RETURN; | 149 | EINA_MAIN_LOOP_CHECK_RETURN; |
160 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 150 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
161 | if (!efl_isa(obj, MY_CLASS)) | 151 | if (!efl_isa(obj, MY_CLASS)) return; |
162 | return; | 152 | _impl_ecore_exe_auto_limits_set(obj, exe, start_bytes, end_bytes, |
163 | 153 | start_lines, end_lines); | |
164 | _impl_ecore_exe_auto_limits_set(obj, exe, start_bytes, end_bytes, start_lines, end_lines); | ||
165 | } | 154 | } |
166 | 155 | ||
167 | EAPI Ecore_Exe_Event_Data * | 156 | EAPI Ecore_Exe_Event_Data * |
@@ -170,9 +159,7 @@ ecore_exe_event_data_get(Ecore_Exe *obj, | |||
170 | { | 159 | { |
171 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 160 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); |
172 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 161 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
173 | if (!efl_isa(obj, MY_CLASS)) | 162 | if (!efl_isa(obj, MY_CLASS)) return NULL; |
174 | return NULL; | ||
175 | |||
176 | return _impl_ecore_exe_event_data_get(obj, exe, flags); | 163 | return _impl_ecore_exe_event_data_get(obj, exe, flags); |
177 | } | 164 | } |
178 | 165 | ||
@@ -182,14 +169,10 @@ ecore_exe_tag_set(Ecore_Exe *obj, | |||
182 | { | 169 | { |
183 | EINA_MAIN_LOOP_CHECK_RETURN; | 170 | EINA_MAIN_LOOP_CHECK_RETURN; |
184 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 171 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
185 | if (!efl_isa(obj, MY_CLASS)) | 172 | if (!efl_isa(obj, MY_CLASS)) return; |
186 | return; | ||
187 | |||
188 | IF_FREE(exe->tag); | 173 | IF_FREE(exe->tag); |
189 | if (tag) | 174 | if (tag) exe->tag = strdup(tag); |
190 | exe->tag = strdup(tag); | 175 | else exe->tag = NULL; |
191 | else | ||
192 | exe->tag = NULL; | ||
193 | } | 176 | } |
194 | 177 | ||
195 | EAPI const char * | 178 | EAPI const char * |
@@ -197,9 +180,7 @@ ecore_exe_tag_get(const Ecore_Exe *obj) | |||
197 | { | 180 | { |
198 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 181 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); |
199 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 182 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
200 | if (!efl_isa(obj, MY_CLASS)) | 183 | if (!efl_isa(obj, MY_CLASS)) return NULL; |
201 | return NULL; | ||
202 | |||
203 | return exe->tag; | 184 | return exe->tag; |
204 | } | 185 | } |
205 | 186 | ||
@@ -208,12 +189,9 @@ ecore_exe_free(Ecore_Exe *obj) | |||
208 | { | 189 | { |
209 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 190 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); |
210 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 191 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
211 | if (!efl_isa(obj, MY_CLASS)) | 192 | if (!efl_isa(obj, MY_CLASS)) return NULL; |
212 | return NULL; | ||
213 | |||
214 | void *data = exe->data; | 193 | void *data = exe->data; |
215 | efl_del(obj); | 194 | efl_del(obj); |
216 | |||
217 | return data; | 195 | return data; |
218 | } | 196 | } |
219 | 197 | ||
@@ -221,7 +199,6 @@ EOLIAN static void | |||
221 | _ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe) | 199 | _ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe) |
222 | { | 200 | { |
223 | efl_destructor(efl_super(obj, ECORE_EXE_CLASS)); | 201 | efl_destructor(efl_super(obj, ECORE_EXE_CLASS)); |
224 | |||
225 | _impl_ecore_exe_efl_object_destructor(obj, exe); | 202 | _impl_ecore_exe_efl_object_destructor(obj, exe); |
226 | } | 203 | } |
227 | 204 | ||
@@ -239,9 +216,7 @@ ecore_exe_pid_get(const Ecore_Exe *obj) | |||
239 | { | 216 | { |
240 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); | 217 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); |
241 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 218 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
242 | if (!efl_isa(obj, MY_CLASS)) | 219 | if (!efl_isa(obj, MY_CLASS)) return -1; |
243 | return -1; | ||
244 | |||
245 | return exe->pid; | 220 | return exe->pid; |
246 | } | 221 | } |
247 | 222 | ||
@@ -250,9 +225,7 @@ ecore_exe_cmd_get(const Ecore_Exe *obj) | |||
250 | { | 225 | { |
251 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 226 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); |
252 | const char *ret = NULL; | 227 | const char *ret = NULL; |
253 | |||
254 | ecore_obj_exe_command_get(obj, &ret, NULL); | 228 | ecore_obj_exe_command_get(obj, &ret, NULL); |
255 | |||
256 | return ret; | 229 | return ret; |
257 | } | 230 | } |
258 | 231 | ||
@@ -261,9 +234,7 @@ ecore_exe_data_get(const Ecore_Exe *obj) | |||
261 | { | 234 | { |
262 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 235 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); |
263 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 236 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
264 | if (!efl_isa(obj, MY_CLASS)) | 237 | if (!efl_isa(obj, MY_CLASS)) return NULL; |
265 | return NULL; | ||
266 | |||
267 | return exe->data; | 238 | return exe->data; |
268 | } | 239 | } |
269 | 240 | ||
@@ -274,9 +245,7 @@ ecore_exe_data_set(Ecore_Exe *obj, | |||
274 | void *ret; | 245 | void *ret; |
275 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); | 246 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); |
276 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 247 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
277 | if (!efl_isa(obj, MY_CLASS)) | 248 | if (!efl_isa(obj, MY_CLASS)) return NULL; |
278 | return NULL; | ||
279 | |||
280 | ret = exe->data; | 249 | ret = exe->data; |
281 | exe->data = data; | 250 | exe->data = data; |
282 | return ret; | 251 | return ret; |
@@ -287,9 +256,7 @@ ecore_exe_flags_get(const Ecore_Exe *obj) | |||
287 | { | 256 | { |
288 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); | 257 | EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); |
289 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 258 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
290 | if (!efl_isa(obj, MY_CLASS)) | 259 | if (!efl_isa(obj, MY_CLASS)) return 0; |
291 | return 0; | ||
292 | |||
293 | return exe->flags; | 260 | return exe->flags; |
294 | } | 261 | } |
295 | 262 | ||
@@ -309,15 +276,8 @@ EOLIAN static void | |||
309 | _ecore_exe_efl_control_suspend_set(Eo *obj EINA_UNUSED, Ecore_Exe_Data *exe, Eina_Bool suspend) | 276 | _ecore_exe_efl_control_suspend_set(Eo *obj EINA_UNUSED, Ecore_Exe_Data *exe, Eina_Bool suspend) |
310 | { | 277 | { |
311 | EINA_MAIN_LOOP_CHECK_RETURN; | 278 | EINA_MAIN_LOOP_CHECK_RETURN; |
312 | 279 | if (suspend) _impl_ecore_exe_pause(obj, exe); | |
313 | if (suspend) | 280 | else _impl_ecore_exe_continue(obj, exe); |
314 | { | ||
315 | _impl_ecore_exe_pause(obj, exe); | ||
316 | } | ||
317 | else | ||
318 | { | ||
319 | _impl_ecore_exe_continue(obj, exe); | ||
320 | } | ||
321 | } | 281 | } |
322 | 282 | ||
323 | EAPI void | 283 | EAPI void |
@@ -325,9 +285,7 @@ ecore_exe_interrupt(Ecore_Exe *obj) | |||
325 | { | 285 | { |
326 | EINA_MAIN_LOOP_CHECK_RETURN; | 286 | EINA_MAIN_LOOP_CHECK_RETURN; |
327 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 287 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
328 | if (!efl_isa(obj, MY_CLASS)) | 288 | if (!efl_isa(obj, MY_CLASS)) return; |
329 | return; | ||
330 | |||
331 | _impl_ecore_exe_interrupt(obj, exe); | 289 | _impl_ecore_exe_interrupt(obj, exe); |
332 | } | 290 | } |
333 | 291 | ||
@@ -336,9 +294,7 @@ ecore_exe_quit(Ecore_Exe *obj) | |||
336 | { | 294 | { |
337 | EINA_MAIN_LOOP_CHECK_RETURN; | 295 | EINA_MAIN_LOOP_CHECK_RETURN; |
338 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 296 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
339 | if (!efl_isa(obj, MY_CLASS)) | 297 | if (!efl_isa(obj, MY_CLASS)) return; |
340 | return; | ||
341 | |||
342 | _impl_ecore_exe_quit(obj, exe); | 298 | _impl_ecore_exe_quit(obj, exe); |
343 | } | 299 | } |
344 | 300 | ||
@@ -347,9 +303,7 @@ ecore_exe_terminate(Ecore_Exe *obj) | |||
347 | { | 303 | { |
348 | EINA_MAIN_LOOP_CHECK_RETURN; | 304 | EINA_MAIN_LOOP_CHECK_RETURN; |
349 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 305 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
350 | if (!efl_isa(obj, MY_CLASS)) | 306 | if (!efl_isa(obj, MY_CLASS)) return; |
351 | return; | ||
352 | |||
353 | _impl_ecore_exe_terminate(obj, exe); | 307 | _impl_ecore_exe_terminate(obj, exe); |
354 | } | 308 | } |
355 | 309 | ||
@@ -358,9 +312,7 @@ ecore_exe_kill(Ecore_Exe *obj) | |||
358 | { | 312 | { |
359 | EINA_MAIN_LOOP_CHECK_RETURN; | 313 | EINA_MAIN_LOOP_CHECK_RETURN; |
360 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 314 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
361 | if (!efl_isa(obj, MY_CLASS)) | 315 | if (!efl_isa(obj, MY_CLASS)) return; |
362 | return; | ||
363 | |||
364 | _impl_ecore_exe_kill(obj, exe); | 316 | _impl_ecore_exe_kill(obj, exe); |
365 | } | 317 | } |
366 | 318 | ||
@@ -370,9 +322,7 @@ ecore_exe_signal(Ecore_Exe *obj, | |||
370 | { | 322 | { |
371 | EINA_MAIN_LOOP_CHECK_RETURN; | 323 | EINA_MAIN_LOOP_CHECK_RETURN; |
372 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 324 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
373 | if (!efl_isa(obj, MY_CLASS)) | 325 | if (!efl_isa(obj, MY_CLASS)) return; |
374 | return; | ||
375 | |||
376 | _impl_ecore_exe_signal(obj, exe, num); | 326 | _impl_ecore_exe_signal(obj, exe, num); |
377 | } | 327 | } |
378 | 328 | ||
@@ -381,9 +331,7 @@ ecore_exe_hup(Ecore_Exe *obj) | |||
381 | { | 331 | { |
382 | EINA_MAIN_LOOP_CHECK_RETURN; | 332 | EINA_MAIN_LOOP_CHECK_RETURN; |
383 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 333 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
384 | if (!efl_isa(obj, MY_CLASS)) | 334 | if (!efl_isa(obj, MY_CLASS)) return; |
385 | return; | ||
386 | |||
387 | _impl_ecore_exe_hup(obj, exe); | 335 | _impl_ecore_exe_hup(obj, exe); |
388 | } | 336 | } |
389 | 337 | ||
@@ -401,7 +349,9 @@ _ecore_exe_shutdown(void) | |||
401 | { | 349 | { |
402 | Ecore_Exe *exe = NULL; | 350 | Ecore_Exe *exe = NULL; |
403 | Eina_List *l1, *l2; | 351 | Eina_List *l1, *l2; |
404 | EINA_LIST_FOREACH_SAFE(_ecore_exe_exes, l1, l2, exe) | 352 | Efl_Loop_Data *loop = EFL_LOOP_DATA; |
353 | |||
354 | EINA_LIST_FOREACH_SAFE(loop->exes, l1, l2, exe) | ||
405 | ecore_exe_free(exe); | 355 | ecore_exe_free(exe); |
406 | 356 | ||
407 | ecore_event_type_flush(ECORE_EXE_EVENT_ADD, | 357 | ecore_event_type_flush(ECORE_EXE_EVENT_ADD, |
@@ -415,22 +365,20 @@ _ecore_exe_find(pid_t pid) | |||
415 | { | 365 | { |
416 | Eina_List *itr; | 366 | Eina_List *itr; |
417 | Ecore_Exe *obj; | 367 | Ecore_Exe *obj; |
368 | Efl_Loop_Data *loop = EFL_LOOP_DATA; | ||
418 | 369 | ||
419 | EINA_LIST_FOREACH(_ecore_exe_exes, itr, obj) | 370 | EINA_LIST_FOREACH(loop->exes, itr, obj) |
420 | { | 371 | { |
421 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 372 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
422 | if (exe->pid == pid) | 373 | if (exe->pid == pid) return obj; |
423 | return obj; | 374 | } |
424 | } | ||
425 | return NULL; | 375 | return NULL; |
426 | } | 376 | } |
427 | 377 | ||
428 | void * | 378 | void * |
429 | _ecore_exe_event_del_new(void) | 379 | _ecore_exe_event_del_new(void) |
430 | { | 380 | { |
431 | Ecore_Exe_Event_Del *e; | 381 | Ecore_Exe_Event_Del *e = calloc(1, sizeof(Ecore_Exe_Event_Del)); |
432 | |||
433 | e = calloc(1, sizeof(Ecore_Exe_Event_Del)); | ||
434 | return e; | 382 | return e; |
435 | } | 383 | } |
436 | 384 | ||
@@ -438,11 +386,8 @@ void | |||
438 | _ecore_exe_event_del_free(void *data EINA_UNUSED, | 386 | _ecore_exe_event_del_free(void *data EINA_UNUSED, |
439 | void *ev) | 387 | void *ev) |
440 | { | 388 | { |
441 | Ecore_Exe_Event_Del *e; | 389 | Ecore_Exe_Event_Del *e = ev; |
442 | 390 | if (e->exe) ecore_exe_free(e->exe); | |
443 | e = ev; | ||
444 | if (e->exe) | ||
445 | ecore_exe_free(e->exe); | ||
446 | free(e); | 391 | free(e); |
447 | } | 392 | } |
448 | 393 | ||
@@ -450,18 +395,14 @@ void | |||
450 | _ecore_exe_event_exe_data_free(void *data EINA_UNUSED, | 395 | _ecore_exe_event_exe_data_free(void *data EINA_UNUSED, |
451 | void *ev) | 396 | void *ev) |
452 | { | 397 | { |
453 | Ecore_Exe_Event_Data *e; | 398 | Ecore_Exe_Event_Data *e = ev; |
454 | |||
455 | e = ev; | ||
456 | ecore_exe_event_data_free(e); | 399 | ecore_exe_event_data_free(e); |
457 | } | 400 | } |
458 | 401 | ||
459 | Ecore_Exe_Event_Add * | 402 | Ecore_Exe_Event_Add * |
460 | _ecore_exe_event_add_new(void) | 403 | _ecore_exe_event_add_new(void) |
461 | { | 404 | { |
462 | Ecore_Exe_Event_Add *e; | 405 | Ecore_Exe_Event_Add *e = calloc(1, sizeof(Ecore_Exe_Event_Add)); |
463 | |||
464 | e = calloc(1, sizeof(Ecore_Exe_Event_Add)); | ||
465 | return e; | 406 | return e; |
466 | } | 407 | } |
467 | 408 | ||
@@ -469,9 +410,7 @@ void | |||
469 | _ecore_exe_event_add_free(void *data EINA_UNUSED, | 410 | _ecore_exe_event_add_free(void *data EINA_UNUSED, |
470 | void *ev) | 411 | void *ev) |
471 | { | 412 | { |
472 | Ecore_Exe_Event_Add *e; | 413 | Ecore_Exe_Event_Add *e = ev; |
473 | |||
474 | e = ev; | ||
475 | free(e); | 414 | free(e); |
476 | } | 415 | } |
477 | 416 | ||
diff --git a/src/lib/ecore/ecore_exe_posix.c b/src/lib/ecore/ecore_exe_posix.c index bebfce26a1..21d8861ef2 100644 --- a/src/lib/ecore/ecore_exe_posix.c +++ b/src/lib/ecore/ecore_exe_posix.c | |||
@@ -43,60 +43,51 @@ | |||
43 | * appended with a preceding space. The first is the command off course. | 43 | * appended with a preceding space. The first is the command off course. |
44 | */ | 44 | */ |
45 | 45 | ||
46 | struct _ecore_exe_dead_exe | 46 | static inline void _ecore_exe_exec_it(const char *exe_cmd, |
47 | { | ||
48 | pid_t pid; | ||
49 | char *cmd; | ||
50 | }; | ||
51 | |||
52 | static inline void _ecore_exe_exec_it(const char *exe_cmd, | ||
53 | Ecore_Exe_Flags flags); | 47 | Ecore_Exe_Flags flags); |
54 | static Eina_Bool _ecore_exe_data_generic_handler(void *data, | 48 | static Eina_Bool _ecore_exe_data_generic_handler(void *data, |
55 | Ecore_Fd_Handler *fd_handler, | 49 | Ecore_Fd_Handler *fd_handler, |
56 | Ecore_Exe_Flags flags); | 50 | Ecore_Exe_Flags flags); |
57 | static Eina_Bool _ecore_exe_data_error_handler(void *data, | 51 | static Eina_Bool _ecore_exe_data_error_handler(void *data, |
58 | Ecore_Fd_Handler *fd_handler); | 52 | Ecore_Fd_Handler *fd_handler); |
59 | static Eina_Bool _ecore_exe_data_read_handler(void *data, | 53 | static Eina_Bool _ecore_exe_data_read_handler(void *data, |
60 | Ecore_Fd_Handler *fd_handler); | 54 | Ecore_Fd_Handler *fd_handler); |
61 | static Eina_Bool _ecore_exe_data_write_handler(void *data, | 55 | static Eina_Bool _ecore_exe_data_write_handler(void *data, |
62 | Ecore_Fd_Handler *fd_handler); | 56 | Ecore_Fd_Handler *fd_handler); |
63 | static void _ecore_exe_flush(Ecore_Exe *obj); | 57 | static void _ecore_exe_flush(Ecore_Exe *obj); |
64 | static Ecore_Exe *_ecore_exe_is_it_alive(pid_t pid); | 58 | static void _ecore_exe_make_sure_its_dead(void *data, const Efl_Event *event); |
65 | static Eina_Bool _ecore_exe_make_sure_its_dead(void *data); | 59 | static void _ecore_exe_make_sure_its_really_dead(void *data, const Efl_Event *event); |
66 | static Eina_Bool _ecore_exe_make_sure_its_really_dead(void *data); | 60 | static void _ecore_exe_dead_attach(Ecore_Exe *obj); |
67 | static void _ecore_exe_dead_attach(Ecore_Exe *obj); | ||
68 | 61 | ||
69 | static const char *shell = NULL; | 62 | static const char *shell = NULL; |
70 | 63 | ||
71 | /* FIXME: This errno checking stuff should be put elsewhere for everybody to use. | 64 | /* FIXME: This errno checking stuff should be put elsewhere for everybody to use. |
72 | * For now it lives here though, just to make testing easier. | 65 | * For now it lives here though, just to make testing easier. |
73 | */ | 66 | */ |
74 | static int _ecore_exe_check_errno(int result, | 67 | static int _ecore_exe_check_errno(int result, |
75 | const char *file, | 68 | const char *file, |
76 | int line); | 69 | int line); |
77 | 70 | ||
78 | #define E_IF_NO_ERRNO(result, foo, ok) \ | 71 | #define E_IF_NO_ERRNO(result, foo, ok) \ |
79 | while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) \ | 72 | while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) sleep(1); \ |
80 | sleep(1); \ | 73 | if (ok) |
81 | if (ok) | ||
82 | 74 | ||
83 | #define E_NO_ERRNO(result, foo, ok) \ | 75 | #define E_NO_ERRNO(result, foo, ok) \ |
84 | while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) \ | 76 | while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) sleep(1) |
85 | sleep(1) | ||
86 | 77 | ||
87 | #define E_IF_NO_ERRNO_NOLOOP(result, foo, ok) \ | 78 | #define E_IF_NO_ERRNO_NOLOOP(result, foo, ok) \ |
88 | if (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__))) | 79 | if (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__))) |
89 | 80 | ||
90 | static int | 81 | static int |
91 | _ecore_exe_check_errno(int result, | 82 | _ecore_exe_check_errno(int result, |
92 | const char *file EINA_UNUSED, | 83 | const char *file EINA_UNUSED, |
93 | int line EINA_UNUSED) | 84 | int line EINA_UNUSED) |
94 | { | 85 | { |
95 | int saved_errno = errno; | 86 | int saved_errno = errno; |
96 | 87 | ||
97 | if (result == -1) | 88 | if (result == -1) |
98 | { | 89 | { |
99 | perror("*** errno reports "); | 90 | perror("*** errno reports "); |
100 | /* What is currently supported - | 91 | /* What is currently supported - |
101 | * | 92 | * |
102 | * pipe | 93 | * pipe |
@@ -152,63 +143,63 @@ _ecore_exe_check_errno(int result, | |||
152 | * // Something failed, cleanup. | 143 | * // Something failed, cleanup. |
153 | * } | 144 | * } |
154 | */ | 145 | */ |
155 | switch (saved_errno) | 146 | switch (saved_errno) |
156 | { | 147 | { |
157 | case EACCES: | 148 | case EACCES: |
158 | case EAGAIN: | 149 | case EAGAIN: |
159 | case EINTR: | 150 | case EINTR: |
160 | { /* Not now, try later. */ | 151 | { /* Not now, try later. */ |
161 | ERR("*** Must try again in %s @%u.", file, line); | 152 | ERR("*** Must try again in %s @%u.", file, line); |
162 | result = -1; | 153 | result = -1; |
163 | break; | 154 | break; |
164 | } | 155 | } |
165 | 156 | ||
166 | case EMFILE: | 157 | case EMFILE: |
167 | case ENFILE: | 158 | case ENFILE: |
168 | case ENOLCK: | 159 | case ENOLCK: |
169 | { /* Low on resources. */ | 160 | { /* Low on resources. */ |
170 | ERR("*** Low on resources in %s @%u.", file, | 161 | ERR("*** Low on resources in %s @%u.", file, |
171 | line); | 162 | line); |
172 | result = 0; | 163 | result = 0; |
173 | break; | 164 | break; |
174 | } | 165 | } |
175 | 166 | ||
176 | case EIO: | 167 | case EIO: |
177 | { /* I/O error. */ | 168 | { /* I/O error. */ |
178 | ERR("*** I/O error in %s @%u.", file, line); | 169 | ERR("*** I/O error in %s @%u.", file, line); |
179 | result = 0; | 170 | result = 0; |
180 | break; | 171 | break; |
181 | } | 172 | } |
182 | 173 | ||
183 | case EFAULT: | 174 | case EFAULT: |
184 | case EBADF: | 175 | case EBADF: |
185 | case EINVAL: | 176 | case EINVAL: |
186 | case EROFS: | 177 | case EROFS: |
187 | case EISDIR: | 178 | case EISDIR: |
188 | case EDEADLK: | 179 | case EDEADLK: |
189 | case EPERM: | 180 | case EPERM: |
190 | case EBUSY: | 181 | case EBUSY: |
191 | { /* Programmer fucked up. */ | 182 | { /* Programmer fucked up. */ |
192 | ERR("*** NAUGHTY PROGRAMMER!!!\n" | 183 | ERR("*** NAUGHTY PROGRAMMER!!!\n" |
193 | "*** SPANK SPANK SPANK!!!\n" | 184 | "*** SPANK SPANK SPANK!!!\n" |
194 | "*** Now go fix your code in %s @%u. Tut tut tut!", | 185 | "*** Now go fix your code in %s @%u. Tut tut tut!", |
195 | file, line); | 186 | file, line); |
196 | result = 0; | 187 | result = 0; |
197 | break; | 188 | break; |
198 | } | 189 | } |
199 | 190 | ||
200 | default: | 191 | default: |
201 | { /* Unsupported errno code, please add this one. */ | 192 | { /* Unsupported errno code, please add this one. */ |
202 | ERR("*** NAUGHTY PROGRAMMER!!!\n" | 193 | ERR("*** NAUGHTY PROGRAMMER!!!\n" |
203 | "*** SPANK SPANK SPANK!!!\n" | 194 | "*** SPANK SPANK SPANK!!!\n" |
204 | "*** Unsupported errno code %d, please add this one.\n" | 195 | "*** Unsupported errno code %d, please add this one.\n" |
205 | "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!", | 196 | "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!", |
206 | saved_errno, __FILE__, __LINE__, file, line); | 197 | saved_errno, __FILE__, __LINE__, file, line); |
207 | result = 0; | 198 | result = 0; |
208 | break; | 199 | break; |
209 | } | 200 | } |
210 | } | 201 | } |
211 | } | 202 | } |
212 | else /* Everything is fine. */ | 203 | else /* Everything is fine. */ |
213 | result = 1; | 204 | result = 1; |
214 | 205 | ||
@@ -260,319 +251,327 @@ _impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe) | |||
260 | 251 | ||
261 | /* Create some pipes. */ | 252 | /* Create some pipes. */ |
262 | if (ok) | 253 | if (ok) |
263 | { | 254 | { |
264 | E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok) | 255 | E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok) |
265 | { | 256 | { |
266 | } | 257 | } |
267 | } | 258 | } |
268 | if (ok && (flags & ECORE_EXE_PIPE_ERROR)) | 259 | if (ok && (flags & ECORE_EXE_PIPE_ERROR)) |
269 | { | 260 | { |
270 | E_IF_NO_ERRNO_NOLOOP(result, pipe(errorPipe), ok) | 261 | E_IF_NO_ERRNO_NOLOOP(result, pipe(errorPipe), ok) |
271 | { | 262 | { |
272 | exe->child_fd_error = errorPipe[0]; | 263 | exe->child_fd_error = errorPipe[0]; |
273 | exe->child_fd_error_x = errorPipe[1]; | 264 | exe->child_fd_error_x = errorPipe[1]; |
274 | } | 265 | } |
275 | } | 266 | } |
276 | if (ok && (flags & ECORE_EXE_PIPE_READ)) | 267 | if (ok && (flags & ECORE_EXE_PIPE_READ)) |
277 | { | 268 | { |
278 | E_IF_NO_ERRNO_NOLOOP(result, pipe(readPipe), ok) | 269 | E_IF_NO_ERRNO_NOLOOP(result, pipe(readPipe), ok) |
279 | { | 270 | { |
280 | exe->child_fd_read = readPipe[0]; | 271 | exe->child_fd_read = readPipe[0]; |
281 | exe->child_fd_read_x = readPipe[1]; | 272 | exe->child_fd_read_x = readPipe[1]; |
282 | } | 273 | } |
283 | } | 274 | } |
284 | if (ok && (flags & ECORE_EXE_PIPE_WRITE)) | 275 | if (ok && (flags & ECORE_EXE_PIPE_WRITE)) |
285 | { | 276 | { |
286 | E_IF_NO_ERRNO_NOLOOP(result, pipe(writePipe), ok) | 277 | E_IF_NO_ERRNO_NOLOOP(result, pipe(writePipe), ok) |
287 | { | 278 | { |
288 | exe->child_fd_write = writePipe[1]; | 279 | exe->child_fd_write = writePipe[1]; |
289 | exe->child_fd_write_x = writePipe[0]; | 280 | exe->child_fd_write_x = writePipe[0]; |
290 | } | 281 | } |
291 | } | 282 | } |
292 | if (ok) | 283 | if (ok) |
293 | { | 284 | { |
294 | pid_t pid = 0; | 285 | pid_t pid = 0; |
295 | volatile int vfork_exec_errno = 0; | 286 | volatile int vfork_exec_errno = 0; |
296 | 287 | ||
297 | /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */ | 288 | /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */ |
298 | /* signal(SIGPIPE, SIG_IGN); We only want EPIPE on errors */ | 289 | /* signal(SIGPIPE, SIG_IGN); We only want EPIPE on errors */ |
299 | pid = fork(); | 290 | pid = fork(); |
300 | 291 | ||
301 | if (pid == -1) | 292 | if (pid == -1) |
302 | { | 293 | { |
303 | ERR("Failed to fork process"); | 294 | ERR("Failed to fork process"); |
304 | pid = 0; | 295 | pid = 0; |
305 | } | 296 | } |
306 | else if (pid == 0) /* child */ | 297 | else if (pid == 0) /* child */ |
307 | { | 298 | { |
308 | #ifdef HAVE_SYSTEMD | 299 | #ifdef HAVE_SYSTEMD |
309 | unsetenv("NOTIFY_SOCKET"); | 300 | unsetenv("NOTIFY_SOCKET"); |
310 | #endif | 301 | #endif |
311 | if (run_pri != ECORE_EXE_PRIORITY_INHERIT) | 302 | if (run_pri != ECORE_EXE_PRIORITY_INHERIT) |
312 | { | 303 | { |
313 | #ifdef PRIO_PROCESS | 304 | #ifdef PRIO_PROCESS |
314 | if ((run_pri >= -20) && (run_pri <= 19)) | 305 | if ((run_pri >= -20) && (run_pri <= 19)) |
315 | setpriority(PRIO_PROCESS, 0, run_pri); | 306 | setpriority(PRIO_PROCESS, 0, run_pri); |
316 | #else | 307 | #else |
317 | #warning "Your OS/libc does not provide PRIO_PROCESS (and possibly setpriority())" | 308 | #warning "Your OS/libc does not provide PRIO_PROCESS (and possibly setpriority())" |
318 | #warning "This is a POSIX-1.2001 standard and it is highly encouraged that you" | 309 | #warning "This is a POSIX-1.2001 standard and it is highly encouraged that you" |
319 | #warning "Have support for this" | 310 | #warning "Have support for this" |
320 | #endif | 311 | #endif |
321 | } | 312 | } |
322 | if (ok && (flags & ECORE_EXE_ISOLATE_IO)) | 313 | if (ok && (flags & ECORE_EXE_ISOLATE_IO)) |
323 | { | 314 | { |
324 | int devnull; | 315 | int devnull; |
325 | 316 | ||
326 | /* we want to isolatie the stdin/out/err of the process so | 317 | /* we want to isolatie the stdin/out/err of the process so |
327 | * it can't share those of the parent, so close and replace with | 318 | * it can't share those of the parent, so close and replace with |
328 | * /dev/null */ | 319 | * /dev/null */ |
329 | devnull = open("/dev/null", O_RDONLY); | 320 | devnull = open("/dev/null", O_RDONLY); |
330 | if (devnull >= 0) | 321 | if (devnull >= 0) |
331 | { | 322 | { |
332 | E_NO_ERRNO(result, close(STDIN_FILENO), ok); | 323 | E_NO_ERRNO(result, close(STDIN_FILENO), ok); |
333 | E_NO_ERRNO(result, dup2(devnull, STDIN_FILENO), ok); | 324 | E_NO_ERRNO(result, dup2(devnull, STDIN_FILENO), ok); |
334 | E_NO_ERRNO(result, close(devnull), ok); | 325 | E_NO_ERRNO(result, close(devnull), ok); |
335 | } | 326 | } |
336 | 327 | ||
337 | devnull = open("/dev/null", O_WRONLY); | 328 | devnull = open("/dev/null", O_WRONLY); |
338 | if (devnull >= 0) | 329 | if (devnull >= 0) |
339 | { | 330 | { |
340 | E_NO_ERRNO(result, close(STDOUT_FILENO), ok); | 331 | E_NO_ERRNO(result, close(STDOUT_FILENO), ok); |
341 | E_NO_ERRNO(result, dup2(devnull, STDOUT_FILENO), ok); | 332 | E_NO_ERRNO(result, dup2(devnull, STDOUT_FILENO), ok); |
342 | E_NO_ERRNO(result, close(devnull), ok); | 333 | E_NO_ERRNO(result, close(devnull), ok); |
343 | } | 334 | } |
344 | 335 | ||
345 | devnull = open("/dev/null", O_WRONLY); | 336 | devnull = open("/dev/null", O_WRONLY); |
346 | if (devnull >= 0) | 337 | if (devnull >= 0) |
347 | { | 338 | { |
348 | E_NO_ERRNO(result, close(STDERR_FILENO), ok); | 339 | E_NO_ERRNO(result, close(STDERR_FILENO), ok); |
349 | E_NO_ERRNO(result, dup2(devnull, STDERR_FILENO), ok); | 340 | E_NO_ERRNO(result, dup2(devnull, STDERR_FILENO), ok); |
350 | E_NO_ERRNO(result, close(devnull), ok); | 341 | E_NO_ERRNO(result, close(devnull), ok); |
351 | } | 342 | } |
352 | } | 343 | } |
353 | else | 344 | else |
354 | { | 345 | { |
355 | /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the | 346 | /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the |
356 | * second pipe if it's open. On the other hand, there was the | 347 | * second pipe if it's open. On the other hand, there was the |
357 | * Great FD Leak Scare of '06, so let's be paranoid. */ | 348 | * Great FD Leak Scare of '06, so let's be paranoid. */ |
358 | if (ok && (flags & ECORE_EXE_PIPE_ERROR)) | 349 | if (ok && (flags & ECORE_EXE_PIPE_ERROR)) |
359 | { | 350 | { |
360 | E_NO_ERRNO(result, close(STDERR_FILENO), ok); | 351 | E_NO_ERRNO(result, close(STDERR_FILENO), ok); |
361 | E_NO_ERRNO(result, dup2(errorPipe[1], STDERR_FILENO), ok); | 352 | E_NO_ERRNO(result, dup2(errorPipe[1], STDERR_FILENO), ok); |
362 | } | 353 | } |
363 | if (ok && (flags & ECORE_EXE_PIPE_READ)) | 354 | if (ok && (flags & ECORE_EXE_PIPE_READ)) |
364 | { | 355 | { |
365 | E_NO_ERRNO(result, close(STDOUT_FILENO), ok); | 356 | E_NO_ERRNO(result, close(STDOUT_FILENO), ok); |
366 | E_NO_ERRNO(result, dup2(readPipe[1], STDOUT_FILENO), ok); | 357 | E_NO_ERRNO(result, dup2(readPipe[1], STDOUT_FILENO), ok); |
367 | } | 358 | } |
368 | if (ok && (flags & ECORE_EXE_PIPE_WRITE)) | 359 | if (ok && (flags & ECORE_EXE_PIPE_WRITE)) |
369 | { | 360 | { |
370 | E_NO_ERRNO(result, close(STDIN_FILENO), ok); | 361 | E_NO_ERRNO(result, close(STDIN_FILENO), ok); |
371 | E_NO_ERRNO(result, dup2(writePipe[0], STDIN_FILENO), ok); | 362 | E_NO_ERRNO(result, dup2(writePipe[0], STDIN_FILENO), ok); |
372 | } | 363 | } |
373 | } | 364 | } |
374 | |||
375 | if (ok) | ||
376 | { | ||
377 | /* Setup the status pipe. */ | ||
378 | E_NO_ERRNO(result, close(statusPipe[0]), ok); | ||
379 | E_IF_NO_ERRNO(result, eina_file_close_on_exec(statusPipe[1], EINA_TRUE), ok) /* close on exec shows success */ | ||
380 | { | ||
381 | /* Run the actual command. */ | ||
382 | _ecore_exe_exec_it(exe_cmd, flags); /* no return */ | ||
383 | } | ||
384 | } | ||
385 | |||
386 | /* Something went 'orribly wrong. */ | ||
387 | vfork_exec_errno = errno; | ||
388 | |||
389 | /* Close the pipes. */ | ||
390 | if (flags & ECORE_EXE_PIPE_ERROR) | ||
391 | E_NO_ERRNO(result, close(errorPipe[1]), ok); | ||
392 | if (flags & ECORE_EXE_PIPE_READ) | ||
393 | E_NO_ERRNO(result, close(readPipe[1]), ok); | ||
394 | if (flags & ECORE_EXE_PIPE_WRITE) | ||
395 | E_NO_ERRNO(result, close(writePipe[0]), ok); | ||
396 | E_NO_ERRNO(result, close(statusPipe[1]), ok); | ||
397 | |||
398 | _exit(-1); | ||
399 | } | ||
400 | else /* parent */ | ||
401 | { | ||
402 | /* Close the unused pipes. */ | ||
403 | E_NO_ERRNO(result, close(statusPipe[1]), ok); | ||
404 | |||
405 | /* FIXME: after having a good look at the current e fd | ||
406 | * handling, investigate fcntl(dataPipe[x], F_SETSIG, ...) */ | ||
407 | /* FIXME: above F_SETSIG etc. - this is async SIGIO based IO | ||
408 | * which is also linux specific so we probably don't want to | ||
409 | * do this as long as select() is working fine. the only time | ||
410 | * we really want to think of SIGIO async IO is when it all | ||
411 | * actually works basically everywhere and we can turn all | ||
412 | * IO into DMA async activities (i.e. you do a read() then | ||
413 | * the read is complete not on return but when you get a | ||
414 | * SIGIO - the read() just starts the transfer and it is | ||
415 | * completed in the background by DMA (or whatever mechanism | ||
416 | * the kernel choses)) */ | ||
417 | |||
418 | /* Wait for it to start executing. */ | ||
419 | /* FIXME: this doesn't seem very nice - we sit and block | ||
420 | * waiting on a child process... even though it's just | ||
421 | * the segment between the fork() and the exec) it just feels | ||
422 | * wrong */ | ||
423 | for (;; ) | ||
424 | { | ||
425 | char buf; | ||
426 | |||
427 | E_NO_ERRNO(result, read(statusPipe[0], &buf, 1), ok); | ||
428 | if (result == 0) | ||
429 | { | ||
430 | if (vfork_exec_errno != 0) | ||
431 | { | ||
432 | n = vfork_exec_errno; | ||
433 | ERR("Could not start \"%s\"", exe_cmd); | ||
434 | pid = 0; | ||
435 | } | ||
436 | break; | ||
437 | } | ||
438 | } | ||
439 | 365 | ||
440 | /* Close the status pipe. */ | 366 | if (ok) |
367 | { | ||
368 | /* Setup the status pipe. */ | ||
441 | E_NO_ERRNO(result, close(statusPipe[0]), ok); | 369 | E_NO_ERRNO(result, close(statusPipe[0]), ok); |
370 | E_IF_NO_ERRNO(result, eina_file_close_on_exec(statusPipe[1], EINA_TRUE), ok) /* close on exec shows success */ | ||
371 | { | ||
372 | /* Run the actual command. */ | ||
373 | _ecore_exe_exec_it(exe_cmd, flags); /* no return */ | ||
374 | } | ||
375 | } | ||
376 | |||
377 | /* Something went 'orribly wrong. */ | ||
378 | vfork_exec_errno = errno; | ||
379 | |||
380 | /* Close the pipes. */ | ||
381 | if (flags & ECORE_EXE_PIPE_ERROR) | ||
382 | E_NO_ERRNO(result, close(errorPipe[1]), ok); | ||
383 | if (flags & ECORE_EXE_PIPE_READ) | ||
384 | E_NO_ERRNO(result, close(readPipe[1]), ok); | ||
385 | if (flags & ECORE_EXE_PIPE_WRITE) | ||
386 | E_NO_ERRNO(result, close(writePipe[0]), ok); | ||
387 | E_NO_ERRNO(result, close(statusPipe[1]), ok); | ||
388 | |||
389 | _exit(-1); | ||
390 | } | ||
391 | else /* parent */ | ||
392 | { | ||
393 | /* Close the unused pipes. */ | ||
394 | E_NO_ERRNO(result, close(statusPipe[1]), ok); | ||
395 | |||
396 | /* FIXME: after having a good look at the current e fd | ||
397 | * handling, investigate fcntl(dataPipe[x], F_SETSIG, ...) */ | ||
398 | /* FIXME: above F_SETSIG etc. - this is async SIGIO based IO | ||
399 | * which is also linux specific so we probably don't want to | ||
400 | * do this as long as select() is working fine. the only time | ||
401 | * we really want to think of SIGIO async IO is when it all | ||
402 | * actually works basically everywhere and we can turn all | ||
403 | * IO into DMA async activities (i.e. you do a read() then | ||
404 | * the read is complete not on return but when you get a | ||
405 | * SIGIO - the read() just starts the transfer and it is | ||
406 | * completed in the background by DMA (or whatever mechanism | ||
407 | * the kernel choses)) */ | ||
408 | |||
409 | /* Wait for it to start executing. */ | ||
410 | /* FIXME: this doesn't seem very nice - we sit and block | ||
411 | * waiting on a child process... even though it's just | ||
412 | * the segment between the fork() and the exec) it just feels | ||
413 | * wrong */ | ||
414 | for (;; ) | ||
415 | { | ||
416 | char buf; | ||
417 | |||
418 | E_NO_ERRNO(result, read(statusPipe[0], &buf, 1), ok); | ||
419 | if (result == 0) | ||
420 | { | ||
421 | if (vfork_exec_errno != 0) | ||
422 | { | ||
423 | n = vfork_exec_errno; | ||
424 | ERR("Could not start \"%s\"", exe_cmd); | ||
425 | pid = 0; | ||
426 | } | ||
427 | break; | ||
428 | } | ||
442 | } | 429 | } |
443 | 430 | ||
444 | if (pid) | 431 | /* Close the status pipe. */ |
432 | E_NO_ERRNO(result, close(statusPipe[0]), ok); | ||
433 | } | ||
434 | |||
435 | if (pid) | ||
436 | { | ||
437 | /* Setup the exe structure. */ | ||
438 | exe->start_bytes = -1; | ||
439 | exe->end_bytes = -1; | ||
440 | exe->start_lines = -1; | ||
441 | exe->end_lines = -1; | ||
442 | exe->pid = pid; | ||
443 | exe->flags = flags; | ||
444 | if (exe->cmd) | ||
445 | { | 445 | { |
446 | /* Setup the exe structure. */ | 446 | if (flags & ECORE_EXE_PIPE_ERROR) /* Setup the error stuff. */ |
447 | exe->start_bytes = -1; | 447 | { |
448 | exe->end_bytes = -1; | 448 | E_IF_NO_ERRNO(result, |
449 | exe->start_lines = -1; | 449 | fcntl(exe->child_fd_error, F_SETFL, |
450 | exe->end_lines = -1; | 450 | O_NONBLOCK), ok) { |
451 | exe->pid = pid; | 451 | } |
452 | exe->flags = flags; | 452 | E_IF_NO_ERRNO(result, |
453 | if (exe->cmd) | 453 | eina_file_close_on_exec(exe->child_fd_error, EINA_TRUE), |
454 | { | 454 | ok) { |
455 | if (flags & ECORE_EXE_PIPE_ERROR) /* Setup the error stuff. */ | 455 | } |
456 | { | 456 | E_IF_NO_ERRNO(result, |
457 | E_IF_NO_ERRNO(result, | 457 | eina_file_close_on_exec(exe->child_fd_error_x, EINA_TRUE), |
458 | fcntl(exe->child_fd_error, F_SETFL, | 458 | ok) { |
459 | O_NONBLOCK), ok) { | 459 | } |
460 | } | 460 | { |
461 | E_IF_NO_ERRNO(result, | 461 | // XXX: eoify ecore fd handlers |
462 | eina_file_close_on_exec(exe->child_fd_error, EINA_TRUE), | 462 | exe->error_fd_handler = |
463 | ok) { | 463 | ecore_main_fd_handler_add(exe->child_fd_error, |
464 | } | 464 | ECORE_FD_READ, |
465 | E_IF_NO_ERRNO(result, | 465 | _ecore_exe_data_error_handler, |
466 | eina_file_close_on_exec(exe->child_fd_error_x, EINA_TRUE), | 466 | obj, NULL, NULL); |
467 | ok) { | 467 | if (!exe->error_fd_handler) |
468 | } | 468 | ok = 0; |
469 | { | 469 | } |
470 | exe->error_fd_handler = | 470 | } |
471 | ecore_main_fd_handler_add(exe->child_fd_error, | 471 | if (ok && (flags & ECORE_EXE_PIPE_READ)) /* Setup the read stuff. */ |
472 | ECORE_FD_READ, | 472 | { |
473 | _ecore_exe_data_error_handler, | 473 | E_IF_NO_ERRNO(result, |
474 | obj, NULL, NULL); | 474 | fcntl(exe->child_fd_read, F_SETFL, |
475 | if (!exe->error_fd_handler) | 475 | O_NONBLOCK), ok) { |
476 | ok = 0; | 476 | } |
477 | } | 477 | E_IF_NO_ERRNO(result, |
478 | } | 478 | eina_file_close_on_exec(exe->child_fd_read, EINA_TRUE), |
479 | if (ok && (flags & ECORE_EXE_PIPE_READ)) /* Setup the read stuff. */ | 479 | ok) { |
480 | { | 480 | } |
481 | E_IF_NO_ERRNO(result, | 481 | E_IF_NO_ERRNO(result, |
482 | fcntl(exe->child_fd_read, F_SETFL, | 482 | eina_file_close_on_exec(exe->child_fd_read_x, EINA_TRUE), |
483 | O_NONBLOCK), ok) { | 483 | ok) { |
484 | } | 484 | } |
485 | E_IF_NO_ERRNO(result, | 485 | { |
486 | eina_file_close_on_exec(exe->child_fd_read, EINA_TRUE), | 486 | // XXX: eoify ecore fd handlers |
487 | ok) { | 487 | exe->read_fd_handler = |
488 | } | 488 | ecore_main_fd_handler_add(exe->child_fd_read, |
489 | E_IF_NO_ERRNO(result, | 489 | ECORE_FD_READ, |
490 | eina_file_close_on_exec(exe->child_fd_read_x, EINA_TRUE), | 490 | _ecore_exe_data_read_handler, |
491 | ok) { | 491 | obj, NULL, NULL); |
492 | } | 492 | if (!exe->read_fd_handler) |
493 | { | 493 | ok = 0; |
494 | exe->read_fd_handler = | 494 | } |
495 | ecore_main_fd_handler_add(exe->child_fd_read, | 495 | } |
496 | ECORE_FD_READ, | 496 | if (ok && (flags & ECORE_EXE_PIPE_WRITE)) /* Setup the write stuff. */ |
497 | _ecore_exe_data_read_handler, | 497 | { |
498 | obj, NULL, NULL); | 498 | E_IF_NO_ERRNO(result, |
499 | if (!exe->read_fd_handler) | 499 | fcntl(exe->child_fd_write, F_SETFL, |
500 | ok = 0; | 500 | O_NONBLOCK), ok) { |
501 | } | 501 | } |
502 | } | 502 | E_IF_NO_ERRNO(result, |
503 | if (ok && (flags & ECORE_EXE_PIPE_WRITE)) /* Setup the write stuff. */ | 503 | eina_file_close_on_exec(exe->child_fd_write, EINA_TRUE), |
504 | { | 504 | ok) { |
505 | E_IF_NO_ERRNO(result, | 505 | } |
506 | fcntl(exe->child_fd_write, F_SETFL, | 506 | E_IF_NO_ERRNO(result, |
507 | O_NONBLOCK), ok) { | 507 | eina_file_close_on_exec(exe->child_fd_write_x, EINA_TRUE), |
508 | } | 508 | ok) { |
509 | E_IF_NO_ERRNO(result, | 509 | } |
510 | eina_file_close_on_exec(exe->child_fd_write, EINA_TRUE), | 510 | { |
511 | ok) { | 511 | // XXX: eoify ecore fd handlers |
512 | } | 512 | exe->write_fd_handler = |
513 | E_IF_NO_ERRNO(result, | 513 | ecore_main_fd_handler_add(exe->child_fd_write, |
514 | eina_file_close_on_exec(exe->child_fd_write_x, EINA_TRUE), | 514 | ECORE_FD_WRITE, |
515 | ok) { | 515 | _ecore_exe_data_write_handler, |
516 | } | 516 | obj, NULL, NULL); |
517 | { | 517 | // XXX: eoify ecore fd handlers |
518 | exe->write_fd_handler = | 518 | if (exe->write_fd_handler) |
519 | ecore_main_fd_handler_add(exe->child_fd_write, | 519 | ecore_main_fd_handler_active_set(exe->write_fd_handler, 0); /* Nothing to write to start with. */ |
520 | ECORE_FD_WRITE, | 520 | else |
521 | _ecore_exe_data_write_handler, | 521 | ok = 0; |
522 | obj, NULL, NULL); | 522 | } |
523 | if (exe->write_fd_handler) | 523 | } |
524 | ecore_main_fd_handler_active_set(exe->write_fd_handler, 0); /* Nothing to write to start with. */ | 524 | |
525 | else | 525 | exe->loop = efl_provider_find(obj, EFL_LOOP_CLASS); |
526 | ok = 0; | 526 | Efl_Loop_Data *loop = efl_data_scope_get(exe->loop, EFL_LOOP_CLASS); |
527 | } | 527 | if (loop) loop->exes = eina_list_append(loop->exes, obj); |
528 | } | 528 | n = 0; |
529 | |||
530 | _ecore_exe_exes = eina_list_append(_ecore_exe_exes, obj); | ||
531 | n = 0; | ||
532 | } | ||
533 | else | ||
534 | ok = 0; | ||
535 | } | 529 | } |
536 | else | 530 | else |
537 | ok = 0; | 531 | ok = 0; |
538 | } | 532 | } |
533 | else | ||
534 | ok = 0; | ||
535 | } | ||
539 | 536 | ||
540 | if (!ok) /* Something went wrong, so pull down everything. */ | 537 | if (!ok) /* Something went wrong, so pull down everything. */ |
541 | { | 538 | { |
542 | if (exe->pid) ecore_exe_terminate(obj); | 539 | // XXX: eoify terminate method |
543 | obj = NULL; | 540 | if (exe->pid) ecore_exe_terminate(obj); |
544 | } | 541 | obj = NULL; |
542 | } | ||
545 | else | 543 | else |
546 | { | 544 | { |
547 | Ecore_Exe_Event_Add *e; | 545 | Ecore_Exe_Event_Add *e; |
548 | 546 | ||
549 | e = _ecore_exe_event_add_new(); | 547 | e = _ecore_exe_event_add_new(); |
550 | if (e) | 548 | if (e) |
551 | { | 549 | { |
552 | e->exe = obj; | 550 | e->exe = obj; |
553 | /* Send the event. */ | 551 | // XXX: eoify ecore_event_add |
554 | ecore_event_add(ECORE_EXE_EVENT_ADD, e, | 552 | /* Send the event. */ |
555 | _ecore_exe_event_add_free, NULL); | 553 | ecore_event_add(ECORE_EXE_EVENT_ADD, e, |
556 | } | 554 | _ecore_exe_event_add_free, NULL); |
557 | /* INF("Running as %d for %s.\n", exe->pid, exe->cmd); */ | 555 | } |
558 | } | 556 | /* INF("Running as %d for %s.\n", exe->pid, exe->cmd); */ |
557 | } | ||
559 | 558 | ||
560 | errno = n; | 559 | errno = n; |
561 | return obj; | 560 | return obj; |
562 | } | 561 | } |
563 | 562 | ||
564 | Eina_Bool | 563 | Eina_Bool |
565 | _impl_ecore_exe_send(Ecore_Exe *obj EINA_UNUSED, | 564 | _impl_ecore_exe_send(Ecore_Exe *obj EINA_UNUSED, |
566 | Ecore_Exe_Data *exe, | 565 | Ecore_Exe_Data *exe, |
567 | const void *data, | 566 | const void *data, |
568 | int size) | 567 | int size) |
569 | { | 568 | { |
570 | void *buf; | 569 | void *buf; |
571 | 570 | ||
572 | if (exe->child_fd_write == -1) | 571 | if (exe->child_fd_write == -1) |
573 | { | 572 | { |
574 | ERR("Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! " | 573 | ERR("Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! " |
575 | "Cannot send %d bytes from %p", exe, size, data); | 574 | "Cannot send %d bytes from %p", exe, size, data); |
576 | return EINA_FALSE; | 575 | return EINA_FALSE; |
577 | } | 576 | } |
578 | 577 | ||
@@ -583,19 +582,20 @@ _impl_ecore_exe_send(Ecore_Exe *obj EINA_UNUSED, | |||
583 | memcpy((char *)exe->write_data_buf + exe->write_data_size, data, size); | 582 | memcpy((char *)exe->write_data_buf + exe->write_data_size, data, size); |
584 | exe->write_data_size += size; | 583 | exe->write_data_size += size; |
585 | 584 | ||
585 | // XXX: eoify ecore_fd_handlers | ||
586 | if (exe->write_fd_handler) | 586 | if (exe->write_fd_handler) |
587 | ecore_main_fd_handler_active_set(exe->write_fd_handler, ECORE_FD_WRITE); | 587 | ecore_main_fd_handler_active_set(exe->write_fd_handler, ECORE_FD_WRITE); |
588 | 588 | ||
589 | return EINA_TRUE; | 589 | return EINA_TRUE; |
590 | } | 590 | } |
591 | 591 | ||
592 | void | 592 | void |
593 | _impl_ecore_exe_auto_limits_set(Ecore_Exe *obj EINA_UNUSED, | 593 | _impl_ecore_exe_auto_limits_set(Ecore_Exe *obj EINA_UNUSED, |
594 | Ecore_Exe_Data *exe, | 594 | Ecore_Exe_Data *exe, |
595 | int start_bytes, | 595 | int start_bytes, |
596 | int end_bytes, | 596 | int end_bytes, |
597 | int start_lines, | 597 | int start_lines, |
598 | int end_lines) | 598 | int end_lines) |
599 | { | 599 | { |
600 | /* FIXME: sanitize the input. */ | 600 | /* FIXME: sanitize the input. */ |
601 | exe->start_bytes = start_bytes; | 601 | exe->start_bytes = start_bytes; |
@@ -644,9 +644,9 @@ _impl_ecore_exe_auto_limits_set(Ecore_Exe *obj EINA_UNUSED, | |||
644 | } | 644 | } |
645 | 645 | ||
646 | Ecore_Exe_Event_Data * | 646 | Ecore_Exe_Event_Data * |
647 | _impl_ecore_exe_event_data_get(Ecore_Exe *obj, | 647 | _impl_ecore_exe_event_data_get(Ecore_Exe *obj, |
648 | Ecore_Exe_Data *exe, | 648 | Ecore_Exe_Data *exe, |
649 | Ecore_Exe_Flags flags) | 649 | Ecore_Exe_Flags flags) |
650 | { | 650 | { |
651 | Ecore_Exe_Event_Data *e = NULL; | 651 | Ecore_Exe_Event_Data *e = NULL; |
652 | int is_buffered = 0; | 652 | int is_buffered = 0; |
@@ -655,130 +655,130 @@ _impl_ecore_exe_event_data_get(Ecore_Exe *obj, | |||
655 | 655 | ||
656 | /* Sort out what sort of event we are. */ | 656 | /* Sort out what sort of event we are. */ |
657 | if (flags & ECORE_EXE_PIPE_READ) | 657 | if (flags & ECORE_EXE_PIPE_READ) |
658 | { | 658 | { |
659 | flags = ECORE_EXE_PIPE_READ; | 659 | flags = ECORE_EXE_PIPE_READ; |
660 | if (exe->flags & ECORE_EXE_PIPE_READ_LINE_BUFFERED) | 660 | if (exe->flags & ECORE_EXE_PIPE_READ_LINE_BUFFERED) |
661 | is_buffered = 1; | 661 | is_buffered = 1; |
662 | } | 662 | } |
663 | else | 663 | else |
664 | { | 664 | { |
665 | flags = ECORE_EXE_PIPE_ERROR; | 665 | flags = ECORE_EXE_PIPE_ERROR; |
666 | if (exe->flags & ECORE_EXE_PIPE_ERROR_LINE_BUFFERED) | 666 | if (exe->flags & ECORE_EXE_PIPE_ERROR_LINE_BUFFERED) |
667 | is_buffered = 1; | 667 | is_buffered = 1; |
668 | } | 668 | } |
669 | 669 | ||
670 | /* Get the data. */ | 670 | /* Get the data. */ |
671 | if (flags & ECORE_EXE_PIPE_READ) | 671 | if (flags & ECORE_EXE_PIPE_READ) |
672 | { | 672 | { |
673 | inbuf = exe->read_data_buf; | 673 | inbuf = exe->read_data_buf; |
674 | inbuf_num = exe->read_data_size; | 674 | inbuf_num = exe->read_data_size; |
675 | exe->read_data_buf = NULL; | 675 | exe->read_data_buf = NULL; |
676 | exe->read_data_size = 0; | 676 | exe->read_data_size = 0; |
677 | } | 677 | } |
678 | else | 678 | else |
679 | { | 679 | { |
680 | inbuf = exe->error_data_buf; | 680 | inbuf = exe->error_data_buf; |
681 | inbuf_num = exe->error_data_size; | 681 | inbuf_num = exe->error_data_size; |
682 | exe->error_data_buf = NULL; | 682 | exe->error_data_buf = NULL; |
683 | exe->error_data_size = 0; | 683 | exe->error_data_size = 0; |
684 | } | 684 | } |
685 | 685 | ||
686 | e = calloc(1, sizeof(Ecore_Exe_Event_Data)); | 686 | e = calloc(1, sizeof(Ecore_Exe_Event_Data)); |
687 | if (e) | 687 | if (e) |
688 | { | 688 | { |
689 | e->exe = obj; | 689 | e->exe = obj; |
690 | e->data = inbuf; | 690 | e->data = inbuf; |
691 | e->size = inbuf_num; | 691 | e->size = inbuf_num; |
692 | 692 | ||
693 | if (is_buffered) /* Deal with line buffering. */ | 693 | if (is_buffered) /* Deal with line buffering. */ |
694 | { | 694 | { |
695 | int max = 0; | 695 | int max = 0; |
696 | int count = 0; | 696 | int count = 0; |
697 | int i; | 697 | int i; |
698 | int last = 0; | 698 | int last = 0; |
699 | char *c; | 699 | char *c; |
700 | 700 | ||
701 | c = (char *)inbuf; | 701 | c = (char *)inbuf; |
702 | for (i = 0; i < inbuf_num; i++) /* Find the lines. */ | 702 | for (i = 0; i < inbuf_num; i++) /* Find the lines. */ |
703 | { | 703 | { |
704 | if (inbuf[i] == '\n') | 704 | if (inbuf[i] == '\n') |
705 | { | 705 | { |
706 | if (count >= max) | 706 | if (count >= max) |
707 | { | ||
708 | Ecore_Exe_Event_Data_Line *lines; | ||
709 | |||
710 | /* In testing, the lines seem to arrive in batches of 500 to 1000 lines at most, roughly speaking. */ | ||
711 | max += 10; /* FIXME: Maybe keep track of the largest number of lines ever sent, and add half that many instead of 10. */ | ||
712 | lines = realloc(e->lines, sizeof(Ecore_Exe_Event_Data_Line) * (max + 1)); /* Allow room for the NULL termination. */ | ||
713 | if (!lines) | ||
714 | { | ||
715 | ERR("Out of memory adding exe data lines to event"); | ||
716 | break; | ||
717 | } | ||
718 | e->lines = lines; | ||
719 | } | ||
720 | /* raster said to leave the line endings as line endings, however - | ||
721 | * This is line buffered mode, we are not dealing with binary here, but lines. | ||
722 | * If we are not dealing with binary, we must be dealing with ASCII, unicode, or some other text format. | ||
723 | * Thus the user is most likely gonna deal with this text as strings. | ||
724 | * Thus the user is most likely gonna pass this data to str functions. | ||
725 | * rasters way - the endings are always gonna be '\n'; onefangs way - they will always be '\0' | ||
726 | * We are handing them the string length as a convenience. | ||
727 | * Thus if they really want it in raw format, they can e->lines[i].line[e->lines[i].size - 1] = '\n'; easily enough. | ||
728 | * In the default case, we can do this conversion quicker than the user can, as we already have the index and pointer. | ||
729 | * Let's make it easy on them to use these as standard C strings. | ||
730 | * | ||
731 | * onefang is proud to announce that he has just set a new personal record for the | ||
732 | * most over documentation of a simple assignment statement. B-) | ||
733 | */ | ||
734 | inbuf[i] = '\0'; | ||
735 | e->lines[count].line = c; | ||
736 | e->lines[count].size = i - last; | ||
737 | last = i + 1; | ||
738 | c = (char *)&inbuf[last]; | ||
739 | count++; | ||
740 | } | ||
741 | } | ||
742 | if (i > last) /* Partial line left over, save it for next time. */ | ||
743 | { | ||
744 | if (count != 0) e->size = last; | ||
745 | if (flags & ECORE_EXE_PIPE_READ) | ||
746 | { | ||
747 | exe->read_data_size = i - last; | ||
748 | exe->read_data_buf = malloc(exe->read_data_size); | ||
749 | if (exe->read_data_buf) | ||
750 | memcpy(exe->read_data_buf, c, exe->read_data_size); | ||
751 | else | ||
752 | { | ||
753 | exe->read_data_size = 0; | ||
754 | ERR("Out of memory in allocating exe pipe data"); | ||
755 | } | ||
756 | } | ||
757 | else | ||
758 | { | ||
759 | exe->error_data_size = i - last; | ||
760 | exe->error_data_buf = malloc(exe->error_data_size); | ||
761 | if (exe->error_data_buf) | ||
762 | memcpy(exe->error_data_buf, c, exe->error_data_size); | ||
763 | else | ||
764 | { | ||
765 | exe->error_data_size = 0; | ||
766 | ERR("Out of memory in allocating exe pipe data"); | ||
767 | } | ||
768 | } | ||
769 | } | ||
770 | if (count == 0) /* No lines to send, cancel the event. */ | ||
771 | { | ||
772 | _ecore_exe_event_exe_data_free(NULL, e); | ||
773 | e = NULL; | ||
774 | } | ||
775 | else /* NULL terminate the array, so that people know where the end is. */ | ||
776 | { | 707 | { |
777 | e->lines[count].line = NULL; | 708 | Ecore_Exe_Event_Data_Line *lines; |
778 | e->lines[count].size = 0; | 709 | |
710 | /* In testing, the lines seem to arrive in batches of 500 to 1000 lines at most, roughly speaking. */ | ||
711 | max += 10; /* FIXME: Maybe keep track of the largest number of lines ever sent, and add half that many instead of 10. */ | ||
712 | lines = realloc(e->lines, sizeof(Ecore_Exe_Event_Data_Line) * (max + 1)); /* Allow room for the NULL termination. */ | ||
713 | if (!lines) | ||
714 | { | ||
715 | ERR("Out of memory adding exe data lines to event"); | ||
716 | break; | ||
717 | } | ||
718 | e->lines = lines; | ||
779 | } | 719 | } |
780 | } | 720 | /* raster said to leave the line endings as line endings, however - |
781 | } | 721 | * This is line buffered mode, we are not dealing with binary here, but lines. |
722 | * If we are not dealing with binary, we must be dealing with ASCII, unicode, or some other text format. | ||
723 | * Thus the user is most likely gonna deal with this text as strings. | ||
724 | * Thus the user is most likely gonna pass this data to str functions. | ||
725 | * rasters way - the endings are always gonna be '\n'; onefangs way - they will always be '\0' | ||
726 | * We are handing them the string length as a convenience. | ||
727 | * Thus if they really want it in raw format, they can e->lines[i].line[e->lines[i].size - 1] = '\n'; easily enough. | ||
728 | * In the default case, we can do this conversion quicker than the user can, as we already have the index and pointer. | ||
729 | * Let's make it easy on them to use these as standard C strings. | ||
730 | * | ||
731 | * onefang is proud to announce that he has just set a new personal record for the | ||
732 | * most over documentation of a simple assignment statement. B-) | ||
733 | */ | ||
734 | inbuf[i] = '\0'; | ||
735 | e->lines[count].line = c; | ||
736 | e->lines[count].size = i - last; | ||
737 | last = i + 1; | ||
738 | c = (char *)&inbuf[last]; | ||
739 | count++; | ||
740 | } | ||
741 | } | ||
742 | if (i > last) /* Partial line left over, save it for next time. */ | ||
743 | { | ||
744 | if (count != 0) e->size = last; | ||
745 | if (flags & ECORE_EXE_PIPE_READ) | ||
746 | { | ||
747 | exe->read_data_size = i - last; | ||
748 | exe->read_data_buf = malloc(exe->read_data_size); | ||
749 | if (exe->read_data_buf) | ||
750 | memcpy(exe->read_data_buf, c, exe->read_data_size); | ||
751 | else | ||
752 | { | ||
753 | exe->read_data_size = 0; | ||
754 | ERR("Out of memory in allocating exe pipe data"); | ||
755 | } | ||
756 | } | ||
757 | else | ||
758 | { | ||
759 | exe->error_data_size = i - last; | ||
760 | exe->error_data_buf = malloc(exe->error_data_size); | ||
761 | if (exe->error_data_buf) | ||
762 | memcpy(exe->error_data_buf, c, exe->error_data_size); | ||
763 | else | ||
764 | { | ||
765 | exe->error_data_size = 0; | ||
766 | ERR("Out of memory in allocating exe pipe data"); | ||
767 | } | ||
768 | } | ||
769 | } | ||
770 | if (count == 0) /* No lines to send, cancel the event. */ | ||
771 | { | ||
772 | _ecore_exe_event_exe_data_free(NULL, e); | ||
773 | e = NULL; | ||
774 | } | ||
775 | else /* NULL terminate the array, so that people know where the end is. */ | ||
776 | { | ||
777 | e->lines[count].line = NULL; | ||
778 | e->lines[count].size = 0; | ||
779 | } | ||
780 | } | ||
781 | } | ||
782 | 782 | ||
783 | return e; | 783 | return e; |
784 | } | 784 | } |
@@ -795,20 +795,9 @@ _impl_ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe) | |||
795 | if (exe->pre_free_cb) | 795 | if (exe->pre_free_cb) |
796 | exe->pre_free_cb(data, obj); | 796 | exe->pre_free_cb(data, obj); |
797 | 797 | ||
798 | if (exe->doomsday_clock) | 798 | exe->doomsday_clock = NULL; |
799 | { | ||
800 | struct _ecore_exe_dead_exe *dead; | ||
801 | 799 | ||
802 | ecore_timer_del(exe->doomsday_clock); | 800 | // XXX: eoify ecore fd handlers |
803 | exe->doomsday_clock = NULL; | ||
804 | dead = exe->doomsday_clock_dead; | ||
805 | if (dead) | ||
806 | { | ||
807 | IF_FREE(dead->cmd); | ||
808 | free(dead); | ||
809 | exe->doomsday_clock_dead = NULL; | ||
810 | } | ||
811 | } | ||
812 | IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler); | 801 | IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler); |
813 | IF_FN_DEL(ecore_main_fd_handler_del, exe->read_fd_handler); | 802 | IF_FN_DEL(ecore_main_fd_handler_del, exe->read_fd_handler); |
814 | IF_FN_DEL(ecore_main_fd_handler_del, exe->error_fd_handler); | 803 | IF_FN_DEL(ecore_main_fd_handler_del, exe->error_fd_handler); |
@@ -829,7 +818,8 @@ _impl_ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe) | |||
829 | IF_FREE(exe->error_data_buf); | 818 | IF_FREE(exe->error_data_buf); |
830 | IF_FREE(exe->cmd); | 819 | IF_FREE(exe->cmd); |
831 | 820 | ||
832 | _ecore_exe_exes = eina_list_remove(_ecore_exe_exes, obj); | 821 | Efl_Loop_Data *loop = efl_data_scope_get(exe->loop, EFL_LOOP_CLASS); |
822 | if (loop) loop->exes = eina_list_remove(loop->exes, obj); | ||
833 | IF_FREE(exe->tag); | 823 | IF_FREE(exe->tag); |
834 | } | 824 | } |
835 | 825 | ||
@@ -870,25 +860,21 @@ _impl_ecore_exe_terminate(Ecore_Exe *obj, Ecore_Exe_Data *exe) | |||
870 | void | 860 | void |
871 | _impl_ecore_exe_kill(Ecore_Exe *obj EINA_UNUSED, Ecore_Exe_Data *exe) | 861 | _impl_ecore_exe_kill(Ecore_Exe *obj EINA_UNUSED, Ecore_Exe_Data *exe) |
872 | { | 862 | { |
873 | struct _ecore_exe_dead_exe *dead; | 863 | efl_del(exe->doomsday_clock); |
874 | dead = calloc(1, sizeof(struct _ecore_exe_dead_exe)); | 864 | exe->doomsday_clock = efl_add(EFL_LOOP_TIMER_CLASS, obj, |
875 | if (dead) | 865 | efl_event_callback_add(efl_added, |
876 | { | 866 | EFL_LOOP_TIMER_EVENT_TICK, |
877 | dead->pid = exe->pid; | 867 | _ecore_exe_make_sure_its_really_dead, |
878 | dead->cmd = strdup(exe->cmd); | 868 | obj), |
879 | IF_FN_DEL(ecore_timer_del, exe->doomsday_clock); | 869 | efl_loop_timer_interval_set(efl_added, 10.0)); |
880 | exe->doomsday_clock = | ||
881 | ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, dead); | ||
882 | } | ||
883 | |||
884 | INF("Sending KILL signal to %s (%d).", exe->cmd, exe->pid); | 870 | INF("Sending KILL signal to %s (%d).", exe->cmd, exe->pid); |
885 | kill(exe->pid, SIGKILL); | 871 | kill(exe->pid, SIGKILL); |
886 | } | 872 | } |
887 | 873 | ||
888 | void | 874 | void |
889 | _impl_ecore_exe_signal(Ecore_Exe *obj EINA_UNUSED, | 875 | _impl_ecore_exe_signal(Ecore_Exe *obj EINA_UNUSED, |
890 | Ecore_Exe_Data *exe, | 876 | Ecore_Exe_Data *exe, |
891 | int num) | 877 | int num) |
892 | { | 878 | { |
893 | if (num == 1) | 879 | if (num == 1) |
894 | kill(exe->pid, SIGUSR1); | 880 | kill(exe->pid, SIGUSR1); |
@@ -902,102 +888,41 @@ _impl_ecore_exe_hup(Ecore_Exe *obj EINA_UNUSED, Ecore_Exe_Data *exe) | |||
902 | kill(exe->pid, SIGHUP); | 888 | kill(exe->pid, SIGHUP); |
903 | } | 889 | } |
904 | 890 | ||
905 | static Ecore_Exe * | 891 | static void |
906 | _ecore_exe_is_it_alive(pid_t pid) | 892 | _ecore_exe_make_sure_its_dead(void *data, const Efl_Event *event EINA_UNUSED) |
907 | { | ||
908 | Ecore_Exe *exe = NULL; | ||
909 | |||
910 | /* FIXME: There is no nice, safe, OS independent way to tell if a | ||
911 | * particular PID is still alive. I have written code to do so | ||
912 | * for my urunlevel busybox applet (http://urunlevel.sourceforge.net/), | ||
913 | * but it's for linux only, and still not guaranteed. | ||
914 | * | ||
915 | * So for now, we just check that a valid Ecore_Exe structure | ||
916 | * exists for it. Even that is not a guarantee, as the structure | ||
917 | * can be freed without killing the process. | ||
918 | * | ||
919 | * I think we can safely put exe's into two categories, those users | ||
920 | * that care about the life of the exe, and the run and forget type. | ||
921 | * The run and forget type starts up the exe, then free's the | ||
922 | * Ecore_Exe structure straight away. They can never call any of | ||
923 | * the functions that can call this, so we don't worry about them. | ||
924 | * | ||
925 | * Those user's that care about the life of exe's will keep the | ||
926 | * Ecore_Exe structure around, terminate them eventually, or | ||
927 | * register for exit events. For these ones the assumption | ||
928 | * that valid Ecore_Exe struct == live exe is almost valid. | ||
929 | * | ||
930 | * I will probably copy my urunlevel code into here someday. | ||
931 | */ | ||
932 | exe = _ecore_exe_find(pid); | ||
933 | |||
934 | return exe; | ||
935 | } | ||
936 | |||
937 | static Eina_Bool | ||
938 | _ecore_exe_make_sure_its_dead(void *data) | ||
939 | { | 893 | { |
940 | struct _ecore_exe_dead_exe *dead; | 894 | Eo *exe_obj = data; |
941 | 895 | Ecore_Exe_Data *exe = efl_data_scope_get(exe_obj, MY_CLASS); | |
942 | dead = data; | 896 | if (exe) |
943 | if (dead) | ||
944 | { | 897 | { |
945 | Ecore_Exe *obj = NULL; | 898 | if (exe->cmd) |
946 | 899 | INF("Sending KILL signal to allegedly dead %s (%d).", exe->cmd, exe->pid); | |
947 | if ((obj = _ecore_exe_is_it_alive(dead->pid))) | ||
948 | { | ||
949 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | ||
950 | if (exe) | ||
951 | { | ||
952 | if (dead->cmd) | ||
953 | INF("Sending KILL signal to allegedly dead %s (%d).", | ||
954 | dead->cmd, dead->pid); | ||
955 | else | ||
956 | INF("Sending KILL signal to allegedly dead PID %d.", | ||
957 | dead->pid); | ||
958 | exe->doomsday_clock = | ||
959 | ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, | ||
960 | dead); | ||
961 | kill(dead->pid, SIGKILL); | ||
962 | } | ||
963 | } | ||
964 | else | 900 | else |
965 | { | 901 | INF("Sending KILL signal to allegedly dead PID %d.", exe->pid); |
966 | IF_FREE(dead->cmd); | 902 | exe->doomsday_clock = efl_add(EFL_LOOP_TIMER_CLASS, exe_obj, |
967 | free(dead); | 903 | efl_event_callback_add(efl_added, |
968 | } | 904 | EFL_LOOP_TIMER_EVENT_TICK, |
905 | _ecore_exe_make_sure_its_really_dead, | ||
906 | exe_obj), | ||
907 | efl_loop_timer_interval_set(efl_added, 10.0)); | ||
908 | kill(exe->pid, SIGKILL); | ||
969 | } | 909 | } |
970 | return ECORE_CALLBACK_CANCEL; | ||
971 | } | 910 | } |
972 | 911 | ||
973 | static Eina_Bool | 912 | static void |
974 | _ecore_exe_make_sure_its_really_dead(void *data) | 913 | _ecore_exe_make_sure_its_really_dead(void *data, const Efl_Event *event EINA_UNUSED) |
975 | { | 914 | { |
976 | struct _ecore_exe_dead_exe *dead; | 915 | Eo *exe_obj = data; |
977 | 916 | Ecore_Exe_Data *exe = efl_data_scope_get(exe_obj, MY_CLASS); | |
978 | dead = data; | 917 | if (exe) |
979 | if (dead) | ||
980 | { | 918 | { |
981 | Ecore_Exe *obj = NULL; | 919 | ERR("RUN! The zombie wants to eat your brains! And your CPU!"); |
982 | 920 | if (exe->cmd) | |
983 | if ((obj = _ecore_exe_is_it_alive(dead->pid))) | 921 | INF("%s (%d) is not really dead.", exe->cmd, exe->pid); |
984 | { | 922 | else |
985 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 923 | INF("PID %d is not really dead.", exe->pid); |
986 | 924 | exe->doomsday_clock = NULL; | |
987 | if (exe) | ||
988 | { | ||
989 | ERR("RUN! The zombie wants to eat your brains! And your CPU!"); | ||
990 | if (dead->cmd) | ||
991 | INF("%s (%d) is not really dead.", dead->cmd, dead->pid); | ||
992 | else | ||
993 | INF("PID %d is not really dead.", dead->pid); | ||
994 | exe->doomsday_clock = NULL; | ||
995 | } | ||
996 | IF_FREE(dead->cmd); | ||
997 | free(dead); | ||
998 | } | ||
999 | } | 925 | } |
1000 | return ECORE_CALLBACK_CANCEL; | ||
1001 | } | 926 | } |
1002 | 927 | ||
1003 | Ecore_Timer * | 928 | Ecore_Timer * |
@@ -1009,7 +934,7 @@ _ecore_exe_doomsday_clock_get(Ecore_Exe *obj) | |||
1009 | } | 934 | } |
1010 | 935 | ||
1011 | void | 936 | void |
1012 | _ecore_exe_doomsday_clock_set(Ecore_Exe *obj, | 937 | _ecore_exe_doomsday_clock_set(Ecore_Exe *obj, |
1013 | Ecore_Timer *dc) | 938 | Ecore_Timer *dc) |
1014 | { | 939 | { |
1015 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); | 940 | Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); |
@@ -1018,7 +943,7 @@ _ecore_exe_doomsday_clock_set(Ecore_Exe *obj, | |||
1018 | } | 943 | } |
1019 | 944 | ||
1020 | static inline void | 945 | static inline void |
1021 | _ecore_exe_exec_it(const char *exe_cmd, | 946 | _ecore_exe_exec_it(const char *exe_cmd, |
1022 | Ecore_Exe_Flags flags) | 947 | Ecore_Exe_Flags flags) |
1023 | { | 948 | { |
1024 | char use_sh = 1; | 949 | char use_sh = 1; |
@@ -1033,55 +958,55 @@ _ecore_exe_exec_it(const char *exe_cmd, | |||
1033 | * If we don't find them, we can call the exe directly. | 958 | * If we don't find them, we can call the exe directly. |
1034 | */ | 959 | */ |
1035 | if (!strpbrk(exe_cmd, "|&;<>()$`\\\"'*?#")) | 960 | if (!strpbrk(exe_cmd, "|&;<>()$`\\\"'*?#")) |
1036 | { | 961 | { |
1037 | char *token; | 962 | char *token; |
1038 | char pre_command = 1; | 963 | char pre_command = 1; |
1039 | int num_tokens = 0; | 964 | int num_tokens = 0; |
1040 | int len; | 965 | int len; |
1041 | 966 | ||
1042 | len = strlen(exe_cmd); | 967 | len = strlen(exe_cmd); |
1043 | buf = alloca(len + 1); | 968 | buf = alloca(len + 1); |
1044 | strcpy(buf, exe_cmd); | 969 | strcpy(buf, exe_cmd); |
1045 | buf[len] = 0; | 970 | buf[len] = 0; |
1046 | 971 | ||
1047 | token = strtok(buf, " \t\n\v"); | 972 | token = strtok(buf, " \t\n\v"); |
1048 | while (token) | 973 | while (token) |
1049 | { | 974 | { |
1050 | if (token[0] == '~') | 975 | if (token[0] == '~') |
1051 | break; | 976 | break; |
1052 | if (pre_command) | 977 | if (pre_command) |
1053 | { | 978 | { |
1054 | if (token[0] == '[') | 979 | if (token[0] == '[') |
1055 | break; | 980 | break; |
1056 | if (strchr(token, '=')) | 981 | if (strchr(token, '=')) |
1057 | break; | 982 | break; |
1058 | else | 983 | else |
1059 | pre_command = 0; | 984 | pre_command = 0; |
1060 | } | 985 | } |
1061 | num_tokens++; | 986 | num_tokens++; |
1062 | token = strtok(NULL, " \t\n\v"); | 987 | token = strtok(NULL, " \t\n\v"); |
1063 | } | 988 | } |
1064 | if ((!token) && (num_tokens)) | 989 | if ((!token) && (num_tokens)) |
1065 | { | 990 | { |
1066 | int i = 0; | 991 | int i = 0; |
1067 | 992 | ||
1068 | len = strlen(exe_cmd); | 993 | len = strlen(exe_cmd); |
1069 | buf = alloca(len + 1); | 994 | buf = alloca(len + 1); |
1070 | strcpy(buf, exe_cmd); | 995 | strcpy(buf, exe_cmd); |
1071 | buf[len] = 0; | 996 | buf[len] = 0; |
1072 | 997 | ||
1073 | token = strtok(buf, " \t\n\v"); | 998 | token = strtok(buf, " \t\n\v"); |
1074 | use_sh = 0; | 999 | use_sh = 0; |
1075 | args = alloca((num_tokens + 1) * sizeof(char *)); | 1000 | args = alloca((num_tokens + 1) * sizeof(char *)); |
1076 | for (i = 0; i < num_tokens; i++) | 1001 | for (i = 0; i < num_tokens; i++) |
1077 | { | 1002 | { |
1078 | if (token) | 1003 | if (token) |
1079 | args[i] = token; | 1004 | args[i] = token; |
1080 | token = strtok(NULL, " \t\n\v"); | 1005 | token = strtok(NULL, " \t\n\v"); |
1081 | } | 1006 | } |
1082 | args[num_tokens] = NULL; | 1007 | args[num_tokens] = NULL; |
1083 | } | 1008 | } |
1084 | } | 1009 | } |
1085 | 1010 | ||
1086 | #ifdef HAVE_PRCTL | 1011 | #ifdef HAVE_PRCTL |
1087 | if ((flags & ECORE_EXE_TERM_WITH_PARENT)) | 1012 | if ((flags & ECORE_EXE_TERM_WITH_PARENT)) |
@@ -1092,34 +1017,34 @@ _ecore_exe_exec_it(const char *exe_cmd, | |||
1092 | 1017 | ||
1093 | if (!(flags & ECORE_EXE_NOT_LEADER)) setsid(); | 1018 | if (!(flags & ECORE_EXE_NOT_LEADER)) setsid(); |
1094 | if ((flags & ECORE_EXE_USE_SH)) | 1019 | if ((flags & ECORE_EXE_USE_SH)) |
1095 | { | 1020 | { |
1096 | errno = 0; | 1021 | errno = 0; |
1097 | execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL); | 1022 | execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL); |
1098 | } | 1023 | } |
1099 | else if (use_sh) /* We have to use a shell to run this. */ | 1024 | else if (use_sh) /* We have to use a shell to run this. */ |
1100 | { | 1025 | { |
1101 | if (!shell) /* Find users preferred shell. */ | 1026 | if (!shell) /* Find users preferred shell. */ |
1102 | { | 1027 | { |
1103 | #if defined(HAVE_GETUID) && defined(HAVE_GETEUID) | 1028 | #if defined(HAVE_GETUID) && defined(HAVE_GETEUID) |
1104 | if (getuid() == geteuid()) | 1029 | if (getuid() == geteuid()) |
1105 | #endif | 1030 | #endif |
1106 | shell = getenv("SHELL"); | 1031 | shell = getenv("SHELL"); |
1107 | if (!shell) | 1032 | if (!shell) |
1108 | shell = "/bin/sh"; | 1033 | shell = "/bin/sh"; |
1109 | } | 1034 | } |
1110 | errno = 0; | 1035 | errno = 0; |
1111 | execl(shell, shell, "-c", exe_cmd, (char *)NULL); | 1036 | execl(shell, shell, "-c", exe_cmd, (char *)NULL); |
1112 | } | 1037 | } |
1113 | else /* We can run this directly. */ | 1038 | else |
1114 | { | 1039 | { /* We can run this directly. */ |
1115 | if (!args) | 1040 | if (!args) |
1116 | { | 1041 | { |
1117 | ERR("arg[0] is NULL!"); | 1042 | ERR("arg[0] is NULL!"); |
1118 | return; | 1043 | return; |
1119 | } | 1044 | } |
1120 | errno = 0; | 1045 | errno = 0; |
1121 | if (args[0]) execvp(args[0], args); | 1046 | if (args[0]) execvp(args[0], args); |
1122 | } | 1047 | } |
1123 | 1048 | ||
1124 | save_errno = errno; | 1049 | save_errno = errno; |
1125 | errno = save_errno; | 1050 | errno = save_errno; |
@@ -1127,9 +1052,9 @@ _ecore_exe_exec_it(const char *exe_cmd, | |||
1127 | } | 1052 | } |
1128 | 1053 | ||
1129 | static Eina_Bool | 1054 | static Eina_Bool |
1130 | _ecore_exe_data_generic_handler(void *data, | 1055 | _ecore_exe_data_generic_handler(void *data, |
1131 | Ecore_Fd_Handler *fd_handler, | 1056 | Ecore_Fd_Handler *fd_handler, |
1132 | Ecore_Exe_Flags flags) | 1057 | Ecore_Exe_Flags flags) |
1133 | { | 1058 | { |
1134 | Ecore_Exe *obj = data; | 1059 | Ecore_Exe *obj = data; |
1135 | int child_fd; | 1060 | int child_fd; |
@@ -1141,139 +1066,142 @@ _ecore_exe_data_generic_handler(void *data, | |||
1141 | 1066 | ||
1142 | /* Sort out what sort of handler we are. */ | 1067 | /* Sort out what sort of handler we are. */ |
1143 | if (flags & ECORE_EXE_PIPE_READ) | 1068 | if (flags & ECORE_EXE_PIPE_READ) |
1144 | { | 1069 | { |
1145 | flags = ECORE_EXE_PIPE_READ; | 1070 | flags = ECORE_EXE_PIPE_READ; |
1146 | event_type = ECORE_EXE_EVENT_DATA; | 1071 | event_type = ECORE_EXE_EVENT_DATA; |
1147 | eo_event = ECORE_EXE_EVENT_DATA_GET; | 1072 | eo_event = ECORE_EXE_EVENT_DATA_GET; |
1148 | child_fd = exe->child_fd_read; | 1073 | child_fd = exe->child_fd_read; |
1149 | } | 1074 | } |
1150 | else | 1075 | else |
1151 | { | 1076 | { |
1152 | flags = ECORE_EXE_PIPE_ERROR; | 1077 | flags = ECORE_EXE_PIPE_ERROR; |
1153 | event_type = ECORE_EXE_EVENT_ERROR; | 1078 | event_type = ECORE_EXE_EVENT_ERROR; |
1154 | eo_event = ECORE_EXE_EVENT_DATA_ERROR; | 1079 | eo_event = ECORE_EXE_EVENT_DATA_ERROR; |
1155 | child_fd = exe->child_fd_error; | 1080 | child_fd = exe->child_fd_error; |
1156 | } | 1081 | } |
1157 | 1082 | ||
1158 | if ((fd_handler) | 1083 | if ((fd_handler) |
1159 | && (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))) | 1084 | && (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))) |
1160 | { | 1085 | { |
1161 | unsigned char *inbuf, *temp; | 1086 | unsigned char *inbuf, *temp; |
1162 | int inbuf_num; | 1087 | int inbuf_num; |
1163 | 1088 | ||
1164 | /* Get any left over data from last time. */ | 1089 | /* Get any left over data from last time. */ |
1165 | if (flags & ECORE_EXE_PIPE_READ) | 1090 | if (flags & ECORE_EXE_PIPE_READ) |
1166 | { | 1091 | { |
1167 | inbuf = exe->read_data_buf; | 1092 | inbuf = exe->read_data_buf; |
1168 | inbuf_num = exe->read_data_size; | 1093 | inbuf_num = exe->read_data_size; |
1169 | exe->read_data_buf = NULL; | 1094 | exe->read_data_buf = NULL; |
1170 | exe->read_data_size = 0; | 1095 | exe->read_data_size = 0; |
1171 | } | 1096 | } |
1172 | else | 1097 | else |
1173 | { | 1098 | { |
1174 | inbuf = exe->error_data_buf; | 1099 | inbuf = exe->error_data_buf; |
1175 | inbuf_num = exe->error_data_size; | 1100 | inbuf_num = exe->error_data_size; |
1176 | exe->error_data_buf = NULL; | 1101 | exe->error_data_buf = NULL; |
1177 | exe->error_data_size = 0; | 1102 | exe->error_data_size = 0; |
1178 | } | 1103 | } |
1179 | 1104 | ||
1180 | for (;; ) | 1105 | for (;; ) |
1181 | { | 1106 | { |
1182 | int num, lost_exe; | 1107 | int num, lost_exe; |
1183 | char buf[READBUFSIZ]; | 1108 | char buf[READBUFSIZ]; |
1184 | 1109 | ||
1185 | lost_exe = 0; | 1110 | lost_exe = 0; |
1186 | errno = 0; | 1111 | errno = 0; |
1187 | if ((num = read(child_fd, buf, READBUFSIZ)) < 1) | 1112 | if ((num = read(child_fd, buf, READBUFSIZ)) < 1) |
1113 | { | ||
1114 | /* FIXME: SPEED/SIZE TRADE OFF - add a smaller READBUFSIZE | ||
1115 | * (currently 64k) to inbuf, use that instead of buf, and | ||
1116 | * save ourselves a memcpy(). */ | ||
1117 | lost_exe = ((errno == EIO) || | ||
1118 | (errno == EBADF) || | ||
1119 | (errno == EPIPE) || | ||
1120 | (errno == EINVAL) || (errno == ENOSPC)); | ||
1121 | if ((errno != EAGAIN) && (errno != EINTR)) | ||
1122 | perror("_ecore_exe_generic_handler() read problem "); | ||
1123 | } | ||
1124 | if (num > 0) /* data got read. */ | ||
1125 | { | ||
1126 | temp = inbuf; | ||
1127 | inbuf = realloc(inbuf, inbuf_num + num); | ||
1128 | if (inbuf) | ||
1129 | { | ||
1130 | memcpy(inbuf + inbuf_num, buf, num); | ||
1131 | inbuf_num += num; | ||
1132 | } | ||
1133 | else // realloc fails and returns NULL. | ||
1134 | { | ||
1135 | ERR("Out of memory in exe generic data handler"); | ||
1136 | inbuf = temp; | ||
1137 | } | ||
1138 | } | ||
1139 | else | ||
1140 | { /* No more data to read. */ | ||
1141 | if (inbuf) | ||
1142 | { | ||
1143 | Ecore_Exe_Event_Data *e; | ||
1144 | |||
1145 | /* Stash the data away for later. */ | ||
1146 | if (flags & ECORE_EXE_PIPE_READ) | ||
1188 | { | 1147 | { |
1189 | /* FIXME: SPEED/SIZE TRADE OFF - add a smaller READBUFSIZE | 1148 | exe->read_data_buf = inbuf; |
1190 | * (currently 64k) to inbuf, use that instead of buf, and | 1149 | exe->read_data_size = inbuf_num; |
1191 | * save ourselves a memcpy(). */ | ||
1192 | lost_exe = ((errno == EIO) || | ||
1193 | (errno == EBADF) || | ||
1194 | (errno == EPIPE) || | ||
1195 | (errno == EINVAL) || (errno == ENOSPC)); | ||
1196 | if ((errno != EAGAIN) && (errno != EINTR)) | ||
1197 | perror("_ecore_exe_generic_handler() read problem "); | ||
1198 | } | 1150 | } |
1199 | if (num > 0) /* data got read. */ | 1151 | else |
1200 | { | 1152 | { |
1201 | temp = inbuf; | 1153 | exe->error_data_buf = inbuf; |
1202 | inbuf = realloc(inbuf, inbuf_num + num); | 1154 | exe->error_data_size = inbuf_num; |
1203 | if (inbuf) | ||
1204 | { | ||
1205 | memcpy(inbuf + inbuf_num, buf, num); | ||
1206 | inbuf_num += num; | ||
1207 | } | ||
1208 | else // realloc fails and returns NULL. | ||
1209 | { | ||
1210 | ERR("Out of memory in exe generic data handler"); | ||
1211 | inbuf = temp; | ||
1212 | } | ||
1213 | } | 1155 | } |
1214 | else /* No more data to read. */ | 1156 | |
1157 | if (!(exe->flags & ECORE_EXE_PIPE_AUTO)) | ||
1215 | { | 1158 | { |
1216 | if (inbuf) | 1159 | // XXX: use eo method |
1217 | { | 1160 | e = ecore_exe_event_data_get(obj, flags); |
1218 | Ecore_Exe_Event_Data *e; | 1161 | if (e) /* Send the event. */ |
1219 | |||
1220 | /* Stash the data away for later. */ | ||
1221 | if (flags & ECORE_EXE_PIPE_READ) | ||
1222 | { | ||
1223 | exe->read_data_buf = inbuf; | ||