Simulation Core
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.
 
 
 
 
 
 

124 lines
3.3 KiB

  1. #ifndef __HIREDIS_LIBHV_H__
  2. #define __HIREDIS_LIBHV_H__
  3. #include <hv/hloop.h>
  4. #include "../hiredis.h"
  5. #include "../async.h"
  6. typedef struct redisLibhvEvents {
  7. hio_t *io;
  8. htimer_t *timer;
  9. } redisLibhvEvents;
  10. static void redisLibhvHandleEvents(hio_t* io) {
  11. redisAsyncContext* context = (redisAsyncContext*)hevent_userdata(io);
  12. int events = hio_events(io);
  13. int revents = hio_revents(io);
  14. if (context && (events & HV_READ) && (revents & HV_READ)) {
  15. redisAsyncHandleRead(context);
  16. }
  17. if (context && (events & HV_WRITE) && (revents & HV_WRITE)) {
  18. redisAsyncHandleWrite(context);
  19. }
  20. }
  21. static void redisLibhvAddRead(void *privdata) {
  22. redisLibhvEvents* events = (redisLibhvEvents*)privdata;
  23. hio_add(events->io, redisLibhvHandleEvents, HV_READ);
  24. }
  25. static void redisLibhvDelRead(void *privdata) {
  26. redisLibhvEvents* events = (redisLibhvEvents*)privdata;
  27. hio_del(events->io, HV_READ);
  28. }
  29. static void redisLibhvAddWrite(void *privdata) {
  30. redisLibhvEvents* events = (redisLibhvEvents*)privdata;
  31. hio_add(events->io, redisLibhvHandleEvents, HV_WRITE);
  32. }
  33. static void redisLibhvDelWrite(void *privdata) {
  34. redisLibhvEvents* events = (redisLibhvEvents*)privdata;
  35. hio_del(events->io, HV_WRITE);
  36. }
  37. static void redisLibhvCleanup(void *privdata) {
  38. redisLibhvEvents* events = (redisLibhvEvents*)privdata;
  39. if (events->timer)
  40. htimer_del(events->timer);
  41. hio_close(events->io);
  42. hevent_set_userdata(events->io, NULL);
  43. hi_free(events);
  44. }
  45. static void redisLibhvTimeout(htimer_t* timer) {
  46. hio_t* io = (hio_t*)hevent_userdata(timer);
  47. redisAsyncHandleTimeout((redisAsyncContext*)hevent_userdata(io));
  48. }
  49. static void redisLibhvSetTimeout(void *privdata, struct timeval tv) {
  50. redisLibhvEvents* events;
  51. uint32_t millis;
  52. hloop_t* loop;
  53. events = (redisLibhvEvents*)privdata;
  54. millis = tv.tv_sec * 1000 + tv.tv_usec / 1000;
  55. if (millis == 0) {
  56. /* Libhv disallows zero'd timers so treat this as a delete or NO OP */
  57. if (events->timer) {
  58. htimer_del(events->timer);
  59. events->timer = NULL;
  60. }
  61. } else if (events->timer == NULL) {
  62. /* Add new timer */
  63. loop = hevent_loop(events->io);
  64. events->timer = htimer_add(loop, redisLibhvTimeout, millis, 1);
  65. hevent_set_userdata(events->timer, events->io);
  66. } else {
  67. /* Update existing timer */
  68. htimer_reset(events->timer, millis);
  69. }
  70. }
  71. static int redisLibhvAttach(redisAsyncContext* ac, hloop_t* loop) {
  72. redisContext *c = &(ac->c);
  73. redisLibhvEvents *events;
  74. hio_t* io = NULL;
  75. if (ac->ev.data != NULL) {
  76. return REDIS_ERR;
  77. }
  78. /* Create container struct to keep track of our io and any timer */
  79. events = (redisLibhvEvents*)hi_malloc(sizeof(*events));
  80. if (events == NULL) {
  81. return REDIS_ERR;
  82. }
  83. io = hio_get(loop, c->fd);
  84. if (io == NULL) {
  85. hi_free(events);
  86. return REDIS_ERR;
  87. }
  88. hevent_set_userdata(io, ac);
  89. events->io = io;
  90. events->timer = NULL;
  91. ac->ev.addRead = redisLibhvAddRead;
  92. ac->ev.delRead = redisLibhvDelRead;
  93. ac->ev.addWrite = redisLibhvAddWrite;
  94. ac->ev.delWrite = redisLibhvDelWrite;
  95. ac->ev.cleanup = redisLibhvCleanup;
  96. ac->ev.scheduleTimer = redisLibhvSetTimeout;
  97. ac->ev.data = events;
  98. return REDIS_OK;
  99. }
  100. #endif