You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rdns_event.h 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * Copyright (c) 2014, Vsevolod Stakhov
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
  15. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
  18. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef RDNS_EVENT_H_
  26. #define RDNS_EVENT_H_
  27. #include <event.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include "rdns.h"
  31. #ifdef __cplusplus
  32. extern "C" {
  33. #endif
  34. static void* rdns_libevent_add_read (void *priv_data, int fd, void *user_data);
  35. static void rdns_libevent_del_read(void *priv_data, void *ev_data);
  36. static void* rdns_libevent_add_write (void *priv_data, int fd, void *user_data);
  37. static void rdns_libevent_del_write (void *priv_data, void *ev_data);
  38. static void* rdns_libevent_add_timer (void *priv_data, double after, void *user_data);
  39. static void* rdns_libevent_add_periodic (void *priv_data, double after,
  40. rdns_periodic_callback cb, void *user_data);
  41. static void rdns_libevent_del_periodic (void *priv_data, void *ev_data);
  42. static void rdns_libevent_repeat_timer (void *priv_data, void *ev_data);
  43. static void rdns_libevent_del_timer (void *priv_data, void *ev_data);
  44. struct rdns_event_periodic_cbdata {
  45. struct event *ev;
  46. rdns_periodic_callback cb;
  47. void *cbdata;
  48. };
  49. static void
  50. rdns_bind_libevent (struct rdns_resolver *resolver, struct event_base *ev_base)
  51. {
  52. struct rdns_async_context ev_ctx = {
  53. .add_read = rdns_libevent_add_read,
  54. .del_read = rdns_libevent_del_read,
  55. .add_write = rdns_libevent_add_write,
  56. .del_write = rdns_libevent_del_write,
  57. .add_timer = rdns_libevent_add_timer,
  58. .add_periodic = rdns_libevent_add_periodic,
  59. .del_periodic = rdns_libevent_del_periodic,
  60. .repeat_timer = rdns_libevent_repeat_timer,
  61. .del_timer = rdns_libevent_del_timer,
  62. .cleanup = NULL
  63. }, *nctx;
  64. /* XXX: never got freed */
  65. nctx = malloc (sizeof (struct rdns_async_context));
  66. if (nctx != NULL) {
  67. memcpy (nctx, &ev_ctx, sizeof (struct rdns_async_context));
  68. nctx->data = ev_base;
  69. }
  70. rdns_resolver_async_bind (resolver, nctx);
  71. }
  72. static void
  73. rdns_libevent_read_event (int fd, short what, void *ud)
  74. {
  75. rdns_process_read (fd, ud);
  76. }
  77. static void
  78. rdns_libevent_write_event (int fd, short what, void *ud)
  79. {
  80. rdns_process_write (fd, ud);
  81. }
  82. static void
  83. rdns_libevent_timer_event (int fd, short what, void *ud)
  84. {
  85. rdns_process_timer (ud);
  86. }
  87. static void
  88. rdns_libevent_periodic_event (int fd, short what, void *ud)
  89. {
  90. struct rdns_event_periodic_cbdata *cbdata = ud;
  91. cbdata->cb (cbdata->cbdata);
  92. }
  93. static void*
  94. rdns_libevent_add_read (void *priv_data, int fd, void *user_data)
  95. {
  96. struct event *ev;
  97. ev = malloc (sizeof (struct event));
  98. if (ev != NULL) {
  99. event_set (ev, fd, EV_READ | EV_PERSIST, rdns_libevent_read_event, user_data);
  100. event_base_set (priv_data, ev);
  101. event_add (ev, NULL);
  102. }
  103. return ev;
  104. }
  105. static void
  106. rdns_libevent_del_read(void *priv_data, void *ev_data)
  107. {
  108. struct event *ev = ev_data;
  109. if (ev != NULL) {
  110. event_del (ev);
  111. free (ev);
  112. }
  113. }
  114. static void*
  115. rdns_libevent_add_write (void *priv_data, int fd, void *user_data)
  116. {
  117. struct event *ev;
  118. ev = malloc (sizeof (struct event));
  119. if (ev != NULL) {
  120. event_set (ev, fd, EV_WRITE | EV_PERSIST,
  121. rdns_libevent_write_event, user_data);
  122. event_base_set (priv_data, ev);
  123. event_add (ev, NULL);
  124. }
  125. return ev;
  126. }
  127. static void
  128. rdns_libevent_del_write (void *priv_data, void *ev_data)
  129. {
  130. struct event *ev = ev_data;
  131. if (ev != NULL) {
  132. event_del (ev);
  133. free (ev);
  134. }
  135. }
  136. #define rdns_event_double_to_tv(dbl, tv) do { \
  137. (tv)->tv_sec = (int)(dbl); \
  138. (tv)->tv_usec = ((dbl) - (int)(dbl))*1000*1000; \
  139. } while(0)
  140. static void*
  141. rdns_libevent_add_timer (void *priv_data, double after, void *user_data)
  142. {
  143. struct event *ev;
  144. struct timeval tv;
  145. ev = malloc (sizeof (struct event));
  146. if (ev != NULL) {
  147. rdns_event_double_to_tv (after, &tv);
  148. event_set (ev, -1, EV_TIMEOUT|EV_PERSIST, rdns_libevent_timer_event, user_data);
  149. event_base_set (priv_data, ev);
  150. event_add (ev, &tv);
  151. }
  152. return ev;
  153. }
  154. static void*
  155. rdns_libevent_add_periodic (void *priv_data, double after,
  156. rdns_periodic_callback cb, void *user_data)
  157. {
  158. struct event *ev;
  159. struct timeval tv;
  160. struct rdns_event_periodic_cbdata *cbdata = NULL;
  161. ev = malloc (sizeof (struct event));
  162. if (ev != NULL) {
  163. cbdata = malloc (sizeof (struct rdns_event_periodic_cbdata));
  164. if (cbdata != NULL) {
  165. rdns_event_double_to_tv (after, &tv);
  166. cbdata->cb = cb;
  167. cbdata->cbdata = user_data;
  168. cbdata->ev = ev;
  169. event_set (ev, -1, EV_TIMEOUT|EV_PERSIST, rdns_libevent_periodic_event, cbdata);
  170. event_base_set (priv_data, ev);
  171. event_add (ev, &tv);
  172. }
  173. else {
  174. free (ev);
  175. return NULL;
  176. }
  177. }
  178. return cbdata;
  179. }
  180. static void
  181. rdns_libevent_del_periodic (void *priv_data, void *ev_data)
  182. {
  183. struct rdns_event_periodic_cbdata *cbdata = ev_data;
  184. if (cbdata != NULL) {
  185. event_del (cbdata->ev);
  186. free (cbdata->ev);
  187. free (cbdata);
  188. }
  189. }
  190. static void
  191. rdns_libevent_repeat_timer (void *priv_data, void *ev_data)
  192. {
  193. /* XXX: libevent hides timeval, so timeouts are persistent here */
  194. }
  195. #undef rdns_event_double_to_tv
  196. static void
  197. rdns_libevent_del_timer (void *priv_data, void *ev_data)
  198. {
  199. struct event *ev = ev_data;
  200. if (ev != NULL) {
  201. event_del (ev);
  202. free (ev);
  203. }
  204. }
  205. #ifdef __cplusplus
  206. }
  207. #endif
  208. #endif /* RDNS_EV_H_ */