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.
 
 
 
 
 
 

116 lines
3.8 KiB

  1. //
  2. // Created by Дмитрий Бахвалов on 13.07.15.
  3. // Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved.
  4. //
  5. #ifndef __HIREDIS_MACOSX_H__
  6. #define __HIREDIS_MACOSX_H__
  7. #include <CoreFoundation/CoreFoundation.h>
  8. #include "../hiredis.h"
  9. #include "../async.h"
  10. typedef struct {
  11. redisAsyncContext *context;
  12. CFSocketRef socketRef;
  13. CFRunLoopSourceRef sourceRef;
  14. } RedisRunLoop;
  15. static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) {
  16. if( redisRunLoop != NULL ) {
  17. if( redisRunLoop->sourceRef != NULL ) {
  18. CFRunLoopSourceInvalidate(redisRunLoop->sourceRef);
  19. CFRelease(redisRunLoop->sourceRef);
  20. }
  21. if( redisRunLoop->socketRef != NULL ) {
  22. CFSocketInvalidate(redisRunLoop->socketRef);
  23. CFRelease(redisRunLoop->socketRef);
  24. }
  25. hi_free(redisRunLoop);
  26. }
  27. return REDIS_ERR;
  28. }
  29. static void redisMacOSAddRead(void *privdata) {
  30. RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
  31. CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack);
  32. }
  33. static void redisMacOSDelRead(void *privdata) {
  34. RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
  35. CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack);
  36. }
  37. static void redisMacOSAddWrite(void *privdata) {
  38. RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
  39. CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack);
  40. }
  41. static void redisMacOSDelWrite(void *privdata) {
  42. RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
  43. CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack);
  44. }
  45. static void redisMacOSCleanup(void *privdata) {
  46. RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
  47. freeRedisRunLoop(redisRunLoop);
  48. }
  49. static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) {
  50. redisAsyncContext* context = (redisAsyncContext*) info;
  51. switch (callbackType) {
  52. case kCFSocketReadCallBack:
  53. redisAsyncHandleRead(context);
  54. break;
  55. case kCFSocketWriteCallBack:
  56. redisAsyncHandleWrite(context);
  57. break;
  58. default:
  59. break;
  60. }
  61. }
  62. static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) {
  63. redisContext *redisCtx = &(redisAsyncCtx->c);
  64. /* Nothing should be attached when something is already attached */
  65. if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR;
  66. RedisRunLoop* redisRunLoop = (RedisRunLoop*) hi_calloc(1, sizeof(RedisRunLoop));
  67. if (redisRunLoop == NULL)
  68. return REDIS_ERR;
  69. /* Setup redis stuff */
  70. redisRunLoop->context = redisAsyncCtx;
  71. redisAsyncCtx->ev.addRead = redisMacOSAddRead;
  72. redisAsyncCtx->ev.delRead = redisMacOSDelRead;
  73. redisAsyncCtx->ev.addWrite = redisMacOSAddWrite;
  74. redisAsyncCtx->ev.delWrite = redisMacOSDelWrite;
  75. redisAsyncCtx->ev.cleanup = redisMacOSCleanup;
  76. redisAsyncCtx->ev.data = redisRunLoop;
  77. /* Initialize and install read/write events */
  78. CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL };
  79. redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd,
  80. kCFSocketReadCallBack | kCFSocketWriteCallBack,
  81. redisMacOSAsyncCallback,
  82. &socketCtx);
  83. if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop);
  84. redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0);
  85. if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop);
  86. CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode);
  87. return REDIS_OK;
  88. }
  89. #endif