#include #include #include #include #include static void _th_read_change(void *data EINA_UNUSED, const Efl_Event *ev); static void _th_main(void *data EINA_UNUSED, const Efl_Event *ev); static void _read_change(void *data EINA_UNUSED, const Efl_Event *ev); static void _task_exit(void *data EINA_UNUSED, const Efl_Event *ev); //////////////////////////////////////////////////////////////////////////// //// thread side of code static void _th_timeout(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED) { Eo *obj = data; printf("--- START EXIT [%p]\n", obj); efl_threadio_outdata_set(obj, (void *)0x9876); efl_loop_quit(obj, eina_value_int_init(99)); } static void _th_read_change(void *data EINA_UNUSED, const Efl_Event *ev) { // read input from parent thread/loop status chnaged - read what we can Eo *obj = ev->object; char buf[4096]; Eina_Rw_Slice rw_slice = EINA_SLICE_ARRAY(buf); while (efl_io_reader_can_read_get(obj)) { Eina_Error err = efl_io_reader_read(obj, &rw_slice); if (!err) { buf[rw_slice.len - 1] = 0; printf("--- TH READ [%p] [%s] ok %i bytes '%s'\n", obj, efl_core_command_line_command_get(obj), (int)rw_slice.len, buf); char *buf2 = "yes-im-here "; Eina_Slice slice = { strlen(buf2), .mem = buf2 }; Eina_Error err = efl_io_writer_write(obj, &slice, NULL); if (!err) { Eina_Accessor *args_access = efl_core_command_line_command_access(obj); printf("--- TH WRITE [%p] [%s] ok %i bytes\n", obj, efl_core_command_line_command_get(obj), (int)slice.len); void *s = ""; eina_accessor_data_get(args_access, 1, &s); if (!strcmp(s, "one")) efl_add(EFL_LOOP_TIMER_CLASS, obj, efl_loop_timer_interval_set(efl_added, 2.0), efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, _th_timeout, obj)); else efl_add(EFL_LOOP_TIMER_CLASS, obj, efl_loop_timer_interval_set(efl_added, 1.0), efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, _th_timeout, obj)); eina_accessor_free(args_access); } } } } static void _th_main(void *data EINA_UNUSED, const Efl_Event *ev) { // the "main function" of the thread thayt gets called with arguments // just like eflm_main for the main loop Eo *obj = ev->object; Eina_Accessor *args_access = efl_core_command_line_command_access(obj); void *s = "", *ss = ""; eina_accessor_data_get(args_access, 0, &s); eina_accessor_data_get(args_access, 1, &ss); printf("--- TH main %p, '%s' '%s' indata=%p\n", obj, (char *)s, (char *)ss, efl_threadio_indata_get(obj)); efl_event_callback_add (obj, EFL_IO_READER_EVENT_CAN_READ_CHANGED, _th_read_change, NULL); if (!strcmp(s, "one")) { Eina_Array *args = eina_array_new(1); eina_array_push(args, eina_stringshare_add("number")); eina_array_push(args, eina_stringshare_add("one")); Eo *obj2 = efl_add(EFL_THREAD_CLASS, obj, efl_threadio_indata_set(efl_added, (void *)0x1234), efl_core_command_line_command_array_set(efl_added, args), efl_task_flags_set(efl_added, EFL_TASK_FLAGS_USE_STDOUT | EFL_TASK_FLAGS_USE_STDIN | EFL_TASK_FLAGS_EXIT_WITH_PARENT), efl_event_callback_add(efl_added, EFL_LOOP_EVENT_ARGUMENTS, _th_main, NULL), efl_event_callback_add(efl_added, EFL_IO_READER_EVENT_CAN_READ_CHANGED, _read_change, NULL), efl_event_callback_add(efl_added, EFL_TASK_EVENT_EXIT, _task_exit, NULL), efl_task_run(efl_added) ); char *buf2 = "hello-out-there2 "; Eina_Slice slice = { strlen(buf2), .mem = buf2 }; Eina_Error err = efl_io_writer_write(obj2, &slice, NULL); if (!err) printf("--- WRITE [%p] [%s] ok %i bytes\n", obj2, efl_core_command_line_command_get(obj), (int)slice.len); } eina_accessor_free(args_access); } //////////////////////////////////////////////////////////////////////////// //// main loop side of code static void _read_change(void *data EINA_UNUSED, const Efl_Event *ev) { // read output from thread status chnaged - read what we can Eo *obj = ev->object; char buf[4096]; Eina_Rw_Slice rw_slice = EINA_SLICE_ARRAY(buf); while (efl_io_reader_can_read_get(obj)) { Eina_Error err = efl_io_reader_read(obj, &rw_slice); if (!err) { buf[rw_slice.len - 1] = 0; printf("--- READ [%p] [%s] ok %i bytes '%s'\n", obj, efl_core_command_line_command_get(obj), (int)rw_slice.len, buf); } } } static void _task_exit(void *data EINA_UNUSED, const Efl_Event *ev) { // called when the task says it has completed and exited. // all output to read has stopped Eo *obj = ev->object; printf("--- [%p] EXITED exit_code=%i outdata=%p\n", obj, efl_task_exit_code_get(obj), efl_threadio_outdata_get(obj)); // thread object will be automatically deleted after as long as // EFL_TASK_FLAGS_EXIT_WITH_PARENT is set on task flags, and this is // actually the default unless you change the flags to be something // else. if you don't use this then the task/thread becomes orphaned } //////////////////////////////////////////////////////////////////////////// // just main loop input handling static void _stdin_read_change(void *data EINA_UNUSED, const Efl_Event *ev) { // read output from thread status chnaged - read what we can Eo *obj = ev->object; char buf[4096]; Eina_Rw_Slice rw_slice = EINA_SLICE_ARRAY(buf); while (efl_io_reader_can_read_get(obj)) { Eina_Error err = efl_io_reader_read(obj, &rw_slice); if (!err) { buf[rw_slice.len - 1] = 0; printf("--- STDIN READ [%p] [%s] ok %i bytes '%s'\n", obj, efl_core_command_line_command_get(obj), (int)rw_slice.len, buf); } } } EAPI_MAIN void efl_main(void *data EINA_UNUSED, const Efl_Event *ev) { Eo *app = ev->object; int threads = 2, i; Eina_Accessor *args_access = efl_core_command_line_command_access(app); void *s; const Efl_Version *v = efl_app_build_efl_version_get(app); printf("--- EFL %i.%i.%i\n", v->major, v->minor, v->micro); s = NULL; eina_accessor_data_get(args_access, 2, &s); if (s && (!strcmp(s, "-stdinwatch"))) efl_event_callback_add(app, EFL_IO_READER_EVENT_CAN_READ_CHANGED, _stdin_read_change, NULL); s = NULL; eina_accessor_data_get(args_access, 1, &s); if (s) threads = atoi(s); for (i = 0; i < threads; i++) { Eina_Array *args = eina_array_new(1); eina_array_push(args, eina_stringshare_add("number")); eina_array_push(args, eina_stringshare_add("one")); Eo *obj = efl_add(EFL_THREAD_CLASS, app, efl_threadio_indata_set(efl_added, (void *)0x5678), efl_core_command_line_command_array_set(efl_added, args), efl_task_flags_set(efl_added, EFL_TASK_FLAGS_USE_STDOUT | EFL_TASK_FLAGS_USE_STDIN | EFL_TASK_FLAGS_EXIT_WITH_PARENT), efl_event_callback_add(efl_added, EFL_LOOP_EVENT_ARGUMENTS, _th_main, NULL), efl_event_callback_add(efl_added, EFL_IO_READER_EVENT_CAN_READ_CHANGED, _read_change, NULL), efl_event_callback_add(efl_added, EFL_TASK_EVENT_EXIT, _task_exit, NULL), efl_task_run(efl_added) ); char *buf2 = "hello-out-there "; Eina_Slice slice = { strlen(buf2), .mem = buf2 }; Eina_Error err = efl_io_writer_write(obj, &slice, NULL); if (!err) printf("--- WRITE [%p] [%s] ok %i bytes\n", obj, efl_core_command_line_command_get(obj), (int)slice.len); } } EFL_MAIN()