2
0

libuv.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #ifndef __HIREDIS_LIBUV_H__
  2. #define __HIREDIS_LIBUV_H__
  3. #include <stdlib.h>
  4. #include <uv.h>
  5. #include "../hiredis.h"
  6. #include "../async.h"
  7. #include <string.h>
  8. typedef struct redisLibuvEvents {
  9. redisAsyncContext* context;
  10. uv_poll_t handle;
  11. int events;
  12. } redisLibuvEvents;
  13. static void redisLibuvPoll(uv_poll_t* handle, int status, int events) {
  14. redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
  15. if (status != 0) {
  16. return;
  17. }
  18. if (p->context != NULL && (events & UV_READABLE)) {
  19. redisAsyncHandleRead(p->context);
  20. }
  21. if (p->context != NULL && (events & UV_WRITABLE)) {
  22. redisAsyncHandleWrite(p->context);
  23. }
  24. }
  25. static void redisLibuvAddRead(void *privdata) {
  26. redisLibuvEvents* p = (redisLibuvEvents*)privdata;
  27. p->events |= UV_READABLE;
  28. uv_poll_start(&p->handle, p->events, redisLibuvPoll);
  29. }
  30. static void redisLibuvDelRead(void *privdata) {
  31. redisLibuvEvents* p = (redisLibuvEvents*)privdata;
  32. p->events &= ~UV_READABLE;
  33. if (p->events) {
  34. uv_poll_start(&p->handle, p->events, redisLibuvPoll);
  35. } else {
  36. uv_poll_stop(&p->handle);
  37. }
  38. }
  39. static void redisLibuvAddWrite(void *privdata) {
  40. redisLibuvEvents* p = (redisLibuvEvents*)privdata;
  41. p->events |= UV_WRITABLE;
  42. uv_poll_start(&p->handle, p->events, redisLibuvPoll);
  43. }
  44. static void redisLibuvDelWrite(void *privdata) {
  45. redisLibuvEvents* p = (redisLibuvEvents*)privdata;
  46. p->events &= ~UV_WRITABLE;
  47. if (p->events) {
  48. uv_poll_start(&p->handle, p->events, redisLibuvPoll);
  49. } else {
  50. uv_poll_stop(&p->handle);
  51. }
  52. }
  53. static void on_close(uv_handle_t* handle) {
  54. redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
  55. free(p);
  56. }
  57. static void redisLibuvCleanup(void *privdata) {
  58. redisLibuvEvents* p = (redisLibuvEvents*)privdata;
  59. p->context = NULL; // indicate that context might no longer exist
  60. uv_close((uv_handle_t*)&p->handle, on_close);
  61. }
  62. static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) {
  63. redisContext *c = &(ac->c);
  64. if (ac->ev.data != NULL) {
  65. return REDIS_ERR;
  66. }
  67. ac->ev.addRead = redisLibuvAddRead;
  68. ac->ev.delRead = redisLibuvDelRead;
  69. ac->ev.addWrite = redisLibuvAddWrite;
  70. ac->ev.delWrite = redisLibuvDelWrite;
  71. ac->ev.cleanup = redisLibuvCleanup;
  72. redisLibuvEvents* p = (redisLibuvEvents*)malloc(sizeof(*p));
  73. if (!p) {
  74. return REDIS_ERR;
  75. }
  76. memset(p, 0, sizeof(*p));
  77. if (uv_poll_init(loop, &p->handle, c->fd) != 0) {
  78. return REDIS_ERR;
  79. }
  80. ac->ev.data = p;
  81. p->handle.data = p;
  82. p->context = ac;
  83. return REDIS_OK;
  84. }
  85. #endif