summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2019-09-10 23:01:19 +0100
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2019-09-10 23:09:30 +0100
commitd1890f5eca0b439c902999716ed0a49634e848a1 (patch)
tree7416686da1e12e12d1e729a109b1c611eea7f95b
parentad48272ffe89bc3604a8c2c6fef41d1114b346b0 (diff)
efl task - change exit method to use normal event for multiple listeners
we couldn't have multilpe listeners before. now we can. better this way. have to do this now because i can't mark efl task as @beta without taking out massive wads of efl with it.
-rw-r--r--src/examples/ecore/efl_exe.c20
-rw-r--r--src/examples/ecore/efl_thread.c17
-rw-r--r--src/lib/ecore/efl_exe.c90
-rw-r--r--src/lib/ecore/efl_loop.c16
-rw-r--r--src/lib/ecore/efl_task.eo3
-rw-r--r--src/lib/ecore/efl_thread.c51
6 files changed, 52 insertions, 145 deletions
diff --git a/src/examples/ecore/efl_exe.c b/src/examples/ecore/efl_exe.c
index b5466763f8..1458d0630d 100644
--- a/src/examples/ecore/efl_exe.c
+++ b/src/examples/ecore/efl_exe.c
@@ -5,8 +5,8 @@
5#include <Eo.h> 5#include <Eo.h>
6#include <Efl_Core.h> 6#include <Efl_Core.h>
7 7
8static void _read_change(void *data EINA_UNUSED, const Efl_Event *ev); 8static void _read_change(void *data EINA_UNUSED, const Efl_Event *ev);
9static Eina_Value _task_exit(void *data, Eina_Value v, const Eina_Future *dead EINA_UNUSED); 9static void _task_exit(void *data EINA_UNUSED, const Efl_Event *ev);
10 10
11static void 11static void
12_read_change(void *data EINA_UNUSED, const Efl_Event *ev) 12_read_change(void *data EINA_UNUSED, const Efl_Event *ev)
@@ -27,16 +27,19 @@ _read_change(void *data EINA_UNUSED, const Efl_Event *ev)
27 } 27 }
28} 28}
29 29
30static Eina_Value 30static void
31_task_exit(void *data, Eina_Value v, const Eina_Future *dead EINA_UNUSED) 31_task_exit(void *data EINA_UNUSED, const Efl_Event *ev)
32{ 32{
33 // called when the task says it has completed and exited. 33 // called when the task says it has completed and exited.
34 // all output to read has stopped 34 // all output to read has stopped
35 Eo *obj = data; 35 Eo *obj = ev->object;
36 printf("--- [%p] EXITED exit_code=%i\n", obj, efl_task_exit_code_get(obj)); 36 printf("--- [%p] EXITED exit_code=%i\n", obj, efl_task_exit_code_get(obj));
37 efl_loop_quit(efl_provider_find(obj, EFL_LOOP_CLASS), eina_value_int_init(99)); 37 efl_loop_quit(efl_provider_find(obj, EFL_LOOP_CLASS), eina_value_int_init(99));
38 efl_del(obj); 38 // exe auto deleted at this point like efl threads. more convenient as
39 return v; 39 // you don't need to remember to delete them yourself if launching
40 // lots of commands - this is how ecore_exe worked. so listen to the
41 // exit event (or del event) if you care about this... or ref it to keep
42 // it around longer.
40} 43}
41 44
42EAPI_MAIN void 45EAPI_MAIN void
@@ -55,7 +58,8 @@ efl_main(void *data EINA_UNUSED, const Efl_Event *ev)
55 efl_exe_env_set(efl_added, env), 58 efl_exe_env_set(efl_added, env),
56 efl_task_flags_set(efl_added, EFL_TASK_FLAGS_USE_STDOUT | EFL_TASK_FLAGS_USE_STDIN), 59 efl_task_flags_set(efl_added, EFL_TASK_FLAGS_USE_STDOUT | EFL_TASK_FLAGS_USE_STDIN),
57 efl_event_callback_add(efl_added, EFL_IO_READER_EVENT_CAN_READ_CHANGED, _read_change, NULL), 60 efl_event_callback_add(efl_added, EFL_IO_READER_EVENT_CAN_READ_CHANGED, _read_change, NULL),
58 eina_future_then(efl_task_run(efl_added), _task_exit, efl_added) 61 efl_event_callback_add(efl_added, EFL_TASK_EVENT_EXIT, _task_exit, NULL),
62 efl_task_run(efl_added)
59 ); 63 );
60 efl_unref(env); 64 efl_unref(env);
61 65
diff --git a/src/examples/ecore/efl_thread.c b/src/examples/ecore/efl_thread.c
index fe300dc6c5..301bf5c06d 100644
--- a/src/examples/ecore/efl_thread.c
+++ b/src/examples/ecore/efl_thread.c
@@ -8,7 +8,7 @@
8static void _th_read_change(void *data EINA_UNUSED, const Efl_Event *ev); 8static void _th_read_change(void *data EINA_UNUSED, const Efl_Event *ev);
9static void _th_main(void *data EINA_UNUSED, const Efl_Event *ev); 9static void _th_main(void *data EINA_UNUSED, const Efl_Event *ev);
10static void _read_change(void *data EINA_UNUSED, const Efl_Event *ev); 10static void _read_change(void *data EINA_UNUSED, const Efl_Event *ev);
11static Eina_Value _task_exit(void *data, Eina_Value v, const Eina_Future *dead EINA_UNUSED); 11static void _task_exit(void *data EINA_UNUSED, const Efl_Event *ev);
12 12
13//////////////////////////////////////////////////////////////////////////// 13////////////////////////////////////////////////////////////////////////////
14//// thread side of code 14//// thread side of code
@@ -85,7 +85,8 @@ _th_main(void *data EINA_UNUSED, const Efl_Event *ev)
85 efl_task_flags_set(efl_added, EFL_TASK_FLAGS_USE_STDOUT | EFL_TASK_FLAGS_USE_STDIN | EFL_TASK_FLAGS_EXIT_WITH_PARENT), 85 efl_task_flags_set(efl_added, EFL_TASK_FLAGS_USE_STDOUT | EFL_TASK_FLAGS_USE_STDIN | EFL_TASK_FLAGS_EXIT_WITH_PARENT),
86 efl_event_callback_add(efl_added, EFL_LOOP_EVENT_ARGUMENTS, _th_main, NULL), 86 efl_event_callback_add(efl_added, EFL_LOOP_EVENT_ARGUMENTS, _th_main, NULL),
87 efl_event_callback_add(efl_added, EFL_IO_READER_EVENT_CAN_READ_CHANGED, _read_change, NULL), 87 efl_event_callback_add(efl_added, EFL_IO_READER_EVENT_CAN_READ_CHANGED, _read_change, NULL),
88 eina_future_then(efl_task_run(efl_added), _task_exit, efl_added) 88 efl_event_callback_add(efl_added, EFL_TASK_EVENT_EXIT, _task_exit, NULL),
89 efl_task_run(efl_added)
89 ); 90 );
90 91
91 char *buf2 = "hello-out-there2 "; 92 char *buf2 = "hello-out-there2 ";
@@ -117,18 +118,17 @@ _read_change(void *data EINA_UNUSED, const Efl_Event *ev)
117 } 118 }
118} 119}
119 120
120static Eina_Value 121static void
121_task_exit(void *data, Eina_Value v, const Eina_Future *dead EINA_UNUSED) 122_task_exit(void *data EINA_UNUSED, const Efl_Event *ev)
122{ 123{
123 // called when the task says it has completed and exited. 124 // called when the task says it has completed and exited.
124 // all output to read has stopped 125 // all output to read has stopped
125 Eo *obj = data; 126 Eo *obj = ev->object;
126 printf("--- [%p] EXITED exit_code=%i outdata=%p\n", obj, efl_task_exit_code_get(obj), efl_threadio_outdata_get(obj)); 127 printf("--- [%p] EXITED exit_code=%i outdata=%p\n", obj, efl_task_exit_code_get(obj), efl_threadio_outdata_get(obj));
127 // thread object will be automatically deleted after as long as 128 // thread object will be automatically deleted after as long as
128 // EFL_TASK_FLAGS_EXIT_WITH_PAREN is set on task flags, and this is 129 // EFL_TASK_FLAGS_EXIT_WITH_PARENT is set on task flags, and this is
129 // actually the default unless you change the flags to be something 130 // actually the default unless you change the flags to be something
130 // else. if you don't use this then the task/thread becomes orphaned 131 // else. if you don't use this then the task/thread becomes orphaned
131 return v;
132} 132}
133 133
134//////////////////////////////////////////////////////////////////////////// 134////////////////////////////////////////////////////////////////////////////
@@ -181,7 +181,8 @@ efl_main(void *data EINA_UNUSED, const Efl_Event *ev)
181 efl_task_flags_set(efl_added, EFL_TASK_FLAGS_USE_STDOUT | EFL_TASK_FLAGS_USE_STDIN | EFL_TASK_FLAGS_EXIT_WITH_PARENT), 181 efl_task_flags_set(efl_added, EFL_TASK_FLAGS_USE_STDOUT | EFL_TASK_FLAGS_USE_STDIN | EFL_TASK_FLAGS_EXIT_WITH_PARENT),
182 efl_event_callback_add(efl_added, EFL_LOOP_EVENT_ARGUMENTS, _th_main, NULL), 182 efl_event_callback_add(efl_added, EFL_LOOP_EVENT_ARGUMENTS, _th_main, NULL),
183 efl_event_callback_add(efl_added, EFL_IO_READER_EVENT_CAN_READ_CHANGED, _read_change, NULL), 183 efl_event_callback_add(efl_added, EFL_IO_READER_EVENT_CAN_READ_CHANGED, _read_change, NULL),
184 eina_future_then(efl_task_run(efl_added), _task_exit, efl_added) 184 efl_event_callback_add(efl_added, EFL_TASK_EVENT_EXIT, _task_exit, NULL),
185 efl_task_run(efl_added)
185 ); 186 );
186 187
187 char *buf2 = "hello-out-there "; 188 char *buf2 = "hello-out-there ";
diff --git a/src/lib/ecore/efl_exe.c b/src/lib/ecore/efl_exe.c
index 21dfdf50d1..6dcac4ffe0 100644
--- a/src/lib/ecore/efl_exe.c
+++ b/src/lib/ecore/efl_exe.c
@@ -56,7 +56,6 @@ struct _Efl_Exe_Data
56 Eina_Bool can_write : 1; 56 Eina_Bool can_write : 1;
57 } fd; 57 } fd;
58#else 58#else
59 Eina_Promise *promise;
60 Eo *exit_handler; 59 Eo *exit_handler;
61 pid_t pid; 60 pid_t pid;
62 struct { 61 struct {
@@ -178,47 +177,8 @@ _exe_exit_eval(Eo *obj, Efl_Exe_Data *pd)
178 (pd->fd.exited_read == -1) && (!pd->exit_called)) 177 (pd->fd.exited_read == -1) && (!pd->exit_called))
179 { 178 {
180 pd->exit_called = EINA_TRUE; 179 pd->exit_called = EINA_TRUE;
181 if (pd->promise) 180 efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL);
182 { 181 efl_del(obj);
183 Eina_Promise *p = pd->promise;
184 int exit_code = efl_task_exit_code_get(obj);
185 if ((exit_code != 0) && (!(efl_task_flags_get(obj) &
186 EFL_TASK_FLAGS_NO_EXIT_CODE_ERROR)))
187 {
188 Eina_Error err = exit_code + 1000000;
189 // Code Meaning Example Comments
190 // ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
191 // 1 Catchall for general errors let "var1 = 1/0" Miscellaneous errors, such as "divide by zero" and other impermissible operations
192 // 2 Misuse of shell builtins empty_function() {} Missing keyword or command, or permission problem (and diff return code on a failed binary file comparison).
193 // 126 Command invoked cannot execute /dev/null Permission problem or command is not an executable
194 // 127 "command not found" illegal_command Possible problem with $PATH or a typo
195 // 128 Invalid argument to exit exit 3.14159 exit takes only integer args in the range 0 - 255 (see first footnote)
196 // 128+n Fatal error signal "n" kill -9 $PPID $? returns 137 (128 + 9)
197 // 130 Script terminated by Control-C Ctl-C Control-C is fatal error signal 2, (130 = 128 + 2, see above)
198 // 255* Exit status out of range exit -1 exit takes only integer args in the range 0 - 255
199 //
200 // According to the above table, exit codes 1 - 2,
201 // 126 - 165, and 255 [1] have special meanings, and
202 // should therefore be avoided for user-specified exit
203 // parameters. Ending a script with exit 127 would
204 // certainly cause confusion when troubleshooting (is
205 // the error code a "command not found" or a user-defined
206 // one?). However, many scripts use an exit 1 as a general
207 // bailout-upon-error. Since exit code 1 signifies so many
208 // possible errors, it is not particularly useful in
209 // debugging.
210 if (exit_code == 1 ) err = EBADF;
211 else if (exit_code == 2 ) err = EDOM;
212 else if (exit_code == 126) err = ENOEXEC;
213 else if (exit_code == 127) err = ENOENT;
214 else if (exit_code == 128) err = EINVAL;
215 else if (exit_code == 129) err = EFAULT;
216 else if (exit_code == 130) err = EINTR;
217 else if ((exit_code >= 131) && (exit_code <= 165)) err = EFAULT;
218 eina_promise_reject(p, err);
219 }
220 else eina_promise_resolve(p, eina_value_int_init(exit_code));
221 }
222 } 182 }
223} 183}
224 184
@@ -268,24 +228,6 @@ _cb_exe_in(void *data, const Efl_Event *event EINA_UNUSED)
268 Eo *obj = data; 228 Eo *obj = data;
269 efl_io_writer_can_write_set(obj, EINA_TRUE); 229 efl_io_writer_can_write_set(obj, EINA_TRUE);
270} 230}
271
272static Eina_Value
273_run_cancel_cb(Efl_Loop_Consumer *consumer, void *data EINA_UNUSED, Eina_Error error)
274{
275 if (error == ECANCELED) efl_task_end(consumer);
276
277 return eina_value_error_init(error);
278}
279
280static void
281_run_clean_cb(Efl_Loop_Consumer *consumer EINA_UNUSED,
282 void *data,
283 const Eina_Future *dead_future EINA_UNUSED)
284{
285 Efl_Exe_Data *pd = data;
286 pd->promise = NULL;
287}
288
289#endif 231#endif
290 232
291////////////////////////////////////////////////////////////////////////// 233//////////////////////////////////////////////////////////////////////////
@@ -399,7 +341,7 @@ _efl_exe_efl_task_priority_get(const Eo *obj EINA_UNUSED, Efl_Exe_Data *pd)
399 return pri; 341 return pri;
400} 342}
401 343
402EOLIAN static Eina_Future * 344EOLIAN static Eina_Bool
403_efl_exe_efl_task_run(Eo *obj, Efl_Exe_Data *pd) 345_efl_exe_efl_task_run(Eo *obj, Efl_Exe_Data *pd)
404{ 346{
405#ifdef _WIN32 347#ifdef _WIN32
@@ -414,20 +356,20 @@ _efl_exe_efl_task_run(Eo *obj, Efl_Exe_Data *pd)
414 int pipe_exited[2]; 356 int pipe_exited[2];
415 int ret; 357 int ret;
416 358
417 if (pd->run) return NULL; 359 if (pd->run) return EINA_FALSE;
418 if (pd->pid != -1) return NULL; 360 if (pd->pid != -1) return EINA_FALSE;
419 if (!td) return NULL; 361 if (!td) return EINA_FALSE;
420 362
421 // get a cmdline to run 363 // get a cmdline to run
422 cmd = efl_core_command_line_command_get(obj); 364 cmd = efl_core_command_line_command_get(obj);
423 if (!cmd) return NULL; 365 if (!cmd) return EINA_FALSE;
424 366
425 ret = pipe(pipe_exited); 367 ret = pipe(pipe_exited);
426 if (EINA_UNLIKELY(ret != 0)) 368 if (EINA_UNLIKELY(ret != 0))
427 { 369 {
428 const int error = errno; 370 const int error = errno;
429 ERR("pipe() failed: %s", strerror(error)); 371 ERR("pipe() failed: %s", strerror(error));
430 return NULL; 372 return EINA_FALSE;
431 } 373 }
432 374
433 pd->fd.exited_read = pipe_exited[0]; 375 pd->fd.exited_read = pipe_exited[0];
@@ -442,7 +384,7 @@ _efl_exe_efl_task_run(Eo *obj, Efl_Exe_Data *pd)
442 { 384 {
443 const int error = errno; 385 const int error = errno;
444 ERR("pipe() failed: %s", strerror(error)); 386 ERR("pipe() failed: %s", strerror(error));
445 return NULL; 387 return EINA_FALSE;
446 } 388 }
447 pd->fd.in = pipe_stdin[1]; 389 pd->fd.in = pipe_stdin[1];
448 if (fcntl(pd->fd.in, F_SETFL, O_NONBLOCK) < 0) 390 if (fcntl(pd->fd.in, F_SETFL, O_NONBLOCK) < 0)
@@ -461,7 +403,7 @@ _efl_exe_efl_task_run(Eo *obj, Efl_Exe_Data *pd)
461 { 403 {
462 const int error = errno; 404 const int error = errno;
463 ERR("pipe() failed: %s", strerror(error)); 405 ERR("pipe() failed: %s", strerror(error));
464 return NULL; 406 return EINA_FALSE;
465 } 407 }
466 pd->fd.out = pipe_stdout[0]; 408 pd->fd.out = pipe_stdout[0];
467 if (fcntl(pd->fd.out, F_SETFL, O_NONBLOCK) < 0) 409 if (fcntl(pd->fd.out, F_SETFL, O_NONBLOCK) < 0)
@@ -488,7 +430,7 @@ _efl_exe_efl_task_run(Eo *obj, Efl_Exe_Data *pd)
488 { 430 {
489 _close_fds(pd); 431 _close_fds(pd);
490 _ecore_signal_pid_unlock(); 432 _ecore_signal_pid_unlock();
491 return NULL; 433 return EINA_FALSE;
492 } 434 }
493 // register this pid in the core sigchild/pid exit code watcher 435 // register this pid in the core sigchild/pid exit code watcher
494 _ecore_signal_pid_register(pd->pid, pd->fd.exited_write); 436 _ecore_signal_pid_register(pd->pid, pd->fd.exited_write);
@@ -502,11 +444,7 @@ _efl_exe_efl_task_run(Eo *obj, Efl_Exe_Data *pd)
502 EFL_LOOP_HANDLER_FLAGS_READ)); 444 EFL_LOOP_HANDLER_FLAGS_READ));
503 _ecore_signal_pid_unlock(); 445 _ecore_signal_pid_unlock();
504 pd->run = EINA_TRUE; 446 pd->run = EINA_TRUE;
505 pd->promise = efl_loop_promise_new(obj); 447 return EINA_TRUE;
506 return efl_future_then(obj, eina_future_new(pd->promise),
507 .data = pd,
508 .error = _run_cancel_cb,
509 .free = _run_clean_cb);
510 } 448 }
511 // this code is in the child here, and is temporary setup until we 449 // this code is in the child here, and is temporary setup until we
512 // exec() the child to replace everything. 450 // exec() the child to replace everything.
@@ -609,7 +547,7 @@ _efl_exe_efl_task_run(Eo *obj, Efl_Exe_Data *pd)
609 (errno == ENOEXEC) || (errno == ENOMEM)) 547 (errno == ENOEXEC) || (errno == ENOMEM))
610 exit(126); 548 exit(126);
611 exit(127); 549 exit(127);
612 return NULL; 550 return EINA_FALSE;
613#endif 551#endif
614} 552}
615 553
@@ -651,7 +589,7 @@ _efl_exe_efl_object_destructor(Eo *obj, Efl_Exe_Data *pd)
651{ 589{
652#ifdef _WIN32 590#ifdef _WIN32
653#else 591#else
654 if (pd->promise) 592 if (!pd->exit_called)
655 ERR("Exe being destroyed while child has not exited yet."); 593 ERR("Exe being destroyed while child has not exited yet.");
656 if (pd->fd.exited_read >= 0) 594 if (pd->fd.exited_read >= 0)
657 { 595 {
diff --git a/src/lib/ecore/efl_loop.c b/src/lib/ecore/efl_loop.c
index 17a2835396..e40dbef3f0 100644
--- a/src/lib/ecore/efl_loop.c
+++ b/src/lib/ecore/efl_loop.c
@@ -642,21 +642,11 @@ efl_build_version_set(int vmaj, int vmin, int vmic, int revision,
642 _app_efl_version.build_id = build_id ? strdup(build_id) : NULL; 642 _app_efl_version.build_id = build_id ? strdup(build_id) : NULL;
643} 643}
644 644
645EOLIAN static Eina_Future * 645EOLIAN static Eina_Bool
646_efl_loop_efl_task_run(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED) 646_efl_loop_efl_task_run(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
647{ 647{
648 Eina_Value *ret; 648 efl_loop_exit_code_process(efl_loop_begin(obj));
649 int real; 649 return EINA_TRUE;
650
651 ret = efl_loop_begin(obj);
652 real = efl_loop_exit_code_process(ret);
653 if (real == 0)
654 {
655 // we never return a valid future here because there is no loop
656 // any more to process the future callback as we would have quit
657 return NULL;
658 }
659 return NULL;
660} 650}
661 651
662EOLIAN static void 652EOLIAN static void
diff --git a/src/lib/ecore/efl_task.eo b/src/lib/ecore/efl_task.eo
index 6fd162bd90..caef983b3b 100644
--- a/src/lib/ecore/efl_task.eo
+++ b/src/lib/ecore/efl_task.eo
@@ -54,7 +54,7 @@ abstract Efl.Task extends Efl.Loop_Consumer
54 } 54 }
55 run @pure_virtual { 55 run @pure_virtual {
56 [[Actually run the task.]] 56 [[Actually run the task.]]
57 return: future<void> @move; [[A future triggered when task exits and is passed int exit code.]] 57 return: bool; [[On success in starting the task, return true, otherwise false]]
58 } 58 }
59 end @pure_virtual { 59 end @pure_virtual {
60 [[Request the task end (may send a signal or interrupt 60 [[Request the task end (may send a signal or interrupt
@@ -63,6 +63,7 @@ abstract Efl.Task extends Efl.Loop_Consumer
63 } 63 }
64 } 64 }
65 events { 65 events {
66 exit: void; [[Called when the task exits. You can pick up any information you need at this point such as exit_code etc.]]
66 } 67 }
67 implements { 68 implements {
68 Efl.Object.constructor; 69 Efl.Object.constructor;
diff --git a/src/lib/ecore/efl_thread.c b/src/lib/ecore/efl_thread.c
index 5211b541b4..f1378883df 100644
--- a/src/lib/ecore/efl_thread.c
+++ b/src/lib/ecore/efl_thread.c
@@ -68,7 +68,6 @@ struct _Efl_Thread_Data
68 Eina_Bool can_write : 1; 68 Eina_Bool can_write : 1;
69 } fd, ctrl; 69 } fd, ctrl;
70 int read_listeners; 70 int read_listeners;
71 Eina_Promise *promise;
72 Eo *loop; 71 Eo *loop;
73 Thread_Data *thdat; 72 Thread_Data *thdat;
74 Efl_Callback_Array_Item_Full *event_cb; 73 Efl_Callback_Array_Item_Full *event_cb;
@@ -363,15 +362,7 @@ _thread_exit_eval(Eo *obj, Efl_Thread_Data *pd)
363 { 362 {
364 pd->exit_called = EINA_TRUE; 363 pd->exit_called = EINA_TRUE;
365 if (pd->thdat) efl_threadio_outdata_set(obj, pd->thdat->outdata); 364 if (pd->thdat) efl_threadio_outdata_set(obj, pd->thdat->outdata);
366 if (pd->promise) 365 efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL);
367 {
368 Eina_Promise *p = pd->promise;
369 int exit_code = efl_task_exit_code_get(obj);
370 if ((exit_code != 0) && (!(efl_task_flags_get(obj) &
371 EFL_TASK_FLAGS_NO_EXIT_CODE_ERROR)))
372 eina_promise_reject(p, exit_code + 1000000);
373 else eina_promise_resolve(p, eina_value_int_init(exit_code));
374 }
375 efl_del(obj); 366 efl_del(obj);
376 } 367 }
377} 368}
@@ -448,22 +439,6 @@ _cb_thread_parent_ctrl_out(void *data, const Efl_Event *event EINA_UNUSED)
448 439
449////////////////////////////////////////////////////////////////////////// 440//////////////////////////////////////////////////////////////////////////
450 441
451static Eina_Value
452_run_cancel_cb(Efl_Loop_Consumer *consumer, void *data EINA_UNUSED, Eina_Error error)
453{
454 if (error == ECANCELED) efl_task_end(consumer);
455
456 return eina_value_error_init(error);
457}
458
459static void
460_run_clean_cb(Efl_Loop_Consumer *consumer EINA_UNUSED,void *data, const Eina_Future *dead_future EINA_UNUSED)
461{
462 Efl_Thread_Data *pd = data;
463
464 pd->promise = NULL;
465}
466
467static void 442static void
468_thread_parent_read_listeners_modify(Efl_Thread_Data *pd, int mod) 443_thread_parent_read_listeners_modify(Efl_Thread_Data *pd, int mod)
469{ 444{
@@ -613,7 +588,7 @@ _efl_thread_efl_object_finalize(Eo *obj, Efl_Thread_Data *pd EINA_UNUSED)
613EOLIAN static void 588EOLIAN static void
614_efl_thread_efl_object_destructor(Eo *obj, Efl_Thread_Data *pd) 589_efl_thread_efl_object_destructor(Eo *obj, Efl_Thread_Data *pd)
615{ 590{
616 if (pd->promise) 591 if (pd->exit_called)
617 ERR("Thread being destroyed while real worker has not exited yet."); 592 ERR("Thread being destroyed while real worker has not exited yet.");
618 if (pd->thdat) 593 if (pd->thdat)
619 { 594 {
@@ -664,7 +639,7 @@ _task_run_pipe_fail_clear(Thread_Data *thdat, Efl_Thread_Data *pd)
664 free(thdat); 639 free(thdat);
665} 640}
666 641
667EOLIAN static Eina_Future * 642EOLIAN static Eina_Bool
668_efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd) 643_efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd)
669{ 644{
670 Eina_Thread_Priority pri; 645 Eina_Thread_Priority pri;
@@ -676,10 +651,10 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd)
676 Efl_Callback_Array_Item_Full *it; 651 Efl_Callback_Array_Item_Full *it;
677 Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS); 652 Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS);
678 653
679 if (pd->run) return NULL; 654 if (pd->run) return EINA_FALSE;
680 if (!td) return NULL; 655 if (!td) return EINA_FALSE;
681 thdat = calloc(1, sizeof(Thread_Data)); 656 thdat = calloc(1, sizeof(Thread_Data));
682 if (!thdat) return NULL; 657 if (!thdat) return EINA_FALSE;
683 thdat->fd.in = -1; 658 thdat->fd.in = -1;
684 thdat->fd.out = -1; 659 thdat->fd.out = -1;
685 thdat->ctrl.in = -1; 660 thdat->ctrl.in = -1;
@@ -695,7 +670,7 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd)
695 { 670 {
696 ERR("Can't create to_thread pipe"); 671 ERR("Can't create to_thread pipe");
697 free(thdat); 672 free(thdat);
698 return NULL; 673 return EINA_FALSE;
699 } 674 }
700 } 675 }
701 if (td->flags & EFL_TASK_FLAGS_USE_STDOUT) 676 if (td->flags & EFL_TASK_FLAGS_USE_STDOUT)
@@ -709,7 +684,7 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd)
709 close(pipe_from_thread[1]); 684 close(pipe_from_thread[1]);
710 } 685 }
711 free(thdat); 686 free(thdat);
712 return NULL; 687 return EINA_FALSE;
713 } 688 }
714 } 689 }
715 if (td->flags & EFL_TASK_FLAGS_USE_STDIN) 690 if (td->flags & EFL_TASK_FLAGS_USE_STDIN)
@@ -752,7 +727,7 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd)
752 { 727 {
753 ERR("Can't create to_thread control pipe"); 728 ERR("Can't create to_thread control pipe");
754 _task_run_pipe_fail_clear(thdat, pd); 729 _task_run_pipe_fail_clear(thdat, pd);
755 return NULL; 730 return EINA_FALSE;
756 } 731 }
757 if (pipe(pipe_from_thread) != 0) 732 if (pipe(pipe_from_thread) != 0)
758 { 733 {
@@ -760,7 +735,7 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd)
760 _task_run_pipe_fail_clear(thdat, pd); 735 _task_run_pipe_fail_clear(thdat, pd);
761 close(pipe_to_thread[0]); 736 close(pipe_to_thread[0]);
762 close(pipe_to_thread[1]); 737 close(pipe_to_thread[1]);
763 return NULL; 738 return EINA_FALSE;
764 } 739 }
765 thdat->ctrl.in = pipe_from_thread[1]; // write - input to parent 740 thdat->ctrl.in = pipe_from_thread[1]; // write - input to parent
766 thdat->ctrl.out = pipe_to_thread [0]; // read - output from parent 741 thdat->ctrl.out = pipe_to_thread [0]; // read - output from parent
@@ -864,13 +839,11 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd)
864 pd->fd.out = -1; 839 pd->fd.out = -1;
865 pd->ctrl.in = -1; 840 pd->ctrl.in = -1;
866 pd->ctrl.out = -1; 841 pd->ctrl.out = -1;
867 return NULL; 842 return EINA_FALSE;
868 } 843 }
869 pd->thdat = thdat; 844 pd->thdat = thdat;
870 pd->run = EINA_TRUE; 845 pd->run = EINA_TRUE;
871 pd->promise = efl_loop_promise_new(obj); 846 return EINA_TRUE;
872 return efl_future_then(obj, eina_future_new(pd->promise),
873 .data = pd, .error = _run_cancel_cb, .free = _run_clean_cb);
874} 847}
875 848
876EOLIAN static void 849EOLIAN static void