C   62
loops c
Guest on 8th February 2023 03:10:21 AM


  1. #define EFL_BETA_API_SUPPORT
  2. #define EFL_EO_API_SUPPORT
  3.  
  4. #include <fcntl.h>
  5. #include <unistd.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9.  
  10. #include <Eina.h>
  11. #include <Eo.h>
  12. #include <Efl_Core.h>
  13.  
  14. // use buffered stream io
  15. //#define BUFF
  16.  
  17. static int count = 0;
  18. static int pipes[1024];
  19. static int pnum = 0;
  20.  
  21. static double
  22. randtimeout(void)
  23. {
  24.    return 4.0;
  25.    return (double)((rand() % 5) + 1) / 3.0;
  26. }
  27.  
  28. static void
  29. exe_exit(void *data, const Efl_Event *event)
  30. {
  31.    printf("--- EXE %p [%s] exited with %i\n",
  32.           event->object,
  33.           efl_task_command_get(event->object),
  34.           efl_task_exit_code_get(event->object));
  35.    efl_del(event->object);
  36.    if (data) efl_del(data);
  37. }
  38.  
  39. static void
  40. exe_read_change(void *data, const Efl_Event *event)
  41. {
  42.    char buf[4096];
  43.    Eina_Rw_Slice rw_slice = EINA_SLICE_ARRAY(buf);
  44.  
  45.    while (efl_io_reader_can_read_get(event->object))
  46.      {
  47.         Eina_Error err = efl_io_reader_read(event->object, &rw_slice);
  48.         if (!err)
  49.           {
  50.              buf[rw_slice.len] = 0;
  51.              printf("--- READ [%p] [%s] ok %i bytes '%s'\n",
  52.                     event->object,
  53.                     efl_task_command_get(data),
  54.                     (int)rw_slice.len,
  55.                     buf);
  56.           }
  57.      }
  58. }
  59.  
  60. static void
  61. _write_cmd(Eo *obj, Eo *exe)
  62. {
  63.    char *buf = "hello-out-there\n";
  64.    Eina_Slice slice = { 17, buf };
  65.  
  66.    printf("--- DO WRITE\n");
  67.    Eina_Error err = efl_io_writer_write(obj, &slice, NULL);
  68.    if (!err)
  69.      {
  70.         printf("--- WRITE [%p] [%s] ok %i bytes\n",
  71.                obj, efl_task_command_get(exe), (int)slice.len);
  72.      }
  73. }
  74.  
  75. static void
  76. exe_write_change(void *data, const Efl_Event *event)
  77. {
  78.    if (efl_io_writer_can_write_get(event->object))
  79.      {
  80.         printf("--- CAN WRITE...\n");
  81.      }
  82. }
  83.  
  84. static Eina_Value
  85. timeout(void *data, const Eina_Value t, const Eina_Future *dead EINA_UNUSED)
  86. {
  87.    // handle cancellation
  88.    if (t.type == EINA_VALUE_TYPE_ERROR) return t;
  89.  
  90.    Eo *loop = data;
  91.    Eina_Future *f = efl_loop_timeout(loop, randtimeout());
  92.    eina_future_then(f, timeout, loop);
  93.    if (loop == efl_main_loop_get())
  94.      {
  95.         int i;
  96.  
  97.         printf("# timeout loop main\n");
  98.         count++;
  99.         if (count == 500)
  100.           {
  101.              Eina_Value exitstatus;
  102.  
  103.              eina_value_setup(&exitstatus, EINA_VALUE_TYPE_UCHAR);
  104.              eina_value_set(&exitstatus, EINA_TRUE);
  105.              efl_loop_quit(loop, exitstatus);
  106.           }
  107.         for (i = 0; i < pnum; i++)
  108.           {
  109.              char buf[2] = { 1, 2 };
  110.  
  111.              write(pipes[i], buf, 2);
  112.           }
  113.      }
  114.    else
  115.      printf("# timeout loop %p\n", loop);
  116.  
  117.    Eo *exe = efl_add(EFL_EXE_CLASS, loop,
  118. #ifndef BUFF
  119.                      efl_event_callback_add
  120.                        (efl_added, EFL_IO_READER_EVENT_CAN_READ_CHANGED,
  121.                         exe_read_change, efl_added),
  122.                      efl_event_callback_add
  123.                        (efl_added, EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED,
  124.                         exe_write_change, efl_added),
  125. #endif
  126.                      efl_exe_flags_set
  127.                        (efl_added,
  128.                         efl_exe_flags_get(efl_added) |
  129.                         EFL_EXE_FLAGS_USE_STDOUT | EFL_EXE_FLAGS_USE_STDIN),
  130.                      efl_task_command_set(efl_added, "./loop.sh"),
  131.                      efl_task_env_set(efl_added, "TZ", "GMT"),
  132.                      efl_task_run(efl_added)
  133.                     );
  134. #ifndef BUFF
  135.    efl_event_callback_add(exe, EFL_TASK_EVENT_EXIT, exe_exit, NULL),
  136.    _write_cmd(exe, exe);
  137. #endif
  138. #ifdef BUFF
  139.    size_t buffer_limit = 4;
  140.    Eo *stream = efl_add(EFL_IO_BUFFERED_STREAM_CLASS, exe,
  141.                         efl_io_buffered_stream_inner_io_set(efl_added, exe),
  142.                         efl_io_buffered_stream_max_queue_size_input_set(efl_added, buffer_limit),
  143.                         efl_io_buffered_stream_max_queue_size_output_set(efl_added, buffer_limit),
  144.                         efl_event_callback_add
  145.                           (efl_added, EFL_IO_READER_EVENT_CAN_READ_CHANGED,
  146.                            exe_read_change, exe));
  147.    efl_event_callback_add(exe, EFL_TASK_EVENT_EXIT, exe_exit, stream),
  148.    _write_cmd(stream, exe);
  149. #endif
  150.    return t;
  151. }
  152.  
  153. static void
  154. idle_enter(void *data, const Efl_Event *event)
  155. {
  156.    Eo *loop = event->object;
  157.  
  158.    if (loop == efl_main_loop_get())
  159.      printf("# idle,enter main\n");
  160.    else
  161.      printf("# idle,enter %p\n", loop);
  162. }
  163.  
  164. static void
  165. idle_exit(void *data, const Efl_Event *event)
  166. {
  167.    Eo *loop = event->object;
  168.  
  169.    if (loop == efl_main_loop_get())
  170.      printf("# idle,exit main\n");
  171.    else
  172.      printf("# idle,exit %p\n", loop);
  173. }
  174.  
  175. static void
  176. pipe_read(void *data, const Efl_Event *event)
  177. {
  178.    int fd = efl_loop_handler_fd_get(event->object);
  179.    char buf[1];
  180.    int ret;
  181.  
  182.    ret = read(fd, buf, 1);
  183.    printf("# read %p ... %i\n", data, ret);
  184. }
  185.  
  186. static void *
  187. thread_main(void *data, Eina_Thread th)
  188. {
  189.    Eo *loop;
  190.    Eina_Value *exitval;
  191.    Eina_Future *f;
  192.    int fd = (int)(uintptr_t)data;
  193.    Eo *handler;
  194.  
  195.    loop = efl_add(EFL_LOOP_CLASS, NULL);
  196.    if (!loop)
  197.      {
  198.         fprintf(stderr, "# Cannot create loop in thread %p\n", data);
  199.      }
  200.    handler = efl_add
  201.      (EFL_LOOP_HANDLER_CLASS, loop,
  202.       efl_loop_handler_active_set(efl_added, EFL_LOOP_HANDLER_FLAGS_READ),
  203.       efl_loop_handler_fd_set(efl_added, fd),
  204.       efl_event_callback_add(efl_added, EFL_LOOP_HANDLER_EVENT_READ,
  205.                              pipe_read, loop));
  206.    efl_event_callback_add(loop, EFL_LOOP_EVENT_IDLE_ENTER,
  207.                           idle_enter, NULL);
  208.    efl_event_callback_add(loop, EFL_LOOP_EVENT_IDLE_EXIT,
  209.                           idle_exit, NULL);
  210.    f = efl_loop_timeout(loop, randtimeout());
  211.    eina_future_then(f, timeout, loop);
  212.    exitval = efl_loop_begin(loop);
  213.    eina_value_free(exitval);
  214.    return NULL;
  215. }
  216.  
  217. static void
  218. thread_add(Eo *loop, int num)
  219. {
  220.    Eina_Bool ok;
  221.    Eina_Thread th;
  222.    int fds[2];
  223.  
  224.    pipe(fds);
  225.    pipes[pnum] = fds[1];
  226.    pnum++;
  227.    ok = eina_thread_create(&th, EINA_THREAD_NORMAL, -1, thread_main,
  228.                           (void *)(uintptr_t)fds[0]);
  229. }
  230.  
  231. EAPI_MAIN void
  232. efl_main(void *data EINA_UNUSED, const Efl_Event *ev)
  233. {
  234.    Eo *loop = ev->object;
  235.    Efl_Loop_Arguments *args = ev->info;
  236.    Eina_Future *f;
  237.  
  238.    efl_event_callback_add(loop, EFL_LOOP_EVENT_IDLE_ENTER,
  239.                           idle_enter, NULL);
  240.    efl_event_callback_add(loop, EFL_LOOP_EVENT_IDLE_EXIT,
  241.                           idle_exit, NULL);
  242.    if (eina_array_count(args->argv) == 1)
  243.      {
  244.         const char *s = eina_array_data_get(args->argv, 0);
  245.         int i, threads = atoi(s);
  246.  
  247.         for (i = 0; i < threads; i++)
  248.           {
  249.              thread_add(ev->object, i);
  250.           }
  251.      }
  252.    f = efl_loop_timeout(loop, randtimeout());
  253.    eina_future_then(f, timeout, loop);
  254. }
  255.  
  256. EFL_MAIN()

Raw Paste

Login or Register to edit or fork this paste. It's free.