summaryrefslogtreecommitdiffstats
path: root/deps/hiredis/adapters/macosx.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/hiredis/adapters/macosx.h')
-rw-r--r--deps/hiredis/adapters/macosx.h115
1 files changed, 115 insertions, 0 deletions
diff --git a/deps/hiredis/adapters/macosx.h b/deps/hiredis/adapters/macosx.h
new file mode 100644
index 0000000..3c87f1b
--- /dev/null
+++ b/deps/hiredis/adapters/macosx.h
@@ -0,0 +1,115 @@
+//
+// Created by Дмитрий Бахвалов on 13.07.15.
+// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved.
+//
+
+#ifndef __HIREDIS_MACOSX_H__
+#define __HIREDIS_MACOSX_H__
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "../hiredis.h"
+#include "../async.h"
+
+typedef struct {
+ redisAsyncContext *context;
+ CFSocketRef socketRef;
+ CFRunLoopSourceRef sourceRef;
+} RedisRunLoop;
+
+static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) {
+ if( redisRunLoop != NULL ) {
+ if( redisRunLoop->sourceRef != NULL ) {
+ CFRunLoopSourceInvalidate(redisRunLoop->sourceRef);
+ CFRelease(redisRunLoop->sourceRef);
+ }
+ if( redisRunLoop->socketRef != NULL ) {
+ CFSocketInvalidate(redisRunLoop->socketRef);
+ CFRelease(redisRunLoop->socketRef);
+ }
+ hi_free(redisRunLoop);
+ }
+ return REDIS_ERR;
+}
+
+static void redisMacOSAddRead(void *privdata) {
+ RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+ CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack);
+}
+
+static void redisMacOSDelRead(void *privdata) {
+ RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+ CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack);
+}
+
+static void redisMacOSAddWrite(void *privdata) {
+ RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+ CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack);
+}
+
+static void redisMacOSDelWrite(void *privdata) {
+ RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+ CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack);
+}
+
+static void redisMacOSCleanup(void *privdata) {
+ RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+ freeRedisRunLoop(redisRunLoop);
+}
+
+static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) {
+ redisAsyncContext* context = (redisAsyncContext*) info;
+
+ switch (callbackType) {
+ case kCFSocketReadCallBack:
+ redisAsyncHandleRead(context);
+ break;
+
+ case kCFSocketWriteCallBack:
+ redisAsyncHandleWrite(context);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) {
+ redisContext *redisCtx = &(redisAsyncCtx->c);
+
+ /* Nothing should be attached when something is already attached */
+ if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR;
+
+ RedisRunLoop* redisRunLoop = (RedisRunLoop*) hi_calloc(1, sizeof(RedisRunLoop));
+ if (redisRunLoop == NULL)
+ return REDIS_ERR;
+
+ /* Setup redis stuff */
+ redisRunLoop->context = redisAsyncCtx;
+
+ redisAsyncCtx->ev.addRead = redisMacOSAddRead;
+ redisAsyncCtx->ev.delRead = redisMacOSDelRead;
+ redisAsyncCtx->ev.addWrite = redisMacOSAddWrite;
+ redisAsyncCtx->ev.delWrite = redisMacOSDelWrite;
+ redisAsyncCtx->ev.cleanup = redisMacOSCleanup;
+ redisAsyncCtx->ev.data = redisRunLoop;
+
+ /* Initialize and install read/write events */
+ CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL };
+
+ redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd,
+ kCFSocketReadCallBack | kCFSocketWriteCallBack,
+ redisMacOSAsyncCallback,
+ &socketCtx);
+ if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop);
+
+ redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0);
+ if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop);
+
+ CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode);
+
+ return REDIS_OK;
+}
+
+#endif
+