diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am index 28a46d374d..630977846d 100644 --- a/src/Makefile_Ecore.am +++ b/src/Makefile_Ecore.am @@ -8,6 +8,7 @@ ecore_eolian_files_legacy = \ lib/ecore/efl_loop_timer.eo ecore_eolian_files_public = \ + lib/ecore/efl_app.eo \ lib/ecore/efl_loop.eo \ lib/ecore/efl_loop_consumer.eo \ lib/ecore/efl_loop_fd.eo \ @@ -16,6 +17,8 @@ ecore_eolian_files_public = \ lib/ecore/efl_loop_message_handler.eo \ lib/ecore/efl_exe.eo \ lib/ecore/efl_thread.eo \ + lib/ecore/efl_appthread.eo \ + lib/ecore/efl_task.eo \ lib/ecore/efl_io_closer_fd.eo \ lib/ecore/efl_io_positioner_fd.eo \ lib/ecore/efl_io_reader_fd.eo \ @@ -35,8 +38,7 @@ ecore_eolian_files_public = \ lib/ecore/efl_interpolator_divisor.eo \ lib/ecore/efl_interpolator_bounce.eo \ lib/ecore/efl_interpolator_spring.eo \ - lib/ecore/efl_interpolator_cubic_bezier.eo \ - lib/ecore/efl_task.eo + lib/ecore/efl_interpolator_cubic_bezier.eo ecore_eolian_files = \ $(ecore_eolian_files_public) \ @@ -95,6 +97,7 @@ lib/ecore/ecore_job.c \ lib/ecore/ecore_main.c \ lib/ecore/ecore_event_message.c \ lib/ecore/ecore_event_message_handler.c \ +lib/ecore/efl_app.c \ lib/ecore/efl_loop.c \ lib/ecore/efl_loop_consumer.c \ lib/ecore/efl_loop_fd.c \ @@ -134,6 +137,8 @@ lib/ecore/efl_interpolator_spring.c \ lib/ecore/efl_interpolator_cubic_bezier.c \ lib/ecore/efl_task.c \ lib/ecore/efl_exe.c \ +lib/ecore/efl_thread.c \ +lib/ecore/efl_appthread.c \ lib/ecore/ecore_main_timechanges.c \ lib/ecore/ecore_pipe.c \ lib/ecore/ecore_poller.c \ diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h index f5ce92d805..be4df7e377 100644 --- a/src/lib/ecore/Ecore_Eo.h +++ b/src/lib/ecore/Ecore_Eo.h @@ -45,9 +45,12 @@ #include "efl_loop_message_handler.eo.h" #include "efl_task.eo.h" +#include "efl_thread.eo.h" #include "efl_exe.eo.h" #include "efl_loop.eo.h" +#include "efl_app.eo.h" +#include "efl_appthread.eo.h" /** * @brief Quits the main loop once all the events currently on the queue have @@ -103,6 +106,7 @@ EAPI Eina_Promise *efl_loop_promise_new(const Eo *obj, Eina_Promise_Cancel_Cb ca /* We ue the factory pattern here, so you shouldn't call eo_add directly. */ EAPI Eo *efl_main_loop_get(void); +EAPI Eo *efl_app_get(void); typedef struct _Efl_Future_Composite_Progress Efl_Future_All_Progress; diff --git a/src/lib/ecore/ecore.c b/src/lib/ecore/ecore.c index d911bc4e23..754b826314 100644 --- a/src/lib/ecore/ecore.c +++ b/src/lib/ecore/ecore.c @@ -215,8 +215,7 @@ _efl_first_loop_iterate(void *data, const Efl_Event *event) case 'T': fprintf(stderr, "Loop started: '%f' - '%f' = '%f' sec\n", end, _efl_startup_time, end - _efl_startup_time); break; } - - efl_event_callback_del(event->object, EFL_LOOP_EVENT_RESUME, + efl_event_callback_del(event->object, EFL_APP_EVENT_RESUME, _efl_first_loop_iterate, data); } @@ -345,13 +344,11 @@ ecore_init(void) if (!_no_system_modules) ecore_system_modules_load(); - if (getenv("EFL_FIRST_LOOP")) efl_event_callback_add(efl_main_loop_get(), - EFL_LOOP_EVENT_RESUME, + EFL_APP_EVENT_RESUME, _efl_first_loop_iterate, getenv("EFL_FIRST_LOOP")); - _ecore_init_count_threshold = _ecore_init_count; eina_log_timing(_ecore_log_dom, @@ -390,8 +387,7 @@ ecore_shutdown(void) } if (_ecore_init_count-- != _ecore_init_count_threshold) goto end; - - efl_event_callback_call(efl_main_loop_get(), EFL_LOOP_EVENT_TERMINATE, NULL); + efl_event_callback_call(efl_main_loop_get(), EFL_APP_EVENT_TERMINATE, NULL); ecore_system_modules_unload(); diff --git a/src/lib/ecore/ecore_exe.c b/src/lib/ecore/ecore_exe.c index 908f677539..781dea60bd 100644 --- a/src/lib/ecore/ecore_exe.c +++ b/src/lib/ecore/ecore_exe.c @@ -66,7 +66,7 @@ ecore_exe_pipe_run(const char *exe_cmd, const void *data) { EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - Ecore_Exe *ret = efl_add(MY_CLASS, efl_loop_main_get(EFL_LOOP_CLASS), + Ecore_Exe *ret = efl_add(MY_CLASS, efl_main_loop_get(), ecore_obj_exe_command_set(efl_added, exe_cmd, flags)); if (ret) diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c index bc3c6c84a9..ebd572bb65 100644 --- a/src/lib/ecore/ecore_main.c +++ b/src/lib/ecore/ecore_main.c @@ -1372,7 +1372,7 @@ ecore_main_fd_handler_add(int fd, { Ecore_Fd_Handler *fdh = NULL; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - fdh = _ecore_main_fd_handler_add(efl_loop_main_get(EFL_LOOP_CLASS), + fdh = _ecore_main_fd_handler_add(efl_main_loop_get(), ML_DAT, NULL, fd, flags, func, data, buf_func, buf_data, EINA_FALSE); if (fdh) fdh->legacy = EINA_TRUE; @@ -1388,7 +1388,7 @@ ecore_main_fd_handler_file_add(int fd, const void *buf_data) { EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - return _ecore_main_fd_handler_add(efl_loop_main_get(EFL_LOOP_CLASS), + return _ecore_main_fd_handler_add(efl_main_loop_get(), ML_DAT, NULL, fd, flags, func, data, buf_func, buf_data, EINA_TRUE); } @@ -1595,7 +1595,7 @@ ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, } void -_ecore_main_content_clear(Efl_Loop_Data *pd) +_ecore_main_content_clear(Eo *obj, Efl_Loop_Data *pd) { Efl_Promise *promise; Efl_Future *future; @@ -1608,7 +1608,7 @@ _ecore_main_content_clear(Efl_Loop_Data *pd) ecore_loop_promise_fulfill(promise); // FIXME - __eina_promise_cancel_all(); + __eina_promise_cancel_data(obj); while (pd->fd_handlers) { diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h index 7ff80f57c3..7e44bf4acb 100644 --- a/src/lib/ecore/ecore_private.h +++ b/src/lib/ecore/ecore_private.h @@ -88,6 +88,7 @@ typedef struct _Efl_Loop_Future_Scheduler Efl_Loop_Future_Scheduler; typedef struct _Efl_Loop_Data Efl_Loop_Data; typedef struct _Efl_Task_Data Efl_Task_Data; +typedef struct _Efl_Appthread_Data Efl_Appthread_Data; typedef struct _Message_Handler Message_Handler; typedef struct _Message Message; @@ -193,6 +194,18 @@ struct _Efl_Task_Data Eina_Bool exited : 1; }; +struct _Efl_Appthread_Data +{ + struct { + int in, out; + Eo *in_handler, *out_handler; + Eina_Bool can_read : 1; + Eina_Bool eos_read : 1; + Eina_Bool can_write : 1; + } fd, ctrl; + int read_listeners; +}; + #define EVAS_FRAME_QUEUING 1 /* for test */ @@ -325,7 +338,7 @@ _ecore_main_win32_handler_del(Eo *obj, Efl_Loop_Data *pd, Ecore_Win32_Handler *win32_handler); -void _ecore_main_content_clear(Efl_Loop_Data *pd); +void _ecore_main_content_clear(Eo *obj, Efl_Loop_Data *pd); void _ecore_main_shutdown(void); #if defined (_WIN32) || defined (__lv2ppu__) || defined (HAVE_EXOTIC) @@ -525,7 +538,7 @@ void ecore_loop_promise_fulfill(Efl_Promise *p); // access to direct input cb #define ECORE_EVAS_INTERNAL -#define EFL_LOOP_DATA efl_data_scope_get(efl_loop_main_get(EFL_LOOP_CLASS), EFL_LOOP_CLASS) +#define EFL_LOOP_DATA efl_data_scope_get(efl_main_loop_get(), EFL_LOOP_CLASS) EOAPI Eina_Bool efl_loop_message_process(Eo *obj); diff --git a/src/lib/ecore/ecore_signal.c b/src/lib/ecore/ecore_signal.c index 98934e63b3..616f22b4ee 100644 --- a/src/lib/ecore/ecore_signal.c +++ b/src/lib/ecore/ecore_signal.c @@ -78,9 +78,9 @@ _ecore_signal_pipe_read(Eo *obj) if (loop) { if (sdata.sig == SIGUSR1) - efl_event_callback_call(loop, EFL_LOOP_EVENT_SIGNAL_USR1, NULL); + efl_event_callback_call(loop, EFL_APP_EVENT_SIGNAL_USR1, NULL); else - efl_event_callback_call(loop, EFL_LOOP_EVENT_SIGNAL_USR2, NULL); + efl_event_callback_call(loop, EFL_APP_EVENT_SIGNAL_USR2, NULL); } } break; @@ -95,7 +95,7 @@ _ecore_signal_pipe_read(Eo *obj) } Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS); if (loop) - efl_event_callback_call(loop, EFL_LOOP_EVENT_SIGNAL_HUP, NULL); + efl_event_callback_call(loop, EFL_APP_EVENT_SIGNAL_HUP, NULL); } break; case SIGQUIT: @@ -112,6 +112,9 @@ _ecore_signal_pipe_read(Eo *obj) ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, _ecore_signal_generic_free, NULL); } + Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS); + if (loop) + efl_event_callback_call(loop, EFL_TASK_EVENT_EXIT, NULL); } break; #ifdef SIGPWR diff --git a/src/lib/ecore/ecore_timer.c b/src/lib/ecore/ecore_timer.c index 6ef4ab254c..7805f79de2 100644 --- a/src/lib/ecore/ecore_timer.c +++ b/src/lib/ecore/ecore_timer.c @@ -74,7 +74,7 @@ static void _check_timer_event_catcher_add(void *data, const Efl_Event *event) { Efl_Loop_Timer_Data *timer = data; - const Efl_Callback_Array_Item *array = event->info; + const Efl_Callback_Array_Item_Full *array = event->info; int i; for (i = 0; array[i].desc != NULL; i++) @@ -94,7 +94,7 @@ static void _check_timer_event_catcher_del(void *data, const Efl_Event *event) { Efl_Loop_Timer_Data *timer = data; - const Efl_Callback_Array_Item *array = event->info; + const Efl_Callback_Array_Item_Full *array = event->info; int i; for (i = 0; array[i].desc != NULL; i++) diff --git a/src/lib/ecore/efl_app.c b/src/lib/ecore/efl_app.c new file mode 100644 index 0000000000..b6e2b1f29d --- /dev/null +++ b/src/lib/ecore/efl_app.c @@ -0,0 +1,415 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#define EFL_IO_READER_PROTECTED 1 +#define EFL_IO_WRITER_PROTECTED 1 +#define EFL_IO_CLOSER_PROTECTED 1 + +#include + +#include "ecore_private.h" + +#ifndef _WIN32 +# include +#endif + +#define MY_CLASS EFL_APP_CLASS + +typedef struct _Efl_App_Data Efl_App_Data; + +struct _Efl_App_Data +{ + struct { + int in, out; + Eo *in_handler, *out_handler; + Eina_Bool can_read : 1; + Eina_Bool eos_read : 1; + Eina_Bool can_write : 1; + } fd; + int read_listeners; +}; + +Efl_Version _app_efl_version = { 0, 0, 0, 0, NULL, NULL }; + +////////////////////////////////////////////////////////////////////////// + +EAPI Eo * +efl_app_get(void) +{ + return efl_main_loop_get(); +} + +////////////////////////////////////////////////////////////////////////// + +static void +_parent_read_listeners_modify(Efl_App_Data *pd, int mod) +{ + pd->read_listeners += mod; + + if (pd->fd.out_handler) + { + if ((pd->read_listeners == 0) && (mod < 0)) + efl_loop_handler_active_set + (pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_NONE); + else if ((pd->read_listeners == 1) && (mod > 0)) + efl_loop_handler_active_set + (pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_READ); + } +} + +static void +_cb_event_callback_add(void *data, const Efl_Event *event) +{ + Efl_App_Data *pd = data; + const Efl_Callback_Array_Item_Full *array = event->info; + int i; + + for (i = 0; array[i].desc != NULL; i++) + { + if (array[i].desc == EFL_IO_READER_EVENT_CAN_READ_CHANGED) + _parent_read_listeners_modify(pd, 1); + } +} + +static void +_cb_event_callback_del(void *data, const Efl_Event *event) +{ + Efl_App_Data *pd = data; + const Efl_Callback_Array_Item_Full *array = event->info; + int i; + + for (i = 0; array[i].desc != NULL; i++) + { + if (array[i].desc == EFL_IO_READER_EVENT_CAN_READ_CHANGED) + _parent_read_listeners_modify(pd, -1); + } +} + +static void +_cb_out(void *data, const Efl_Event *event EINA_UNUSED) +{ + Eo *obj = data; + efl_io_reader_can_read_set(obj, EINA_TRUE); +} + +static void +_cb_in(void *data, const Efl_Event *event EINA_UNUSED) +{ + Eo *obj = data; + efl_io_writer_can_write_set(obj, EINA_TRUE); +} + + +EFL_CALLBACKS_ARRAY_DEFINE(_event_callback_watch, + { EFL_EVENT_CALLBACK_ADD, _cb_event_callback_add }, + { EFL_EVENT_CALLBACK_DEL, _cb_event_callback_del }); + +////////////////////////////////////////////////////////////////////////// + +EOLIAN static Efl_Loop * +_efl_app_loop_main_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED) +{ + if (_mainloop_singleton) return _mainloop_singleton; + _mainloop_singleton = efl_add(EFL_APP_CLASS, NULL); + _mainloop_singleton_data = efl_data_scope_get(_mainloop_singleton, EFL_LOOP_CLASS); + return _mainloop_singleton; +} + +EOLIAN static const Efl_Version * +_efl_app_build_efl_version_get(Eo *obj EINA_UNUSED, Efl_App_Data *pd EINA_UNUSED) +{ + return &_app_efl_version; +} + +EOLIAN static const Efl_Version * +_efl_app_efl_version_get(Eo *obj EINA_UNUSED, Efl_App_Data *pd EINA_UNUSED) +{ + /* vanilla EFL: flavor = NULL */ + static const Efl_Version version = { + .major = VMAJ, + .minor = VMIN, + .micro = VMIC, + .revision = VREV, + .build_id = EFL_BUILD_ID, + .flavor = NULL + }; + return &version; +} + +EOLIAN static Efl_Object * +_efl_app_efl_object_constructor(Eo *obj, Efl_App_Data *pd) +{ + obj = efl_constructor(efl_super(obj, MY_CLASS)); + efl_event_callback_array_add(obj, _event_callback_watch(), pd); + pd->fd.in = 1; + pd->fd.out = 0; + pd->fd.can_write = EINA_TRUE; + pd->fd.in_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, pd->fd.in), + efl_event_callback_add + (efl_added, EFL_LOOP_HANDLER_EVENT_WRITE, _cb_in, obj)); + pd->fd.out_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, pd->fd.out), + efl_event_callback_add + (efl_added, EFL_LOOP_HANDLER_EVENT_READ, _cb_out, obj)); + return obj; +} + +EOLIAN static void +_efl_app_efl_object_destructor(Eo *obj, Efl_App_Data *pd) +{ + efl_del(pd->fd.in_handler); + efl_del(pd->fd.out_handler); + pd->fd.in_handler = NULL; + pd->fd.out_handler = NULL; + pd->fd.in = -1; + pd->fd.out = -1; + efl_destructor(efl_super(obj, MY_CLASS)); +} + +EOLIAN static Eina_Error +_efl_app_efl_io_closer_close(Eo *obj, Efl_App_Data *pd) +{ + EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(obj), EBADF); + efl_io_writer_can_write_set(obj, EINA_FALSE); + efl_io_reader_can_read_set(obj, EINA_FALSE); + efl_io_reader_eos_set(obj, EINA_TRUE); + if (pd->fd.in_handler) efl_del(pd->fd.in_handler); + if (pd->fd.out_handler) efl_del(pd->fd.out_handler); + pd->fd.in = -1; + pd->fd.out = -1; + pd->fd.in_handler = NULL; + pd->fd.out_handler = NULL; + return 0; +} + +EOLIAN static Eina_Bool +_efl_app_efl_io_closer_closed_get(Eo *obj EINA_UNUSED, Efl_App_Data *pd) +{ + if ((pd->fd.in == -1) && (pd->fd.out == -1)) return EINA_TRUE; + return EINA_FALSE; +} + +EOLIAN static Eina_Error +_efl_app_efl_io_reader_read(Eo *obj, Efl_App_Data *pd, Eina_Rw_Slice *rw_slice) +{ + ssize_t r; + + errno = 0; + if (pd->fd.out == -1) goto err; + + do + { + errno = 0; + r = read(pd->fd.out, rw_slice->mem, rw_slice->len); + if (r == -1) + { + if (errno == EINTR) continue; + goto err; + } + } + while (r == -1); + + rw_slice->len = r; + if (r == 0) + { + efl_io_reader_can_read_set(obj, EINA_FALSE); + efl_io_reader_eos_set(obj, EINA_TRUE); + close(pd->fd.out); + pd->fd.out = -1; + efl_del(pd->fd.out_handler); + pd->fd.out_handler = NULL; + return EPIPE; + } + return 0; +err: + if ((pd->fd.out != -1) && (errno != EAGAIN)) + { + close(pd->fd.out); + pd->fd.out = -1; + efl_del(pd->fd.out_handler); + pd->fd.out_handler = NULL; + } + rw_slice->len = 0; + rw_slice->mem = NULL; + efl_io_reader_can_read_set(obj, EINA_FALSE); + return EINVAL; +} + +EOLIAN static void +_efl_app_efl_io_reader_can_read_set(Eo *obj, Efl_App_Data *pd, Eina_Bool can_read) +{ + Eina_Bool old = efl_io_reader_can_read_get(obj); + if (old == can_read) return; + pd->fd.can_read = can_read; + if (can_read) + efl_loop_handler_active_set(pd->fd.in_handler, 0); + else + efl_loop_handler_active_set(pd->fd.in_handler, + EFL_LOOP_HANDLER_FLAGS_READ); + efl_event_callback_call(obj, EFL_IO_READER_EVENT_CAN_READ_CHANGED, NULL); +} + +EOLIAN static Eina_Bool +_efl_app_efl_io_reader_can_read_get(Eo *obj EINA_UNUSED, Efl_App_Data *pd) +{ + return pd->fd.can_read; +} + +EOLIAN static void +_efl_app_efl_io_reader_eos_set(Eo *obj, Efl_App_Data *pd, Eina_Bool is_eos) +{ + Eina_Bool old = efl_io_reader_eos_get(obj); + if (old == is_eos) return; + + pd->fd.eos_read = is_eos; + if (!is_eos) return; + if (pd->fd.out_handler) + efl_loop_handler_active_set(pd->fd.out_handler, 0); + efl_event_callback_call(obj, EFL_IO_READER_EVENT_EOS, NULL); +} + +EOLIAN static Eina_Bool +_efl_app_efl_io_reader_eos_get(Eo *obj EINA_UNUSED, Efl_App_Data *pd) +{ + return pd->fd.eos_read; +} + +EOLIAN static Eina_Error +_efl_app_efl_io_writer_write(Eo *obj, Efl_App_Data *pd, Eina_Slice *slice, Eina_Slice *remaining) +{ + ssize_t r; + + errno = 0; + if (pd->fd.in == -1) goto err; + + do + { + errno = 0; + r = write(pd->fd.in, slice->mem, slice->len); + if (r == -1) + { + if (errno == EINTR) continue; + goto err; + } + } + while (r == -1); + + if (remaining) + { + remaining->len = slice->len - r; + remaining->bytes = slice->bytes + r; + } + slice->len = r; + + if ((slice) && (slice->len > 0)) + efl_io_writer_can_write_set(obj, EINA_FALSE); + if (r == 0) + { + close(pd->fd.in); + pd->fd.in = -1; + efl_del(pd->fd.in_handler); + pd->fd.in_handler = NULL; + return EPIPE; + } + return 0; +err: + if ((pd->fd.in != -1) && (errno != EAGAIN)) + { + close(pd->fd.in); + pd->fd.in = -1; + efl_del(pd->fd.in_handler); + pd->fd.in_handler = NULL; + } + if (remaining) *remaining = *slice; + slice->len = 0; + slice->mem = NULL; + efl_io_writer_can_write_set(obj, EINA_FALSE); + return EINVAL; +} + +EOLIAN static void +_efl_app_efl_io_writer_can_write_set(Eo *obj, Efl_App_Data *pd, Eina_Bool can_write) +{ + Eina_Bool old = efl_io_writer_can_write_get(obj); + if (old == can_write) return; + pd->fd.can_write = can_write; + if (can_write) + efl_loop_handler_active_set(pd->fd.in_handler, 0); + else + efl_loop_handler_active_set(pd->fd.in_handler, + EFL_LOOP_HANDLER_FLAGS_WRITE); + efl_event_callback_call(obj, EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED, NULL); +} + +EOLIAN static Eina_Bool +_efl_app_efl_io_writer_can_write_get(Eo *obj EINA_UNUSED, Efl_App_Data *pd) +{ + return pd->fd.can_write; +} + +#ifdef _WIN32 +#else +static const signed char primap[EFL_TASK_PRIORITY_ULTRA + 1] = +{ + 10, // EFL_TASK_PRIORITY_NORMAL + 19, // EFL_TASK_PRIORITY_BACKGROUND + 15, // EFL_TASK_PRIORITY_LOW + 5, // EFL_TASK_PRIORITY_HIGH + 0 // EFL_TASK_PRIORITY_ULTRA +}; +#endif + +EOLIAN static void +_efl_app_efl_task_priority_set(Eo *obj, Efl_App_Data *pd EINA_UNUSED, Efl_Task_Priority priority) +{ + efl_task_priority_set(efl_super(obj, MY_CLASS), priority); +#ifdef _WIN32 +#else + // -20 (high) -> 19 (low) + int p = 0; + + if ((priority >= EFL_TASK_PRIORITY_NORMAL) && + (priority <= EFL_TASK_PRIORITY_ULTRA)) + p = primap[priority]; + setpriority(PRIO_PROCESS, 0, p); +#endif +} + +EOLIAN static Efl_Task_Priority +_efl_app_efl_task_priority_get(Eo *obj, Efl_App_Data *pd EINA_UNUSED) +{ + Efl_Task_Priority pri = EFL_TASK_PRIORITY_NORMAL; +#ifdef _WIN32 +#else + int p, i, dist = 0x7fffffff, d; + + errno = 0; + p = getpriority(PRIO_PROCESS, 0); + if (errno != 0) + return efl_task_priority_get(efl_super(obj, MY_CLASS)); + + // find the closest matching priority in primap + for (i = EFL_TASK_PRIORITY_NORMAL; i <= EFL_TASK_PRIORITY_ULTRA; i++) + { + d = primap[i] - p; + if (d < 0) d = -d; + if (d < dist) + { + pri = i; + dist = d; + } + } + + Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS); + if (td) td->priority = pri; +#endif + return pri; +} + +////////////////////////////////////////////////////////////////////////// + +#include "efl_app.eo.c" diff --git a/src/lib/ecore/efl_app.eo b/src/lib/ecore/efl_app.eo new file mode 100644 index 0000000000..97e08957e2 --- /dev/null +++ b/src/lib/ecore/efl_app.eo @@ -0,0 +1,57 @@ +import efl_types; +import eina_types; + +class Efl.App (Efl.Loop) +{ + [[ ]] + methods { + @property loop_main @class { + [[ Points to the main loop instance of the application. ]] + get {} + values { + main_loop: Efl.Loop; [[Application main loop]] + } + } + @property build_efl_version { + [[ Indicates the version of EFL with which this application was + compiled against/for. + + This might differ from @.efl_version. + ]] + get {} + values { + @cref version: Efl.Version; [[Efl version]] + } + } + @property efl_version { + [[ Indicates the currently running version of EFL. + + This might differ from @.build_efl_version. + ]] + get {} + values { + @cref version: Efl.Version; [[Efl version]] + } + } + } + events { + pause; [[Called when the application is not going be displayed or otherwise used by a user for some time]] + resume; [[Called before a window is rendered after a pause event]] + terminate; [[Called before starting the shutdown of the application]] + signal,usr1; [[System specific, but on unix maps to SIGUSR1 signal to the process - only called on main loop object]] + signal,usr2; [[System specific, but on unix maps to SIGUSR2 signal to the process - only called on main loop object]] + signal,hup; [[System specific, but on unix maps to SIGHUP signal to the process - only called on main loop object]] + } + implements { + Efl.Object.constructor; + Efl.Object.destructor; + Efl.Io.Closer.close; + Efl.Io.Closer.closed { get; } + Efl.Io.Reader.read; + Efl.Io.Reader.can_read { get; set; } + Efl.Io.Reader.eos { get; set; } + Efl.Io.Writer.write; + Efl.Io.Writer.can_write { get; set; } + Efl.Task.priority { get; set; } + } +} diff --git a/src/lib/ecore/efl_appthread.c b/src/lib/ecore/efl_appthread.c new file mode 100644 index 0000000000..93de9c0917 --- /dev/null +++ b/src/lib/ecore/efl_appthread.c @@ -0,0 +1,245 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#define EFL_IO_READER_PROTECTED 1 +#define EFL_IO_WRITER_PROTECTED 1 +#define EFL_IO_CLOSER_PROTECTED 1 + +#include + +#include "ecore_private.h" + +#include +#include +#include + +#define MY_CLASS EFL_APPTHREAD_CLASS + +////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////// + +EOLIAN static Efl_Object * +_efl_appthread_efl_object_constructor(Eo *obj, Efl_Appthread_Data *pd) +{ + obj = efl_constructor(efl_super(obj, MY_CLASS)); + pd->fd.in = -1; + pd->fd.out = -1; + pd->fd.can_write = EINA_TRUE; + pd->ctrl.in = -1; + pd->ctrl.out = -1; + return obj; +} + +EOLIAN static void +_efl_appthread_efl_object_destructor(Eo *obj, Efl_Appthread_Data *pd) +{ + if (pd->fd.in >= 0) + { + efl_del(pd->fd.in_handler); + efl_del(pd->fd.out_handler); + efl_del(pd->ctrl.in_handler); + efl_del(pd->ctrl.out_handler); + close(pd->fd.in); + close(pd->fd.out); + close(pd->ctrl.in); + close(pd->ctrl.out); + pd->fd.in_handler = NULL; + pd->fd.out_handler = NULL; + pd->ctrl.in_handler = NULL; + pd->ctrl.out_handler = NULL; + pd->fd.in = -1; + pd->fd.out = -1; + pd->ctrl.in = -1; + pd->ctrl.out = -1; + } + efl_destructor(efl_super(obj, MY_CLASS)); +} + +EOLIAN static Eina_Error +_efl_appthread_efl_io_closer_close(Eo *obj, Efl_Appthread_Data *pd) +{ + EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(obj), EBADF); + efl_io_writer_can_write_set(obj, EINA_FALSE); + efl_io_reader_can_read_set(obj, EINA_FALSE); + efl_io_reader_eos_set(obj, EINA_TRUE); + if (pd->fd.in >= 0) close(pd->fd.in); + if (pd->fd.out >= 0) close(pd->fd.out); + if (pd->fd.in_handler) efl_del(pd->fd.in_handler); + if (pd->fd.out_handler) efl_del(pd->fd.out_handler); + pd->fd.in = -1; + pd->fd.out = -1; + pd->fd.in_handler = NULL; + pd->fd.out_handler = NULL; + return 0; +} + +EOLIAN static Eina_Bool +_efl_appthread_efl_io_closer_closed_get(Eo *obj EINA_UNUSED, Efl_Appthread_Data *pd) +{ + if ((pd->fd.in == -1) && (pd->fd.out == -1)) return EINA_TRUE; + return EINA_FALSE; +} + +EOLIAN static Eina_Error +_efl_appthread_efl_io_reader_read(Eo *obj, Efl_Appthread_Data *pd, Eina_Rw_Slice *rw_slice) +{ + ssize_t r; + + errno = 0; + if (pd->fd.out == -1) goto err; + + do + { + errno = 0; + r = read(pd->fd.out, rw_slice->mem, rw_slice->len); + if (r == -1) + { + if (errno == EINTR) continue; + goto err; + } + } + while (r == -1); + + rw_slice->len = r; + if (r == 0) + { + efl_io_reader_can_read_set(obj, EINA_FALSE); + efl_io_reader_eos_set(obj, EINA_TRUE); + close(pd->fd.out); + pd->fd.out = -1; + efl_del(pd->fd.out_handler); + pd->fd.out_handler = NULL; + return EPIPE; + } + return 0; +err: + if ((pd->fd.out != -1) && (errno != EAGAIN)) + { + close(pd->fd.out); + pd->fd.out = -1; + efl_del(pd->fd.out_handler); + pd->fd.out_handler = NULL; + } + rw_slice->len = 0; + rw_slice->mem = NULL; + efl_io_reader_can_read_set(obj, EINA_FALSE); + return EINVAL; +} + +EOLIAN static void +_efl_appthread_efl_io_reader_can_read_set(Eo *obj, Efl_Appthread_Data *pd, Eina_Bool can_read) +{ + Eina_Bool old = efl_io_reader_can_read_get(obj); + if (old == can_read) return; + pd->fd.can_read = can_read; + if (can_read) + efl_loop_handler_active_set(pd->fd.in_handler, 0); + else + efl_loop_handler_active_set(pd->fd.in_handler, + EFL_LOOP_HANDLER_FLAGS_READ); + efl_event_callback_call(obj, EFL_IO_READER_EVENT_CAN_READ_CHANGED, NULL); +} + +EOLIAN static Eina_Bool +_efl_appthread_efl_io_reader_can_read_get(Eo *obj EINA_UNUSED, Efl_Appthread_Data *pd) +{ + return pd->fd.can_read; +} + +EOLIAN static void +_efl_appthread_efl_io_reader_eos_set(Eo *obj, Efl_Appthread_Data *pd, Eina_Bool is_eos) +{ + Eina_Bool old = efl_io_reader_eos_get(obj); + if (old == is_eos) return; + + pd->fd.eos_read = is_eos; + if (!is_eos) return; + if (pd->fd.out_handler) + efl_loop_handler_active_set(pd->fd.out_handler, 0); + efl_event_callback_call(obj, EFL_IO_READER_EVENT_EOS, NULL); +} + +EOLIAN static Eina_Bool +_efl_appthread_efl_io_reader_eos_get(Eo *obj EINA_UNUSED, Efl_Appthread_Data *pd) +{ + return pd->fd.eos_read; +} + +EOLIAN static Eina_Error +_efl_appthread_efl_io_writer_write(Eo *obj, Efl_Appthread_Data *pd, Eina_Slice *slice, Eina_Slice *remaining) +{ + ssize_t r; + + errno = 0; + if (pd->fd.in == -1) goto err; + + do + { + errno = 0; + r = write(pd->fd.in, slice->mem, slice->len); + if (r == -1) + { + if (errno == EINTR) continue; + goto err; + } + } + while (r == -1); + + if (remaining) + { + remaining->len = slice->len - r; + remaining->bytes = slice->bytes + r; + } + slice->len = r; + + if ((slice) && (slice->len > 0)) + efl_io_writer_can_write_set(obj, EINA_FALSE); + if (r == 0) + { + close(pd->fd.in); + pd->fd.in = -1; + efl_del(pd->fd.in_handler); + pd->fd.in_handler = NULL; + return EPIPE; + } + return 0; +err: + if ((pd->fd.in != -1) && (errno != EAGAIN)) + { + close(pd->fd.in); + pd->fd.in = -1; + efl_del(pd->fd.in_handler); + pd->fd.in_handler = NULL; + } + if (remaining) *remaining = *slice; + slice->len = 0; + slice->mem = NULL; + efl_io_writer_can_write_set(obj, EINA_FALSE); + return EINVAL; +} + +EOLIAN static void +_efl_appthread_efl_io_writer_can_write_set(Eo *obj, Efl_Appthread_Data *pd, Eina_Bool can_write) +{ + Eina_Bool old = efl_io_writer_can_write_get(obj); + if (old == can_write) return; + pd->fd.can_write = can_write; + if (can_write) + efl_loop_handler_active_set(pd->fd.in_handler, 0); + else + efl_loop_handler_active_set(pd->fd.in_handler, + EFL_LOOP_HANDLER_FLAGS_WRITE); + efl_event_callback_call(obj, EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED, NULL); +} + +EOLIAN static Eina_Bool +_efl_appthread_efl_io_writer_can_write_get(Eo *obj EINA_UNUSED, Efl_Appthread_Data *pd) +{ + return pd->fd.can_write; +} + +////////////////////////////////////////////////////////////////////////// + +#include "efl_appthread.eo.c" diff --git a/src/lib/ecore/efl_appthread.eo b/src/lib/ecore/efl_appthread.eo new file mode 100644 index 0000000000..2f5021a720 --- /dev/null +++ b/src/lib/ecore/efl_appthread.eo @@ -0,0 +1,22 @@ +import efl_types; +import eina_types; + +class Efl.Appthread (Efl.Loop) +{ + [[ ]] + methods { + } + events { + } + implements { + Efl.Object.constructor; + Efl.Object.destructor; + Efl.Io.Closer.close; + Efl.Io.Closer.closed { get; } + Efl.Io.Reader.read; + Efl.Io.Reader.can_read { get; set; } + Efl.Io.Reader.eos { get; set; } + Efl.Io.Writer.write; + Efl.Io.Writer.can_write { get; set; } + } +} diff --git a/src/lib/ecore/efl_exe.c b/src/lib/ecore/efl_exe.c index ed9c53c583..1443bbf071 100644 --- a/src/lib/ecore/efl_exe.c +++ b/src/lib/ecore/efl_exe.c @@ -179,15 +179,30 @@ _foreach_env(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, voi return EINA_TRUE; } +static Eina_Value +_efl_loop_task_exit(void *data, const Eina_Value v, + const Eina_Future *dead EINA_UNUSED) +{ + Eo *obj = data; + + efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL); + efl_unref(obj); + return v; +} + static void _exe_exit_eval(Eo *obj, Efl_Exe_Data *pd) { - // XXX: defer the below in a job - if ((pd->fd.out == -1) && (pd->fd.exited_read == -1) && - (!pd->exit_called)) + if ((pd->fd.out == -1) && /*(pd->fd.in == -1) &&*/ + (pd->fd.exited_read == -1) && (!pd->exit_called)) { + Eina_Future *job; + Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS); + pd->exit_called = EINA_TRUE; - efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL); + efl_ref(obj); + job = eina_future_then(efl_loop_job(loop), _efl_loop_task_exit, obj); + efl_future_Eina_FutureXXX_then(loop, job); } } @@ -666,10 +681,11 @@ _efl_exe_efl_io_reader_can_read_set(Eo *obj, Efl_Exe_Data *pd, Eina_Bool can_rea Eina_Bool old = efl_io_reader_can_read_get(obj); if (old == can_read) return; pd->fd.can_read = can_read; + if (!pd->fd.out_handler) return; if (can_read) - efl_loop_handler_active_set(pd->fd.in_handler, 0); + efl_loop_handler_active_set(pd->fd.out_handler, 0); else - efl_loop_handler_active_set(pd->fd.in_handler, + efl_loop_handler_active_set(pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_READ); efl_event_callback_call(obj, EFL_IO_READER_EVENT_CAN_READ_CHANGED, NULL); } diff --git a/src/lib/ecore/efl_general.h b/src/lib/ecore/efl_general.h index 256f1065a4..222c799c2c 100644 --- a/src/lib/ecore/efl_general.h +++ b/src/lib/ecore/efl_general.h @@ -107,9 +107,9 @@ #define EFL_MAIN_EX() \ EFL_CALLBACKS_ARRAY_DEFINE(_efl_main_ex, \ { EFL_LOOP_EVENT_ARGUMENTS, efl_main }, \ - { EFL_LOOP_EVENT_PAUSE, efl_pause }, \ - { EFL_LOOP_EVENT_RESUME, efl_resume }, \ - { EFL_LOOP_EVENT_TERMINATE, efl_terminate }); \ + { EFL_APP_EVENT_PAUSE, efl_pause }, \ + { EFL_APP_EVENT_RESUME, efl_resume }, \ + { EFL_APP_EVENT_TERMINATE, efl_terminate }); \ int main(int argc, char **argv) \ { \ Eina_Value *ret__; \ diff --git a/src/lib/ecore/efl_loop.c b/src/lib/ecore/efl_loop.c index 74a12deb50..0ccee1706f 100644 --- a/src/lib/ecore/efl_loop.c +++ b/src/lib/ecore/efl_loop.c @@ -8,9 +8,6 @@ #include #include #include -#ifndef _WIN32 -# include -#endif #include #include "Ecore.h" @@ -53,8 +50,6 @@ _efl_loop_message_handler_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Loo return mh.handler; } -Efl_Version _app_efl_version = { 0, 0, 0, 0, NULL, NULL }; - Eo *_mainloop_singleton = NULL; Efl_Loop_Data *_mainloop_singleton_data = NULL; @@ -63,19 +58,10 @@ static Eina_List *_environ_strings_set = NULL; static void _clean_old_environ(void); -EOLIAN static Efl_Loop * -_efl_loop_main_get(Efl_Class *klass EINA_UNUSED, void *_pd EINA_UNUSED) -{ - if (_mainloop_singleton) return _mainloop_singleton; - _mainloop_singleton = efl_add(EFL_LOOP_CLASS, NULL); - _mainloop_singleton_data = efl_data_scope_get(_mainloop_singleton, EFL_LOOP_CLASS); - return _mainloop_singleton; -} - EAPI Eo * efl_main_loop_get(void) { - return efl_loop_main_get(EFL_LOOP_CLASS); + return efl_app_loop_main_get(EFL_APP_CLASS); } EOLIAN static void @@ -172,8 +158,8 @@ efl_loop_exit_code_process(Eina_Value *value) Eina_Value v = EINA_VALUE_EMPTY; eina_value_setup(&v, EINA_VALUE_TYPE_INT); - if (!eina_value_convert(&v, value)) r = -1; - else eina_value_get(&v, &v); + if (!eina_value_convert(value, &v)) r = -1; + else eina_value_get(&v, &r); } else { @@ -203,7 +189,7 @@ _poll_trigger(void *data, const Efl_Event *event) static void _check_event_catcher_add(void *data, const Efl_Event *event) { - const Efl_Callback_Array_Item *array = event->info; + const Efl_Callback_Array_Item_Full *array = event->info; Efl_Loop_Data *pd = data; int i; @@ -272,7 +258,7 @@ _check_event_catcher_add(void *data, const Efl_Event *event) static void _check_event_catcher_del(void *data, const Efl_Event *event) { - const Efl_Callback_Array_Item *array = event->info; + const Efl_Callback_Array_Item_Full *array = event->info; Efl_Loop_Data *pd = data; int i; @@ -337,7 +323,7 @@ _efl_loop_efl_object_constructor(Eo *obj, Efl_Loop_Data *pd) EOLIAN static void _efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd) { - _ecore_main_content_clear(pd); + _ecore_main_content_clear(obj, pd); pd->future_message_handler = NULL; @@ -725,6 +711,7 @@ efl_build_version_set(int vmaj, int vmin, int vmic, int revision, _app_efl_version.build_id = build_id ? strdup(build_id) : NULL; } +/* HHH: EOLIAN static const Efl_Version * _efl_loop_app_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) { @@ -734,7 +721,7 @@ _efl_loop_app_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED EOLIAN static const Efl_Version * _efl_loop_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) { - /* vanilla EFL: flavor = NULL */ + // vanilla EFL: flavor = NULL static const Efl_Version version = { .major = VMAJ, .minor = VMIN, @@ -745,6 +732,7 @@ _efl_loop_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) }; return &version; } +*/ static void _env_sync(Efl_Loop_Data *pd, Efl_Task_Data *td) @@ -903,63 +891,23 @@ _efl_loop_efl_task_env_get(Eo *obj, Efl_Loop_Data *pd, const char *var) eina_lock_release(&_environ_lock); return efl_task_env_get(efl_super(obj, EFL_LOOP_CLASS), var); } -#ifdef _WIN32 -#else -static const signed char primap[EFL_TASK_PRIORITY_ULTRA + 1] = -{ - 10, // EFL_TASK_PRIORITY_NORMAL - 19, // EFL_TASK_PRIORITY_BACKGROUND - 15, // EFL_TASK_PRIORITY_LOW - 5, // EFL_TASK_PRIORITY_HIGH - 0 // EFL_TASK_PRIORITY_ULTRA -}; -#endif -EOLIAN static void -_efl_loop_efl_task_priority_set(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, Efl_Task_Priority priority) +EOLIAN static Eina_Bool +_efl_loop_efl_task_run(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED) { - efl_task_priority_set(efl_super(obj, EFL_LOOP_CLASS), priority); -#ifdef _WIN32 -#else - // -20 (high) -> 19 (low) - int p = 0; + Eina_Value *ret; + int real; - if ((priority >= EFL_TASK_PRIORITY_NORMAL) && - (priority <= EFL_TASK_PRIORITY_ULTRA)) - p = primap[priority]; - setpriority(PRIO_PROCESS, 0, p); -#endif + ret = efl_loop_begin(obj); + real = efl_loop_exit_code_process(ret); + if (real == 0) return EINA_TRUE; + return EINA_FALSE; } -EOLIAN static Efl_Task_Priority -_efl_loop_efl_task_priority_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) +EOLIAN static void +_efl_loop_efl_task_end(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED) { - Efl_Task_Priority pri = EFL_TASK_PRIORITY_NORMAL; -#ifdef _WIN32 -#else - int p, i, dist = 0x7fffffff, d; - - errno = 0; - p = getpriority(PRIO_PROCESS, 0); - if (errno != 0) - return efl_task_priority_get(efl_super(obj, EFL_LOOP_CLASS)); - - // find the closest matching priority in primap - for (i = EFL_TASK_PRIORITY_NORMAL; i <= EFL_TASK_PRIORITY_ULTRA; i++) - { - d = primap[i] - p; - if (d < 0) d = -d; - if (d < dist) - { - pri = i; - dist = d; - } - } - - Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS); - if (td) td->priority = pri; -#endif - return pri; + efl_loop_quit(obj, eina_value_int_init(0)); } EAPI Eina_Future_Scheduler * diff --git a/src/lib/ecore/efl_loop.eo b/src/lib/ecore/efl_loop.eo index e6c1229772..1ecdd68538 100644 --- a/src/lib/ecore/efl_loop.eo +++ b/src/lib/ecore/efl_loop.eo @@ -20,33 +20,6 @@ class Efl.Loop (Efl.Task) you can provide these if you need to. ]] methods { - @property main @class { - [[Points to the main loop instance of the application.]] - get {} - values { - main_loop: Efl.Loop; [[Application main loop]] - } - } - @property app_efl_version { - [[Indicates the version of EFL with which this application was compiled. - - This might differ from @.efl_version. - ]] - get {} - values { - @cref version: Efl.Version; [[Efl version]] - } - } - @property efl_version { - [[Indicates the currently running version of EFL. - - This might differ from @.app_efl_version. - ]] - get {} - values { - @cref version: Efl.Version; [[Efl version]] - } - } iterate { [[Runs a single iteration of the main loop to process everything on the queue.]] @@ -148,18 +121,13 @@ class Efl.Loop (Efl.Task) poll,high; [[Event occurs multiple times per second. The exact tick is undefined and can be adjusted system wide.]] poll,medium; [[Event occurs multiple times per minute. The exact tick is undefined and can be adjusted system wide.]] poll,low; [[Event occurs multiple times every 15 minutes. The exact tick is undefined and can be adjusted system wide.]] - pause; [[Called when the window is not going be displayed for some time]] - resume; [[Called before a window is rendered after a pause event]] - terminate; [[Called before starting the shutdown of Elementary]] - signal,usr1; [[System specific, but on unix maps to SIGUSR1 signal to the process - only called on main loop object]] - signal,usr2; [[System specific, but on unix maps to SIGUSR2 signal to the process - only called on main loop object]] - signal,hup; [[System specific, but on unix maps to SIGHUP signal to the process - only called on main loop object]] } implements { Efl.Object.constructor; Efl.Object.destructor; Efl.Object.provider_find; Efl.Task.env { set; get; } - Efl.Task.priority { get; set; } + Efl.Task.run; + Efl.Task.end; } } diff --git a/src/lib/ecore/efl_loop_fd.c b/src/lib/ecore/efl_loop_fd.c index 87cb58c41a..e6ec21d7b9 100644 --- a/src/lib/ecore/efl_loop_fd.c +++ b/src/lib/ecore/efl_loop_fd.c @@ -111,7 +111,7 @@ _efl_loop_fd_fd_file_get(Eo *obj EINA_UNUSED, Efl_Loop_Fd_Data *pd) static void _check_fd_event_catcher_add(void *data, const Efl_Event *event) { - const Efl_Callback_Array_Item *array = event->info; + const Efl_Callback_Array_Item_Full *array = event->info; Efl_Loop_Fd_Data *fd = data; Eina_Bool need_reset = EINA_FALSE; int i; @@ -142,7 +142,7 @@ _check_fd_event_catcher_add(void *data, const Efl_Event *event) static void _check_fd_event_catcher_del(void *data, const Efl_Event *event) { - const Efl_Callback_Array_Item *array = event->info; + const Efl_Callback_Array_Item_Full *array = event->info; Efl_Loop_Fd_Data *fd = data; Eina_Bool need_reset = EINA_FALSE; int i; diff --git a/src/lib/ecore/efl_loop_handler.c b/src/lib/ecore/efl_loop_handler.c index 39d05359dd..34e03a9cc4 100644 --- a/src/lib/ecore/efl_loop_handler.c +++ b/src/lib/ecore/efl_loop_handler.c @@ -132,7 +132,7 @@ _handler_reset(Eo *obj, Efl_Loop_Handler_Data *pd) static Eina_Bool _event_references_update(Efl_Loop_Handler_Data *pd, const Efl_Event *event, int increment) { - const Efl_Callback_Array_Item *array = event->info; + const Efl_Callback_Array_Item_Full *array = event->info; int i; Eina_Bool need_reset = EINA_FALSE; diff --git a/src/lib/ecore/efl_task.c b/src/lib/ecore/efl_task.c index 18927e843e..9a727743ed 100644 --- a/src/lib/ecore/efl_task.c +++ b/src/lib/ecore/efl_task.c @@ -186,8 +186,8 @@ _escape(const char *s) { *d = '\"'; d++; - *d = 0; } + *d = 0; return s2; } @@ -215,7 +215,7 @@ _rebuild_command(Efl_Task_Data *pd) char *str = _escape(arg); if (str) { - if (!have_args) eina_strbuf_append(sb, " "); + if (have_args) eina_strbuf_append(sb, " "); eina_strbuf_append(sb, str); free(str); have_args = EINA_TRUE; @@ -272,14 +272,17 @@ _efl_task_arg_value_set(Eo *obj EINA_UNUSED, Efl_Task_Data *pd, unsigned int num if (!pd->args) pd->args = eina_array_new(16); count = eina_array_count(pd->args); - if (count > num) + if ((count > 0) && (count > num)) parg = eina_array_data_get(pd->args, num); else { unsigned int i; for (i = count; i <= num; i++) - eina_array_push(pd->args, NULL); + { + eina_array_push(pd->args, ""); + eina_array_data_set(pd->args, i, NULL); + } } if (arg) diff --git a/src/lib/ecore/efl_thread.c b/src/lib/ecore/efl_thread.c new file mode 100644 index 0000000000..ffd4f4756f --- /dev/null +++ b/src/lib/ecore/efl_thread.c @@ -0,0 +1,917 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#define EFL_IO_READER_PROTECTED 1 +#define EFL_IO_WRITER_PROTECTED 1 +#define EFL_IO_CLOSER_PROTECTED 1 + +#include + +#include "ecore_private.h" + +#include +#include +#include + +#define MY_CLASS EFL_THREAD_CLASS + +typedef struct +{ + const char *name; + struct { + int in, out; + Eo *in_handler, *out_handler; + } fd, ctrl; + struct { + unsigned int argc; + const char **argv; + } args; + Efl_Callback_Array_Item_Full *event_cb; +} Thread_Data; + +#define CMD_EXIT 1 +#define CMD_EXITED 2 + +typedef struct +{ + int command; + int data; +} Control_Data; + +typedef struct _Efl_Thread_Data Efl_Thread_Data; + +struct _Efl_Thread_Data +{ + struct { + int in, out; + Eo *in_handler, *out_handler; + Eina_Bool can_read : 1; + Eina_Bool eos_read : 1; + Eina_Bool can_write : 1; + } fd, ctrl; + int read_listeners; + Eo *loop; + Thread_Data *thdat; + Efl_Callback_Array_Item_Full *event_cb; + Eina_Thread thread; + Eina_Bool end_sent : 1; + Eina_Bool exit_read : 1; + Eina_Bool exit_called : 1; +}; + +////////////////////////////////////////////////////////////////////////// + +static void +_cb_thread_out(void *data, const Efl_Event *event EINA_UNUSED) +{ + Eo *obj = data; + efl_io_reader_can_read_set(obj, EINA_TRUE); +} + +static void +_cb_thread_in(void *data, const Efl_Event *event EINA_UNUSED) +{ + Eo *obj = data; + efl_io_writer_can_write_set(obj, EINA_TRUE); +} + +static void +_cb_thread_ctrl_out(void *data, const Efl_Event *event EINA_UNUSED) +{ + Eo *obj = data; + Control_Data cmd; + ssize_t ret; + Efl_Appthread_Data *ad; + + ad = efl_data_scope_get(obj, EFL_APPTHREAD_CLASS); + cmd.command = 0; + cmd.data = 0; + ret = read(ad->ctrl.out, &cmd, sizeof(Control_Data)); + if (ret == sizeof(Control_Data)) + { + if (cmd.command == CMD_EXIT) + { + efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL); + efl_loop_quit(obj, eina_value_int_init(0)); + } + } +} + +static Eina_Value +_efl_loop_arguments_send(void *data, const Eina_Value v, + const Eina_Future *dead EINA_UNUSED) + +{ + Efl_Loop_Arguments arge; + Eo *obj = data; + Eina_Array *arga; + Eina_Stringshare *s; + unsigned int argc = efl_task_arg_count_get(obj); + unsigned int i; + + arga = eina_array_new(argc); + if (v.type == EINA_VALUE_TYPE_ERROR) goto on_error; + + for (i = 0; i < argc; i++) + { + const char *argv = efl_task_arg_value_get(obj, i); + if (argv) + eina_array_push(arga, eina_stringshare_add(argv)); + } + arge.argv = arga; + arge.initialization = EINA_TRUE; + efl_event_callback_call(obj, + EFL_LOOP_EVENT_ARGUMENTS, &arge); +on_error: + while ((s = eina_array_pop(arga))) eina_stringshare_del(s); + eina_array_free(arga); + return v; +} + +static void +_appthread_parent_read_listeners_modify(Efl_Appthread_Data *ad, int mod) +{ + ad->read_listeners += mod; + + if (ad->fd.out_handler) + { + if ((ad->read_listeners == 0) && (mod < 0)) + efl_loop_handler_active_set + (ad->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_NONE); + else if ((ad->read_listeners == 1) && (mod > 0)) + efl_loop_handler_active_set + (ad->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_READ); + } +} + +static void +_cb_appthread_event_callback_add(void *data, const Efl_Event *event) +{ + Efl_Appthread_Data *ad = data; + const Efl_Callback_Array_Item_Full *array = event->info; + int i; + + for (i = 0; array[i].desc != NULL; i++) + { + if (array[i].desc == EFL_IO_READER_EVENT_CAN_READ_CHANGED) + _appthread_parent_read_listeners_modify(ad, 1); + } +} + +static void +_cb_appthread_event_callback_del(void *data, const Efl_Event *event) +{ + Efl_Appthread_Data *ad = data; + const Efl_Callback_Array_Item_Full *array = event->info; + int i; + + for (i = 0; array[i].desc != NULL; i++) + { + if (array[i].desc == EFL_IO_READER_EVENT_CAN_READ_CHANGED) + _appthread_parent_read_listeners_modify(ad, -1); + } +} + +EFL_CALLBACKS_ARRAY_DEFINE(_appthread_event_callback_watch, + { EFL_EVENT_CALLBACK_ADD, _cb_appthread_event_callback_add }, + { EFL_EVENT_CALLBACK_DEL, _cb_appthread_event_callback_del }); + +static void * +_efl_thread_main(void *data, Eina_Thread t) +{ + Efl_Appthread_Data *ad; + Thread_Data *thdat = data; + Eo *obj; + Eina_Value *ret; + Control_Data cmd; + unsigned int i; + int real; + Efl_Callback_Array_Item_Full *it; + Eina_Future *job; + + if (thdat->name) eina_thread_name_set(t, thdat->name); + else eina_thread_name_set(t, "Eflthread"); + + obj = efl_add(EFL_APPTHREAD_CLASS, NULL); + ad = efl_data_scope_get(obj, EFL_APPTHREAD_CLASS); + efl_event_callback_array_add(obj, _appthread_event_callback_watch(), ad); + + // add handlers for "stdio" + thdat->fd.in_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, thdat->fd.in), + efl_event_callback_add + (efl_added, EFL_LOOP_HANDLER_EVENT_WRITE, _cb_thread_in, obj)); + thdat->fd.out_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, thdat->fd.out), + efl_event_callback_add + (efl_added, EFL_LOOP_HANDLER_EVENT_READ, _cb_thread_out, obj)); + // add handlers for control pipes + thdat->ctrl.in_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, thdat->ctrl.in)); + thdat->ctrl.out_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, thdat->ctrl.out), + efl_event_callback_add + (efl_added, EFL_LOOP_HANDLER_EVENT_READ, _cb_thread_ctrl_out, obj), + efl_loop_handler_active_set + (efl_added, EFL_LOOP_HANDLER_FLAGS_READ)); + ad->fd.in = thdat->fd.in; + ad->fd.out = thdat->fd.out; + ad->ctrl.in = thdat->ctrl.in; + ad->ctrl.out = thdat->ctrl.out; + ad->fd.in_handler = thdat->fd.in_handler; + ad->fd.out_handler = thdat->fd.out_handler; + ad->ctrl.in_handler = thdat->ctrl.in_handler; + ad->ctrl.out_handler = thdat->ctrl.out_handler; + + if (thdat->event_cb) + { + for (it = thdat->event_cb; it->func; it++) + efl_event_callback_priority_add(obj, it->desc, it->priority, + it->func, it->user_data); + } + for (i = 0; i < thdat->args.argc; i++) + efl_task_arg_append(obj, thdat->args.argv[i]); + job = eina_future_then(efl_loop_job(obj), _efl_loop_arguments_send, obj); + efl_future_Eina_FutureXXX_then(obj, job); + + for (i = 0; i < thdat->args.argc; i++) + eina_stringshare_del(thdat->args.argv[i]); + free(thdat->args.argv); + free(thdat->event_cb); + thdat->args.argv = NULL; + thdat->event_cb = NULL; + + ret = efl_loop_begin(obj); + real = efl_loop_exit_code_process(ret); + + cmd.command = CMD_EXITED; + cmd.data = real; + write(thdat->ctrl.in, &cmd, sizeof(Control_Data)); + + efl_del(obj); + + thdat->fd.in_handler = NULL; + thdat->fd.out_handler = NULL; + thdat->ctrl.in_handler = NULL; + thdat->ctrl.out_handler = NULL; + thdat->fd.in = -1; + thdat->fd.out = -1; + thdat->ctrl.in = -1; + thdat->ctrl.out = -1; + + return NULL; +} + +////////////////////////////////////////////////////////////////////////// + +static Eina_Value +_efl_loop_task_exit(void *data, const Eina_Value v, + const Eina_Future *dead EINA_UNUSED) + +{ + Eo *obj = data; + + efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL); + efl_unref(obj); + return v; +} + +static void +_thread_exit_eval(Eo *obj, Efl_Thread_Data *pd) +{ + if ((pd->fd.out == -1) && /*(pd->fd.in == -1) &&*/ + (pd->exit_read) && (!pd->exit_called)) + { + Eina_Future *job; + Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS); + + pd->exit_called = EINA_TRUE; + efl_ref(obj); + job = eina_future_then(efl_loop_job(loop), _efl_loop_task_exit, obj); + efl_future_Eina_FutureXXX_then(loop, job); + } +} + +static void +_cb_thread_parent_out(void *data, const Efl_Event *event EINA_UNUSED) +{ + Eo *obj = data; + efl_io_reader_can_read_set(obj, EINA_TRUE); +} + +static void +_cb_thread_parent_in(void *data, const Efl_Event *event EINA_UNUSED) +{ + Eo *obj = data; + efl_io_writer_can_write_set(obj, EINA_TRUE); +} + +static void +_cb_thread_parent_ctrl_out(void *data, const Efl_Event *event EINA_UNUSED) +{ + Eo *obj = data; + Control_Data cmd; + ssize_t ret; + Efl_Thread_Data *pd = efl_data_scope_get(obj, MY_CLASS); + + if (!pd) return; + + cmd.command = 0; + cmd.data = 0; + ret = read(pd->ctrl.out, &cmd, sizeof(Control_Data)); + if (ret == sizeof(Control_Data)) + { + if (cmd.command == CMD_EXITED) + { + if (!pd->exit_read) + { + Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS); + + if (td) td->exit_code = cmd.data; + pd->exit_read = EINA_TRUE; + _thread_exit_eval(obj, pd); + } + } + } +} + +////////////////////////////////////////////////////////////////////////// + +static void +_thread_parent_read_listeners_modify(Efl_Thread_Data *pd, int mod) +{ + pd->read_listeners += mod; + + if (pd->fd.out_handler) + { + if ((pd->read_listeners == 0) && (mod < 0)) + efl_loop_handler_active_set + (pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_NONE); + else if ((pd->read_listeners == 1) && (mod > 0)) + efl_loop_handler_active_set + (pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_READ); + } +} + +static void +_cb_event_callback_add(void *data, const Efl_Event *event) +{ + Efl_Thread_Data *pd = data; + const Efl_Callback_Array_Item_Full *array = event->info; + int i; + + for (i = 0; array[i].desc != NULL; i++) + { + if (array[i].desc == EFL_LOOP_EVENT_ARGUMENTS) + { + Efl_Callback_Array_Item_Full *event_cb, *it; + int num; + + num = 0; + if (pd->event_cb) + { + for (it = pd->event_cb; it->func; it++) num++; + } + num++; + event_cb = realloc(pd->event_cb, (num + 1) * sizeof(Efl_Callback_Array_Item_Full)); + if (event_cb) + { + pd->event_cb = event_cb; + event_cb[num - 1] = array[i]; + event_cb[num].desc = NULL; + event_cb[num].priority = 0; + event_cb[num].func = NULL; + event_cb[num].user_data = NULL; + } + } + else if (array[i].desc == EFL_IO_READER_EVENT_CAN_READ_CHANGED) + _thread_parent_read_listeners_modify(pd, 1); + } +} + +static void +_cb_event_callback_del(void *data, const Efl_Event *event) +{ + Efl_Thread_Data *pd = data; + const Efl_Callback_Array_Item_Full *array = event->info; + int i; + + for (i = 0; array[i].desc != NULL; i++) + { + if (array[i].desc == EFL_LOOP_EVENT_ARGUMENTS) + { + Efl_Callback_Array_Item_Full *it; + + if (pd->event_cb) + { + Eina_Bool shuffle_down = EINA_FALSE; + + for (it = pd->event_cb; it->func; it++) + { + if ((it->desc == array[i].desc) && + (it->priority == array[i].priority) && + (it->func == array[i].func) && + (it->user_data == array[i].user_data)) + shuffle_down = EINA_TRUE; + if (shuffle_down) it[0] = it[1]; + } + } + } + else if (array[i].desc == EFL_IO_READER_EVENT_CAN_READ_CHANGED) + _thread_parent_read_listeners_modify(pd, -1); + } +} + +EFL_CALLBACKS_ARRAY_DEFINE(_event_callback_watch, + { EFL_EVENT_CALLBACK_ADD, _cb_event_callback_add }, + { EFL_EVENT_CALLBACK_DEL, _cb_event_callback_del }); + +////////////////////////////////////////////////////////////////////////// + +EOLIAN static Efl_Object * +_efl_thread_efl_object_constructor(Eo *obj, Efl_Thread_Data *pd) +{ + obj = efl_constructor(efl_super(obj, MY_CLASS)); + efl_event_callback_array_add(obj, _event_callback_watch(), pd); + pd->fd.in = -1; + pd->fd.out = -1; + pd->fd.can_write = EINA_TRUE; + pd->ctrl.in = -1; + pd->ctrl.out = -1; + return obj; +} + +EOLIAN static void +_efl_thread_efl_object_destructor(Eo *obj, Efl_Thread_Data *pd) +{ + if (pd->thdat) + { +/* we probably shouldn't do this... this simply has to orphan threads if they + * lose their parent. this stops shutdown from blocking. + // if exit response not read yet, read until fetched + if (!pd->exit_read) + { + Control_Data cmd; + ssize_t ret; + + // if it hasn't been asked to exit... ask it + if (!pd->end_sent) efl_task_end(obj); + cmd.command = 0; + cmd.data = 0; + ret = read(pd->ctrl.out, &cmd, sizeof(Control_Data)); + while (ret == sizeof(Control_Data)) + { + if (cmd.command == CMD_EXITED) + { + if (!pd->exit_read) + { + Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS); + + if (td) td->exit_code = cmd.data; + pd->exit_read = EINA_TRUE; + efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL); + break; + } + } + ret = read(pd->ctrl.out, &cmd, sizeof(Control_Data)); + } + } + */ + // stop and wait for thread to exit/join here + eina_thread_join(pd->thread); + efl_del(pd->fd.in_handler); + efl_del(pd->fd.out_handler); + efl_del(pd->ctrl.in_handler); + efl_del(pd->ctrl.out_handler); + close(pd->fd.in); + close(pd->fd.out); + close(pd->ctrl.in); + close(pd->ctrl.out); + pd->fd.in_handler = NULL; + pd->fd.out_handler = NULL; + pd->ctrl.in_handler = NULL; + pd->ctrl.out_handler = NULL; + pd->fd.in = -1; + pd->fd.out = -1; + pd->ctrl.in = -1; + pd->ctrl.out = -1; + free(pd->thdat); + } + free(pd->event_cb); + pd->event_cb = NULL; + efl_destructor(efl_super(obj, MY_CLASS)); +} + +EOLIAN static void +_efl_thread_efl_object_parent_set(Eo *obj, Efl_Thread_Data *pd, Efl_Object *parent) +{ + efl_parent_set(efl_super(obj, MY_CLASS), parent); + pd->loop = efl_provider_find(parent, EFL_LOOP_CLASS); +} + +EOLIAN static Eina_Bool +_efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd) +{ + Eina_Thread_Priority pri; + Thread_Data *thdat; + const char *name; + int pipe_to_thread[2]; + int pipe_from_thread[2]; + unsigned int argc, i, num; + Efl_Callback_Array_Item_Full *it; + + thdat = calloc(1, sizeof(Thread_Data)); + if (!thdat) return EINA_FALSE; + thdat->fd.in = -1; + thdat->fd.out = -1; + thdat->ctrl.in = -1; + thdat->ctrl.out = -1; + + if (pipe(pipe_to_thread) != 0) + { + ERR("Can't create to_thread pipe"); + free(thdat); + return EINA_FALSE; + } + if (pipe(pipe_from_thread) != 0) + { + ERR("Can't create from_thread pipe"); + close(pipe_to_thread[0]); + close(pipe_to_thread[1]); + free(thdat); + return EINA_FALSE; + } + thdat->fd.in = pipe_from_thread[1]; // write - input to parent + thdat->fd.out = pipe_to_thread [0]; // read - output from parent + pd->fd.in = pipe_to_thread [1]; // write - input to child + pd->fd.out = pipe_from_thread[0]; // read - output from child + eina_file_close_on_exec(pd->fd.in, EINA_TRUE); + eina_file_close_on_exec(pd->fd.out, EINA_TRUE); + eina_file_close_on_exec(thdat->fd.in, EINA_TRUE); + eina_file_close_on_exec(thdat->fd.out, EINA_TRUE); + fcntl(pd->fd.in, F_SETFL, O_NONBLOCK); + fcntl(pd->fd.out, F_SETFL, O_NONBLOCK); + fcntl(thdat->fd.in, F_SETFL, O_NONBLOCK); + fcntl(thdat->fd.out, F_SETFL, O_NONBLOCK); + pd->fd.in_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, pd->fd.in), + efl_event_callback_add + (efl_added, EFL_LOOP_HANDLER_EVENT_WRITE, _cb_thread_parent_in, obj)); + pd->fd.out_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, pd->fd.out), + efl_event_callback_add + (efl_added, EFL_LOOP_HANDLER_EVENT_READ, _cb_thread_parent_out, obj)); + if (pd->read_listeners > 0) + efl_loop_handler_active_set(pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_READ); + + if (pipe(pipe_to_thread) != 0) + { + ERR("Can't create to_thread control pipe"); + efl_del(pd->fd.in_handler); + efl_del(pd->fd.out_handler); + close(thdat->fd.in); + close(thdat->fd.out); + close(pd->fd.in); + close(pd->fd.out); + pd->fd.in_handler = NULL; + pd->fd.out_handler = NULL; + pd->fd.in = -1; + pd->fd.out = -1; + free(thdat); + return EINA_FALSE; + } + if (pipe(pipe_from_thread) != 0) + { + ERR("Can't create from_thread control pipe"); + efl_del(pd->fd.in_handler); + efl_del(pd->fd.out_handler); + close(pipe_to_thread[0]); + close(pipe_to_thread[1]); + close(thdat->fd.in); + close(thdat->fd.out); + close(pd->fd.in); + close(pd->fd.out); + pd->fd.in_handler = NULL; + pd->fd.out_handler = NULL; + pd->fd.in = -1; + pd->fd.out = -1; + free(thdat); + return EINA_FALSE; + } + thdat->ctrl.in = pipe_from_thread[1]; // write - input to parent + thdat->ctrl.out = pipe_to_thread [0]; // read - output from parent + pd->ctrl.in = pipe_to_thread [1]; // write - input to child + pd->ctrl.out = pipe_from_thread[0]; // read - output from child + // yes - these are blocking because we write and read very little + eina_file_close_on_exec(pd->ctrl.in, EINA_TRUE); + eina_file_close_on_exec(pd->ctrl.out, EINA_TRUE); + eina_file_close_on_exec(thdat->ctrl.in, EINA_TRUE); + eina_file_close_on_exec(thdat->ctrl.out, EINA_TRUE); + pd->ctrl.in_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, pd->ctrl.in)); + pd->ctrl.out_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, pd->ctrl.out), + efl_event_callback_add + (efl_added, EFL_LOOP_HANDLER_EVENT_READ, _cb_thread_parent_ctrl_out, obj), + efl_loop_handler_active_set + (efl_added, EFL_LOOP_HANDLER_FLAGS_READ)); + + switch (efl_task_priority_get(obj)) + { + case EFL_TASK_PRIORITY_BACKGROUND: + pri = EINA_THREAD_IDLE; + break; + case EFL_TASK_PRIORITY_HIGH: + case EFL_TASK_PRIORITY_ULTRA: + pri = EINA_THREAD_URGENT; + break; + case EFL_TASK_PRIORITY_LOW: + pri = EINA_THREAD_BACKGROUND; + break; + case EFL_TASK_PRIORITY_NORMAL: + default: + pri = EINA_THREAD_NORMAL; + break; + } + name = efl_name_get(obj); + if (name) thdat->name = eina_stringshare_add(name); + + argc = efl_task_arg_count_get(obj); + if (argc > 0) + { + thdat->args.argc = argc; + thdat->args.argv = malloc(argc * sizeof(char *)); + if (thdat->args.argv) + { + for (i = 0; i < argc; i++) + { + const char *argv = efl_task_arg_value_get(obj, i); + if (argv) + thdat->args.argv[i] = eina_stringshare_add(argv); + else + thdat->args.argv[i] = NULL; + } + } + // XXX: if malloc fails? + } + if (pd->event_cb) + { + num = 0; + for (it = pd->event_cb; it->func; it++) num++; + thdat->event_cb = malloc((num + 1) * sizeof(Efl_Callback_Array_Item_Full)); + if (thdat->event_cb) + memcpy(thdat->event_cb, pd->event_cb, + (num + 1) * sizeof(Efl_Callback_Array_Item_Full)); + // XXX: if malloc fails? + } + + // env data - ignore as other end will share same env + + if (!eina_thread_create(&(pd->thread), pri, -1, _efl_thread_main, thdat)) + { + for (i = 0; i < thdat->args.argc; i++) + eina_stringshare_del(thdat->args.argv[i]); + free(thdat->args.argv); + efl_del(pd->fd.in_handler); + efl_del(pd->fd.out_handler); + efl_del(pd->ctrl.in_handler); + efl_del(pd->ctrl.out_handler); + close(pd->fd.in); + close(pd->fd.out); + close(pd->ctrl.in); + close(pd->ctrl.out); + close(thdat->fd.in); + close(thdat->fd.out); + close(thdat->ctrl.in); + close(thdat->ctrl.out); + free(thdat); + pd->fd.in_handler = NULL; + pd->fd.out_handler = NULL; + pd->ctrl.in_handler = NULL; + pd->ctrl.out_handler = NULL; + pd->fd.in = -1; + pd->fd.out = -1; + pd->ctrl.in = -1; + pd->ctrl.out = -1; + return EINA_FALSE; + } + pd->thdat = thdat; + return EINA_TRUE; +} + +EOLIAN static void +_efl_thread_efl_task_end(Eo *obj EINA_UNUSED, Efl_Thread_Data *pd) +{ + if (pd->end_sent) return; + if (pd->thdat) + { + Control_Data cmd; + + pd->end_sent = EINA_TRUE; + cmd.command = CMD_EXIT; + cmd.data = 0; + write(pd->ctrl.in, &cmd, sizeof(Control_Data)); + } +} + +EOLIAN static Eina_Error +_efl_thread_efl_io_closer_close(Eo *obj, Efl_Thread_Data *pd) +{ + if (!pd->thdat) return 0; + EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(obj), EBADF); + efl_io_writer_can_write_set(obj, EINA_FALSE); + efl_io_reader_can_read_set(obj, EINA_FALSE); + efl_io_reader_eos_set(obj, EINA_TRUE); + if (pd->fd.in >= 0) close(pd->fd.in); + if (pd->fd.out >= 0) close(pd->fd.out); + if (pd->fd.in_handler) efl_del(pd->fd.in_handler); + if (pd->fd.out_handler) efl_del(pd->fd.out_handler); + pd->fd.in = -1; + pd->fd.out = -1; + pd->fd.in_handler = NULL; + pd->fd.out_handler = NULL; + return 0; +} + +EOLIAN static Eina_Bool +_efl_thread_efl_io_closer_closed_get(Eo *obj EINA_UNUSED, Efl_Thread_Data *pd) +{ + if ((pd->fd.in == -1) && (pd->fd.out == -1)) return EINA_TRUE; + return EINA_FALSE; +} + +EOLIAN static Eina_Error +_efl_thread_efl_io_reader_read(Eo *obj, Efl_Thread_Data *pd, Eina_Rw_Slice *rw_slice) +{ + ssize_t r; + + errno = 0; + if (pd->fd.out == -1) goto err; + + do + { + errno = 0; + r = read(pd->fd.out, rw_slice->mem, rw_slice->len); + if (r == -1) + { + if (errno == EINTR) continue; + goto err; + } + } + while (r == -1); + + rw_slice->len = r; + if (r == 0) + { + efl_io_reader_can_read_set(obj, EINA_FALSE); + efl_io_reader_eos_set(obj, EINA_TRUE); + close(pd->fd.out); + pd->fd.out = -1; + efl_del(pd->fd.out_handler); + pd->fd.out_handler = NULL; + _thread_exit_eval(obj, pd); + return EPIPE; + } + return 0; +err: + if ((pd->fd.out != -1) && (errno != EAGAIN)) + { + close(pd->fd.out); + pd->fd.out = -1; + efl_del(pd->fd.out_handler); + pd->fd.out_handler = NULL; + } + rw_slice->len = 0; + rw_slice->mem = NULL; + efl_io_reader_can_read_set(obj, EINA_FALSE); + _thread_exit_eval(obj, pd); + return EINVAL; +} + +EOLIAN static void +_efl_thread_efl_io_reader_can_read_set(Eo *obj, Efl_Thread_Data *pd, Eina_Bool can_read) +{ + Eina_Bool old = efl_io_reader_can_read_get(obj); + if (old == can_read) return; + pd->fd.can_read = can_read; + if (!pd->fd.out_handler) return; + if (can_read) + efl_loop_handler_active_set(pd->fd.out_handler, 0); + else + efl_loop_handler_active_set(pd->fd.out_handler, + EFL_LOOP_HANDLER_FLAGS_READ); + efl_event_callback_call(obj, EFL_IO_READER_EVENT_CAN_READ_CHANGED, NULL); +} + +EOLIAN static Eina_Bool +_efl_thread_efl_io_reader_can_read_get(Eo *obj EINA_UNUSED, Efl_Thread_Data *pd) +{ + return pd->fd.can_read; +} + +EOLIAN static void +_efl_thread_efl_io_reader_eos_set(Eo *obj, Efl_Thread_Data *pd, Eina_Bool is_eos) +{ + Eina_Bool old = efl_io_reader_eos_get(obj); + if (old == is_eos) return; + + pd->fd.eos_read = is_eos; + if (!is_eos) return; + if (pd->fd.out_handler) + efl_loop_handler_active_set(pd->fd.out_handler, 0); + efl_event_callback_call(obj, EFL_IO_READER_EVENT_EOS, NULL); +} + +EOLIAN static Eina_Bool +_efl_thread_efl_io_reader_eos_get(Eo *obj EINA_UNUSED, Efl_Thread_Data *pd) +{ + return pd->fd.eos_read; +} + +EOLIAN static Eina_Error +_efl_thread_efl_io_writer_write(Eo *obj, Efl_Thread_Data *pd, Eina_Slice *slice, Eina_Slice *remaining) +{ + ssize_t r; + + errno = 0; + if (pd->fd.in == -1) goto err; + + do + { + errno = 0; + r = write(pd->fd.in, slice->mem, slice->len); + if (r == -1) + { + if (errno == EINTR) continue; + goto err; + } + } + while (r == -1); + + if (remaining) + { + remaining->len = slice->len - r; + remaining->bytes = slice->bytes + r; + } + slice->len = r; + + if ((slice) && (slice->len > 0)) + efl_io_writer_can_write_set(obj, EINA_FALSE); + if (r == 0) + { + close(pd->fd.in); + pd->fd.in = -1; + efl_del(pd->fd.in_handler); + pd->fd.in_handler = NULL; + _thread_exit_eval(obj, pd); + return EPIPE; + } + return 0; +err: + if ((pd->fd.in != -1) && (errno != EAGAIN)) + { + close(pd->fd.in); + pd->fd.in = -1; + efl_del(pd->fd.in_handler); + pd->fd.in_handler = NULL; + } + if (remaining) *remaining = *slice; + slice->len = 0; + slice->mem = NULL; + efl_io_writer_can_write_set(obj, EINA_FALSE); + _thread_exit_eval(obj, pd); + return EINVAL; +} + +EOLIAN static void +_efl_thread_efl_io_writer_can_write_set(Eo *obj, Efl_Thread_Data *pd, Eina_Bool can_write) +{ + Eina_Bool old = efl_io_writer_can_write_get(obj); + if (old == can_write) return; + pd->fd.can_write = can_write; + if (can_write) + efl_loop_handler_active_set(pd->fd.in_handler, 0); + else + efl_loop_handler_active_set(pd->fd.in_handler, + EFL_LOOP_HANDLER_FLAGS_WRITE); + efl_event_callback_call(obj, EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED, NULL); +} + +EOLIAN static Eina_Bool +_efl_thread_efl_io_writer_can_write_get(Eo *obj EINA_UNUSED, Efl_Thread_Data *pd) +{ + return pd->fd.can_write; +} + +////////////////////////////////////////////////////////////////////////// + +#include "efl_thread.eo.c" diff --git a/src/lib/ecore/efl_thread.eo b/src/lib/ecore/efl_thread.eo index 63b7292131..214c0fd07f 100644 --- a/src/lib/ecore/efl_thread.eo +++ b/src/lib/ecore/efl_thread.eo @@ -8,5 +8,15 @@ class Efl.Thread (Efl.Task) implements { Efl.Object.constructor; Efl.Object.destructor; + Efl.Object.parent { set; } + Efl.Task.run; + Efl.Task.end; + Efl.Io.Closer.close; + Efl.Io.Closer.closed { get; } + Efl.Io.Reader.read; + Efl.Io.Reader.can_read { get; set; } + Efl.Io.Reader.eos { get; set; } + Efl.Io.Writer.write; + Efl.Io.Writer.can_write { get; set; } } } diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c index 67ab7e9fd0..4348da8084 100644 --- a/src/lib/ecore_evas/ecore_evas.c +++ b/src/lib/ecore_evas/ecore_evas.c @@ -3195,7 +3195,7 @@ _ecore_evas_animator_fallback(void *data) static void _check_animator_event_catcher_add(void *data, const Efl_Event *event) { - const Efl_Callback_Array_Item *array = event->info; + const Efl_Callback_Array_Item_Full *array = event->info; Ecore_Evas *ee = data; int i; @@ -3229,7 +3229,7 @@ _check_animator_event_catcher_add(void *data, const Efl_Event *event) static void _check_animator_event_catcher_del(void *data, const Efl_Event *event) { - const Efl_Callback_Array_Item *array = event->info; + const Efl_Callback_Array_Item_Full *array = event->info; Ecore_Evas *ee = data; int i; diff --git a/src/lib/eina/eina_internal.h b/src/lib/eina/eina_internal.h index 9324118c91..83e6f5da61 100644 --- a/src/lib/eina/eina_internal.h +++ b/src/lib/eina/eina_internal.h @@ -71,6 +71,8 @@ struct _Eina_Vpath_Interface_User */ EAPI void __eina_promise_cancel_all(void); +EAPI void __eina_promise_cancel_data(void *data); + /** * Make the app specific paths accessable as virtual path * diff --git a/src/lib/eina/eina_promise.c b/src/lib/eina/eina_promise.c index c3b488d223..93e091bd9e 100644 --- a/src/lib/eina/eina_promise.c +++ b/src/lib/eina/eina_promise.c @@ -566,6 +566,27 @@ __eina_promise_cancel_all(void) eina_lock_release(&_pending_futures_lock); } +EAPI void +__eina_promise_cancel_data(void *data) +{ + Eina_List *del = NULL, *l; + Eina_Future *f; + + eina_lock_take(&_pending_futures_lock); + EINA_LIST_FOREACH(_pending_futures, l, f) + { + if (f->data == data) + { + del = eina_list_append(del, f); + } + } + EINA_LIST_FREE(del, f) + { + _eina_future_cancel(f, ECANCELED); + } + eina_lock_release(&_pending_futures_lock); +} + Eina_Bool eina_promise_shutdown(void) { diff --git a/src/lib/elementary/efl_ui_text.c b/src/lib/elementary/efl_ui_text.c index 98dda2afea..b8fa0ea20e 100644 --- a/src/lib/elementary/efl_ui_text.c +++ b/src/lib/elementary/efl_ui_text.c @@ -2975,9 +2975,10 @@ _efl_ui_text_efl_canvas_group_group_member_add(Eo *obj, Efl_Ui_Text_Data *sd, Ev static void _cb_added(void *data EINA_UNUSED, const Efl_Event *ev) { - const Efl_Callback_Array_Item *event = ev->info; + const Efl_Callback_Array_Item_Full *event = ev->info; EFL_UI_TEXT_DATA_GET(ev->object, sd); + // XXX: BUG - not walking the array until a NULL entry if (event->desc == EFL_UI_TEXT_EVENT_VALIDATE) sd->validators++; } @@ -2985,9 +2986,10 @@ _cb_added(void *data EINA_UNUSED, const Efl_Event *ev) static void _cb_deleted(void *data EINA_UNUSED, const Efl_Event *ev) { - const Efl_Callback_Array_Item *event = ev->info; + const Efl_Callback_Array_Item_Full *event = ev->info; EFL_UI_TEXT_DATA_GET(ev->object, sd); + // XXX: BUG - not walking the array until a NULL entry if (event->desc == EFL_UI_TEXT_EVENT_VALIDATE) sd->validators--; return; diff --git a/src/lib/elementary/efl_ui_win.c b/src/lib/elementary/efl_ui_win.c index f9f9723d8e..0059cfb9b0 100644 --- a/src/lib/elementary/efl_ui_win.c +++ b/src/lib/elementary/efl_ui_win.c @@ -1904,7 +1904,7 @@ _elm_win_evas_device_changed(void *data, static void _win_event_add_cb(void *data, const Efl_Event *ev) { - const Efl_Callback_Array_Item *array = ev->info; + const Efl_Callback_Array_Item_Full *array = ev->info; Efl_Ui_Win_Data *sd = data; Efl_Ui_Win *win = ev->object; int i; @@ -2035,7 +2035,7 @@ _win_event_add_cb(void *data, const Efl_Event *ev) static void _win_event_del_cb(void *data, const Efl_Event *ev) { - const Efl_Callback_Array_Item *array = ev->info; + const Efl_Callback_Array_Item_Full *array = ev->info; Efl_Ui_Win_Data *sd = data; Efl_Ui_Win *win = ev->object; int i; @@ -2177,7 +2177,7 @@ _win_paused(void *data, const Efl_Event *ev) _paused_windows++; if (_elm_win_count == _paused_windows) - efl_event_callback_call(efl_loop_get(ev->object), EFL_LOOP_EVENT_PAUSE, NULL); + efl_event_callback_call(efl_loop_get(ev->object), EFL_APP_EVENT_PAUSE, NULL); } EFL_CALLBACKS_ARRAY_DEFINE(_elm_win_tracking, @@ -2205,7 +2205,7 @@ _elm_win_resume(void *data, const Efl_Event *ev) sd->paused = EINA_FALSE; if (_elm_win_count == _paused_windows) - efl_event_callback_call(efl_loop_get(ev->object), EFL_LOOP_EVENT_RESUME, NULL); + efl_event_callback_call(efl_loop_get(ev->object), EFL_APP_EVENT_RESUME, NULL); _paused_windows--; } @@ -2831,7 +2831,7 @@ _efl_ui_win_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Win_Data *sd) _elm_win_state_eval_queue(); if (_elm_win_count == _paused_windows) - efl_event_callback_call(efl_loop_get(obj), EFL_LOOP_EVENT_PAUSE, NULL); + efl_event_callback_call(efl_loop_get(obj), EFL_APP_EVENT_PAUSE, NULL); if (sd->ee) { @@ -5474,7 +5474,7 @@ _efl_ui_win_efl_object_finalize(Eo *obj, Efl_Ui_Win_Data *sd) obj = _elm_win_finalize_internal(obj, sd, sd->name, sd->type); if (!obj) return NULL; obj = efl_finalize(efl_super(obj, MY_CLASS)); - if (obj && resume) efl_event_callback_call(efl_loop_get(obj), EFL_LOOP_EVENT_RESUME, NULL); + if (obj && resume) efl_event_callback_call(efl_loop_get(obj), EFL_APP_EVENT_RESUME, NULL); return obj; } diff --git a/src/lib/elementary/elm_entry.c b/src/lib/elementary/elm_entry.c index 0b61f24124..eff0bbfa65 100644 --- a/src/lib/elementary/elm_entry.c +++ b/src/lib/elementary/elm_entry.c @@ -4061,9 +4061,10 @@ elm_entry_add(Evas_Object *parent) static void _cb_added(void *data EINA_UNUSED, const Efl_Event *ev) { - const Efl_Callback_Array_Item *event = ev->info; + const Efl_Callback_Array_Item_Full *event = ev->info; ELM_ENTRY_DATA_GET(ev->object, sd); + // XXX: BUG - not walking the array until a NULL entry if (event->desc == ELM_ENTRY_EVENT_VALIDATE) sd->validators++; } @@ -4071,9 +4072,10 @@ _cb_added(void *data EINA_UNUSED, const Efl_Event *ev) static void _cb_deleted(void *data EINA_UNUSED, const Efl_Event *ev) { - const Efl_Callback_Array_Item *event = ev->info; + const Efl_Callback_Array_Item_Full *event = ev->info; ELM_ENTRY_DATA_GET(ev->object, sd); + // XXX: BUG - not walking the array until a NULL entry if (event->desc == ELM_ENTRY_EVENT_VALIDATE) sd->validators--; return; diff --git a/src/lib/elementary/elm_main.c b/src/lib/elementary/elm_main.c index 646b2ee474..82efe0a3c7 100644 --- a/src/lib/elementary/elm_main.c +++ b/src/lib/elementary/elm_main.c @@ -927,8 +927,8 @@ static void (*qre_terminate)(void *data, EFL_CALLBACKS_ARRAY_DEFINE(_qre_main_ex, { EFL_LOOP_EVENT_ARGUMENTS, qre_main }, - { EFL_LOOP_EVENT_PAUSE, qre_pause }, - { EFL_LOOP_EVENT_RESUME, qre_resume }, + { EFL_APP_EVENT_PAUSE, qre_pause }, + { EFL_APP_EVENT_RESUME, qre_resume }, { EFL_EVENT_DEL, qre_terminate }); EAPI Eina_Bool @@ -1304,12 +1304,12 @@ elm_policy_set(unsigned int policy, { if (value == ELM_POLICY_EXIT_WINDOWS_DEL) { - efl_event_callback_add(efl_main_loop_get(), EFL_LOOP_EVENT_TERMINATE, + efl_event_callback_add(efl_main_loop_get(), EFL_APP_EVENT_TERMINATE, _on_terminate, NULL); } else { - efl_event_callback_del(efl_main_loop_get(), EFL_LOOP_EVENT_TERMINATE, + efl_event_callback_del(efl_main_loop_get(), EFL_APP_EVENT_TERMINATE, _on_terminate, NULL); } } diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 441b3789fc..7c20daaccb 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -241,10 +241,25 @@ typedef short Efl_Callback_Priority; */ typedef struct _Efl_Callback_Array_Item { - const Efl_Event_Description *desc; /**< The event description. */ - Efl_Event_Cb func; /**< The callback function. */ + const Efl_Event_Description *desc; /**< The event description. */ + Efl_Event_Cb func; /**< The callback function. */ } Efl_Callback_Array_Item; + +/** + * @struct _Efl_Callback_Array_Item_Full + * @brief An item provided by EFL_EVENT_CALLBACK_ADD/EFL_EVENT_CALLBACK_DEL. + * + * See also EFL_EVENT_CALLBACK_ADD EFL_EVENT_CALLBACK_DEL. + */ +typedef struct _Efl_Callback_Array_Item_Full +{ + const Efl_Event_Description *desc; /**< The event description. */ + Efl_Callback_Priority priority; /** < The priorit of the event */ + Efl_Event_Cb func; /**< The callback function. */ + void *user_data; /**< The user data pointer to be passed to the func */ +} Efl_Callback_Array_Item_Full; + /** * @brief Add a callback for an event with a specific priority. * diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c index ca38e7b171..f1eff91f3e 100644 --- a/src/lib/eo/eo_base_class.c +++ b/src/lib/eo/eo_base_class.c @@ -1228,7 +1228,8 @@ _efl_object_event_callback_priority_add(Eo *obj, Efl_Object_Data *pd, Efl_Event_Cb func, const void *user_data) { - const Efl_Callback_Array_Item arr[] = { {desc, func}, {NULL, NULL}}; + const Efl_Callback_Array_Item_Full arr[] = + { {desc, priority, func, (void *)user_data}, {NULL, 0, NULL, NULL}}; Eo_Callback_Description *cb = _eo_callback_new(); // very unlikely so improve l1 instr cache by using goto @@ -1265,7 +1266,7 @@ EOAPI EFL_FUNC_BODYV(efl_event_callback_priority_add, static void _efl_object_event_callback_clean(Eo *obj, Efl_Object_Data *pd, - const Efl_Callback_Array_Item *array, + const Efl_Callback_Array_Item_Full *array, Eo_Callback_Description **cb) { (*cb)->delete_me = EINA_TRUE; @@ -1295,7 +1296,8 @@ _efl_object_event_callback_del(Eo *obj, Efl_Object_Data *pd, ((*cb)->items.item.func == func) && ((*cb)->func_data == user_data)) { - const Efl_Callback_Array_Item arr[] = { {desc, func}, {NULL, NULL}}; + const Efl_Callback_Array_Item_Full arr[] = + { {desc, (*cb)->priority, func, (*cb)->func_data}, {NULL, 0, NULL, NULL}}; _efl_object_event_callback_clean(obj, pd, arr, cb); return EINA_TRUE; @@ -1318,9 +1320,9 @@ _efl_object_event_callback_array_priority_add(Eo *obj, Efl_Object_Data *pd, const void *user_data) { Eo_Callback_Description *cb = _eo_callback_new(); -#if defined(EFL_EVENT_SPECIAL_SKIP) || defined(EO_DEBUG) const Efl_Callback_Array_Item *it; -#endif + unsigned int num, i; + Efl_Callback_Array_Item_Full *ev_array; #ifdef EO_DEBUG const Efl_Callback_Array_Item *prev; #endif @@ -1363,7 +1365,21 @@ _efl_object_event_callback_array_priority_add(Eo *obj, Efl_Object_Data *pd, } #endif - efl_event_callback_call(obj, EFL_EVENT_CALLBACK_ADD, (void *)array); + num = 0; + for (it = cb->items.item_array; it->func; it++) num++; + ev_array = alloca((num + 1) * sizeof(Efl_Callback_Array_Item_Full)); + for (i = 0, it = cb->items.item_array; it->func; it++, i++) + { + ev_array[i].desc = cb->items.item_array[i].desc; + ev_array[i].priority = cb->priority; + ev_array[i].func = cb->items.item_array[i].func; + ev_array[i].user_data = cb->func_data; + } + ev_array[i].desc = NULL; + ev_array[i].priority = 0; + ev_array[i].func = NULL; + ev_array[i].user_data = NULL; + efl_event_callback_call(obj, EFL_EVENT_CALLBACK_ADD, ev_array); return EINA_TRUE; @@ -1384,17 +1400,35 @@ _efl_object_event_callback_array_del(Eo *obj, Efl_Object_Data *pd, const void *user_data) { Eo_Callback_Description **cb; - unsigned int i; + unsigned int j; - for (cb = pd->callbacks, i = 0; - i < pd->callbacks_count; - cb++, i++) + for (cb = pd->callbacks, j = 0; + j < pd->callbacks_count; + cb++, j++) { if (!(*cb)->delete_me && ((*cb)->items.item_array == array) && ((*cb)->func_data == user_data)) { - _efl_object_event_callback_clean(obj, pd, array, cb); + const Efl_Callback_Array_Item *it; + unsigned int num, i; + Efl_Callback_Array_Item_Full *ev_array; + + num = 0; + for (it = (*cb)->items.item_array; it->func; it++) num++; + ev_array = alloca((num + 1) * sizeof(Efl_Callback_Array_Item_Full)); + for (i = 0, it = (*cb)->items.item_array; it->func; it++, i++) + { + ev_array[i].desc = (*cb)->items.item_array[i].desc; + ev_array[i].priority = (*cb)->priority; + ev_array[i].func = (*cb)->items.item_array[i].func; + ev_array[i].user_data = (*cb)->func_data; + } + ev_array[i].desc = NULL; + ev_array[i].priority = 0; + ev_array[i].func = NULL; + ev_array[i].user_data = NULL; + _efl_object_event_callback_clean(obj, pd, ev_array, cb); return EINA_TRUE; } } diff --git a/src/lib/evas/canvas/evas_callbacks.c b/src/lib/evas/canvas/evas_callbacks.c index 4f63c2323d..8896dea691 100644 --- a/src/lib/evas/canvas/evas_callbacks.c +++ b/src/lib/evas/canvas/evas_callbacks.c @@ -700,7 +700,7 @@ _animator_repeater(void *data, const Efl_Event *event) static void _check_event_catcher_add(void *data, const Efl_Event *event) { - const Efl_Callback_Array_Item *array = event->info; + const Efl_Callback_Array_Item_Full *array = event->info; Evas_Object_Protected_Data *obj = data; Evas_Callback_Type type = EVAS_CALLBACK_LAST; int i; @@ -728,7 +728,7 @@ _check_event_catcher_add(void *data, const Efl_Event *event) static void _check_event_catcher_del(void *data, const Efl_Event *event) { - const Efl_Callback_Array_Item *array = event->info; + const Efl_Callback_Array_Item_Full *array = event->info; Evas_Object_Protected_Data *obj = data; int i; diff --git a/src/tests/ecore/ecore_test_ecore.c b/src/tests/ecore/ecore_test_ecore.c index 492c2aa033..6fd95738f4 100644 --- a/src/tests/ecore/ecore_test_ecore.c +++ b/src/tests/ecore/ecore_test_ecore.c @@ -896,11 +896,11 @@ START_TEST(ecore_test_efl_app_version) ecore_init(); - loop = efl_loop_main_get(EFL_LOOP_CLASS); + loop = efl_app_loop_main_get(EFL_APP_CLASS); fail_if(!efl_isa(loop, EFL_LOOP_CLASS)); efl_build_version_set(EFL_VERSION_MAJOR, EFL_VERSION_MINOR, 0, 0, NULL, EFL_BUILD_ID); - ver = efl_loop_app_efl_version_get(loop); + ver = efl_app_build_efl_version_get(loop); fail_if(!ver); fail_if(ver->major != EFL_VERSION_MAJOR); fail_if(ver->minor != EFL_VERSION_MINOR); @@ -909,7 +909,7 @@ START_TEST(ecore_test_efl_app_version) fail_if(ver->flavor); fail_if(!eina_streq(ver->build_id, EFL_BUILD_ID)); - ver = efl_loop_efl_version_get(loop); + ver = efl_app_efl_version_get(loop); fail_if(!ver); fail_if(ver->major != EFL_VERSION_MAJOR); fail_if(ver->minor != EFL_VERSION_MINOR); diff --git a/src/tests/elementary/efl_ui_suite.c b/src/tests/elementary/efl_ui_suite.c index 629bb10faa..d2269b68a7 100644 --- a/src/tests/elementary/efl_ui_suite.c +++ b/src/tests/elementary/efl_ui_suite.c @@ -32,10 +32,10 @@ START_TEST(efl_ui_test_init) _efl_startup_time = ecore_time_unix_get(); _EFL_APP_VERSION_SET(); fail_if(!ecore_init()); - efl_event_callback_add(efl_app_main_loop_get(efl_app_get()), EFL_LOOP_EVENT_ARGUMENTS, efl_main, NULL); + efl_event_callback_add(efl_app_get(), EFL_LOOP_EVENT_ARGUMENTS, efl_main, NULL); fail_if(!ecore_init_ex(argc, argv)); __EFL_MAIN_CONSTRUCTOR; - ret__ = efl_loop_begin(efl_app_main_loop_get(efl_app_get())); + ret__ = efl_loop_begin(efl_app_get()); real__ = efl_loop_exit_code_process(ret__); __EFL_MAIN_DESTRUCTOR; ecore_shutdown_ex(); diff --git a/src/tests/eo/signals/signals_simple.c b/src/tests/eo/signals/signals_simple.c index 9449c3f8c0..0e016dc550 100644 --- a/src/tests/eo/signals/signals_simple.c +++ b/src/tests/eo/signals/signals_simple.c @@ -32,7 +32,7 @@ void _cb_added(void *data EINA_UNUSED, const Efl_Event *event) { Simple_Public_Data *pd = efl_data_scope_get(event->object, MY_CLASS); - const Efl_Callback_Array_Item *callback_array = event->info; + const Efl_Callback_Array_Item_Full *callback_array = event->info; if (callback_array->desc != EV_A_CHANGED) return; @@ -46,7 +46,7 @@ void _cb_deled(void *data EINA_UNUSED, const Efl_Event *event) { Simple_Public_Data *pd = efl_data_scope_get(event->object, MY_CLASS); - const Efl_Callback_Array_Item *callback_array = event->info; + const Efl_Callback_Array_Item_Full *callback_array = event->info; if (callback_array->desc != EV_A_CHANGED) return; diff --git a/src/tests/eo/suite/eo_test_general.c b/src/tests/eo/suite/eo_test_general.c index e475889e95..18684f1ad2 100644 --- a/src/tests/eo/suite/eo_test_general.c +++ b/src/tests/eo/suite/eo_test_general.c @@ -181,11 +181,9 @@ _eo_signals_efl_del_cb(void *_data EINA_UNUSED, const Efl_Event *event EINA_UNUS void _eo_signals_cb_added_deled(void *data, const Efl_Event *event) { - const Efl_Callback_Array_Item *callback_array = event->info; - const Efl_Callback_Array_Item *(*callback_data)(void) = data; + const Efl_Callback_Array_Item_Full *callback_array = event->info; - fail_if((callback_data() != callback_array) && - (callback_array->func != _eo_signals_cb_added_deled)); + fail_if(callback_array->func != _eo_signals_cb_added_deled); } EFL_CALLBACKS_ARRAY_DEFINE(_eo_signals_callbacks,