libev.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #ifndef __HIREDIS_LIBEV_H__
  2. #define __HIREDIS_LIBEV_H__
  3. #include <stdlib.h>
  4. #include <sys/types.h>
  5. #include <ev.h>
  6. #include "../hiredis.h"
  7. #include "../async.h"
  8. typedef struct redisLibevEvents {
  9. redisAsyncContext *context;
  10. struct ev_loop *loop;
  11. int reading, writing;
  12. ev_io rev, wev;
  13. } redisLibevEvents;
  14. static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) {
  15. #if EV_MULTIPLICITY
  16. ((void)loop);
  17. #endif
  18. ((void)revents);
  19. redisLibevEvents *e = (redisLibevEvents*)watcher->data;
  20. redisAsyncHandleRead(e->context);
  21. }
  22. static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) {
  23. #if EV_MULTIPLICITY
  24. ((void)loop);
  25. #endif
  26. ((void)revents);
  27. redisLibevEvents *e = (redisLibevEvents*)watcher->data;
  28. redisAsyncHandleWrite(e->context);
  29. }
  30. static void redisLibevAddRead(void *privdata) {
  31. redisLibevEvents *e = (redisLibevEvents*)privdata;
  32. struct ev_loop *loop = e->loop;
  33. ((void)loop);
  34. if (!e->reading) {
  35. e->reading = 1;
  36. ev_io_start(EV_A_ &e->rev);
  37. }
  38. }
  39. static void redisLibevDelRead(void *privdata) {
  40. redisLibevEvents *e = (redisLibevEvents*)privdata;
  41. struct ev_loop *loop = e->loop;
  42. ((void)loop);
  43. if (e->reading) {
  44. e->reading = 0;
  45. ev_io_stop(EV_A_ &e->rev);
  46. }
  47. }
  48. static void redisLibevAddWrite(void *privdata) {
  49. redisLibevEvents *e = (redisLibevEvents*)privdata;
  50. struct ev_loop *loop = e->loop;
  51. ((void)loop);
  52. if (!e->writing) {
  53. e->writing = 1;
  54. ev_io_start(EV_A_ &e->wev);
  55. }
  56. }
  57. static void redisLibevDelWrite(void *privdata) {
  58. redisLibevEvents *e = (redisLibevEvents*)privdata;
  59. struct ev_loop *loop = e->loop;
  60. ((void)loop);
  61. if (e->writing) {
  62. e->writing = 0;
  63. ev_io_stop(EV_A_ &e->wev);
  64. }
  65. }
  66. static void redisLibevCleanup(void *privdata) {
  67. redisLibevEvents *e = (redisLibevEvents*)privdata;
  68. redisLibevDelRead(privdata);
  69. redisLibevDelWrite(privdata);
  70. free(e);
  71. }
  72. static int redisLibevAttach(EV_P_ redisAsyncContext *ac) {
  73. redisContext *c = &(ac->c);
  74. redisLibevEvents *e;
  75. /* Nothing should be attached when something is already attached */
  76. if (ac->ev.data != NULL)
  77. return REDIS_ERR;
  78. /* Create container for context and r/w events */
  79. e = (redisLibevEvents*)malloc(sizeof(*e));
  80. e->context = ac;
  81. #if EV_MULTIPLICITY
  82. e->loop = loop;
  83. #else
  84. e->loop = NULL;
  85. #endif
  86. e->reading = e->writing = 0;
  87. e->rev.data = e;
  88. e->wev.data = e;
  89. /* Register functions to start/stop listening for events */
  90. ac->ev.addRead = redisLibevAddRead;
  91. ac->ev.delRead = redisLibevDelRead;
  92. ac->ev.addWrite = redisLibevAddWrite;
  93. ac->ev.delWrite = redisLibevDelWrite;
  94. ac->ev.cleanup = redisLibevCleanup;
  95. ac->ev.data = e;
  96. /* Initialize read/write events */
  97. ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ);
  98. ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE);
  99. return REDIS_OK;
  100. }
  101. #endif