123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- //
- // 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);
- }
- 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*) calloc(1, sizeof(RedisRunLoop));
- if( !redisRunLoop ) 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
|