2
0

libuv.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. int ev = (status ? p->events : events);
  16. if (p->context != NULL && (ev & UV_READABLE)) {
  17. redisAsyncHandleRead(p->context);
  18. }
  19. if (p->context != NULL && (ev & UV_WRITABLE)) {
  20. redisAsyncHandleWrite(p->context);
  21. }
  22. }
  23. static void redisLibuvAddRead(void *privdata) {
  24. redisLibuvEvents* p = (redisLibuvEvents*)privdata;
  25. p->events |= UV_READABLE;
  26. uv_poll_start(&p->handle, p->events, redisLibuvPoll);
  27. }
  28. static void redisLibuvDelRead(void *privdata) {
  29. redisLibuvEvents* p = (redisLibuvEvents*)privdata;
  30. p->events &= ~UV_READABLE;
  31. if (p->events) {
  32. uv_poll_start(&p->handle, p->events, redisLibuvPoll);
  33. } else {
  34. uv_poll_stop(&p->handle);
  35. }
  36. }
  37. static void redisLibuvAddWrite(void *privdata) {
  38. redisLibuvEvents* p = (redisLibuvEvents*)privdata;
  39. p->events |= UV_WRITABLE;
  40. uv_poll_start(&p->handle, p->events, redisLibuvPoll);
  41. }
  42. static void redisLibuvDelWrite(void *privdata) {
  43. redisLibuvEvents* p = (redisLibuvEvents*)privdata;
  44. p->events &= ~UV_WRITABLE;
  45. if (p->events) {
  46. uv_poll_start(&p->handle, p->events, redisLibuvPoll);
  47. } else {
  48. uv_poll_stop(&p->handle);
  49. }
  50. }
  51. static void on_close(uv_handle_t* handle) {
  52. redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
  53. free(p);
  54. }
  55. static void redisLibuvCleanup(void *privdata) {
  56. redisLibuvEvents* p = (redisLibuvEvents*)privdata;
  57. p->context = NULL; // indicate that context might no longer exist
  58. uv_close((uv_handle_t*)&p->handle, on_close);
  59. }
  60. static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) {
  61. redisContext *c = &(ac->c);
  62. if (ac->ev.data != NULL) {
  63. return REDIS_ERR;
  64. }
  65. ac->ev.addRead = redisLibuvAddRead;
  66. ac->ev.delRead = redisLibuvDelRead;
  67. ac->ev.addWrite = redisLibuvAddWrite;
  68. ac->ev.delWrite = redisLibuvDelWrite;
  69. ac->ev.cleanup = redisLibuvCleanup;
  70. redisLibuvEvents* p = (redisLibuvEvents*)malloc(sizeof(*p));
  71. if (!p) {
  72. return REDIS_ERR;
  73. }
  74. memset(p, 0, sizeof(*p));
  75. if (uv_poll_init(loop, &p->handle, c->fd) != 0) {
  76. return REDIS_ERR;
  77. }
  78. ac->ev.data = p;
  79. p->handle.data = p;
  80. p->context = ac;
  81. return REDIS_OK;
  82. }
  83. #endif