evtloop_event.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * Copyright (C) 2019-2020 Alibaba Group Holding Limited
  3. */
  4. #include <stdlib.h>
  5. #include <stdbool.h>
  6. #include <errno.h>
  7. #include <aos/yloop.h>
  8. #include <aos/list.h>
  9. #include "evtloop_main.h"
  10. #ifndef DEBUG_MALLOC
  11. #define DEBUG_MALLOC malloc
  12. #endif
  13. #ifndef DEBUG_FREE
  14. #define DEBUG_FREE free
  15. #endif
  16. extern int event_write(const void *buf, size_t len);
  17. extern int event_read(void *buf, size_t len);
  18. extern int event_poll(void *reader, bool setup, void *sem);
  19. void * g_current_event_cb = NULL;
  20. typedef struct {
  21. dlist_t node;
  22. aos_event_cb cb;
  23. void *private_data;
  24. uint16_t type_filter;
  25. } local_event_list_node_t;
  26. static dlist_t g_local_event_list = AOS_DLIST_INIT(g_local_event_list);
  27. static int input_add_event(input_event_t *event)
  28. {
  29. return event_write(event, sizeof(*event));
  30. }
  31. static void handle_events(input_event_t *event)
  32. {
  33. if (event->type == EV_RPC) {
  34. aos_call_t handler = (aos_call_t)event->value;
  35. void *arg = (void *)event->extra;
  36. handler(arg);
  37. return;
  38. }
  39. if (event->type == EV_SYS && event->code == CODE_NULL && event->value == VALUE_NULL) {
  40. return;
  41. } else if (event->type == EV_ALL && event->code == CODE_NULL && event->value == VALUE_NULL) {
  42. //LOGD("loop", "loop run test");
  43. return;
  44. }
  45. local_event_list_node_t *event_node = NULL;
  46. dlist_for_each_entry(&g_local_event_list, event_node, local_event_list_node_t, node) {
  47. if (event_node->type_filter != EV_ALL
  48. && event_node->type_filter != event->type) {
  49. continue;
  50. }
  51. g_current_event_cb = event_node->cb;
  52. (event_node->cb)(event, event_node->private_data);
  53. g_current_event_cb = NULL;
  54. }
  55. }
  56. void event_read_cb(void)
  57. {
  58. input_event_t event;
  59. int ret = event_read(&event, sizeof(event));
  60. if (ret == sizeof(event)) {
  61. handle_events(&event);
  62. }
  63. }
  64. int aos_post_event(uint16_t type, uint16_t code, unsigned long value)
  65. {
  66. int ret;
  67. input_event_t event = {
  68. .type = type,
  69. .code = code,
  70. .value = value,
  71. };
  72. ret = input_add_event(&event);
  73. if (ret < 0) {
  74. return -EPERM;
  75. }
  76. return 0;
  77. }
  78. #if 0
  79. int yoc_eloop_register_listener(aos_event_cb cb, void *priv)
  80. {
  81. local_event_list_node_t *event_node = DEBUG_MALLOC(sizeof(local_event_list_node_t));
  82. if (NULL == event_node) {
  83. return -ENOMEM;
  84. }
  85. event_node->cb = cb;
  86. event_node->private_data = priv;
  87. event_node->type_filter = EV_ALL;
  88. dlist_add_tail(&event_node->node, &g_local_event_list);
  89. return YOC_OK;
  90. }
  91. #endif
  92. void yoc_eloop_unregister_listener(aos_event_cb cb, void *priv)
  93. {
  94. local_event_list_node_t *event_node = NULL;
  95. dlist_for_each_entry(&g_local_event_list, event_node, local_event_list_node_t, node) {
  96. if (event_node->cb == cb && event_node->private_data == priv) {
  97. dlist_del(&event_node->node);
  98. DEBUG_FREE(event_node);
  99. return;
  100. }
  101. }
  102. }
  103. int aos_register_event_filter(uint16_t type, aos_event_cb cb, void *priv)
  104. {
  105. if (cb == NULL) {
  106. return -EINVAL;
  107. }
  108. local_event_list_node_t *event_node = DEBUG_MALLOC(sizeof(local_event_list_node_t));
  109. if (NULL == event_node) {
  110. return -ENOMEM;
  111. }
  112. event_node->cb = cb;
  113. event_node->private_data = priv;
  114. event_node->type_filter = type;
  115. dlist_add_tail(&event_node->node, &g_local_event_list);
  116. return 0;
  117. }
  118. int aos_unregister_event_filter(uint16_t type, aos_event_cb cb, void *priv)
  119. {
  120. local_event_list_node_t *event_node = NULL;
  121. if (cb == NULL) {
  122. return -EINVAL;
  123. }
  124. dlist_for_each_entry(&g_local_event_list, event_node, local_event_list_node_t, node) {
  125. if (event_node->cb == cb && event_node->private_data == priv && event_node->type_filter == type) {
  126. dlist_del(&event_node->node);
  127. DEBUG_FREE(event_node);
  128. return 0;
  129. }
  130. }
  131. return -ENOMEM;
  132. }
  133. /*
  134. * schedule a callback in yos loop main thread
  135. */
  136. int aos_schedule_call(aos_call_t fun, void *arg)
  137. {
  138. int ret;
  139. input_event_t event = {
  140. .type = EV_RPC,
  141. .value = (unsigned long)fun,
  142. .extra = (unsigned long)arg,
  143. };
  144. if (fun == NULL) {
  145. return -EINVAL;
  146. }
  147. ret = input_add_event(&event);
  148. if (ret < 0) {
  149. return -EPERM;
  150. }
  151. return 0;
  152. }