mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 08:38:27 -05:00
122 lines
4.0 KiB
C
122 lines
4.0 KiB
C
|
/*
|
||
|
* Copyright (c) 2015 Dmitry Bakhvalov
|
||
|
*
|
||
|
* SPDX-FileCopyrightText: 2024 Hiredict Contributors
|
||
|
* SPDX-FileCopyrightText: 2024 Dmitry Bakhvalov
|
||
|
*
|
||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||
|
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#ifndef __HIREDICT_MACOSX_H__
|
||
|
#define __HIREDICT_MACOSX_H__
|
||
|
|
||
|
#include <CoreFoundation/CoreFoundation.h>
|
||
|
|
||
|
#include "../hiredict.h"
|
||
|
#include "../async.h"
|
||
|
|
||
|
typedef struct {
|
||
|
redictAsyncContext *context;
|
||
|
CFSocketRef socketRef;
|
||
|
CFRunLoopSourceRef sourceRef;
|
||
|
} RedictRunLoop;
|
||
|
|
||
|
static int freeRedictRunLoop(RedictRunLoop* redictRunLoop) {
|
||
|
if( redictRunLoop != NULL ) {
|
||
|
if( redictRunLoop->sourceRef != NULL ) {
|
||
|
CFRunLoopSourceInvalidate(redictRunLoop->sourceRef);
|
||
|
CFRelease(redictRunLoop->sourceRef);
|
||
|
}
|
||
|
if( redictRunLoop->socketRef != NULL ) {
|
||
|
CFSocketInvalidate(redictRunLoop->socketRef);
|
||
|
CFRelease(redictRunLoop->socketRef);
|
||
|
}
|
||
|
hi_free(redictRunLoop);
|
||
|
}
|
||
|
return REDICT_ERR;
|
||
|
}
|
||
|
|
||
|
static void redictMacOSAddRead(void *privdata) {
|
||
|
RedictRunLoop *redictRunLoop = (RedictRunLoop*)privdata;
|
||
|
CFSocketEnableCallBacks(redictRunLoop->socketRef, kCFSocketReadCallBack);
|
||
|
}
|
||
|
|
||
|
static void redictMacOSDelRead(void *privdata) {
|
||
|
RedictRunLoop *redictRunLoop = (RedictRunLoop*)privdata;
|
||
|
CFSocketDisableCallBacks(redictRunLoop->socketRef, kCFSocketReadCallBack);
|
||
|
}
|
||
|
|
||
|
static void redictMacOSAddWrite(void *privdata) {
|
||
|
RedictRunLoop *redictRunLoop = (RedictRunLoop*)privdata;
|
||
|
CFSocketEnableCallBacks(redictRunLoop->socketRef, kCFSocketWriteCallBack);
|
||
|
}
|
||
|
|
||
|
static void redictMacOSDelWrite(void *privdata) {
|
||
|
RedictRunLoop *redictRunLoop = (RedictRunLoop*)privdata;
|
||
|
CFSocketDisableCallBacks(redictRunLoop->socketRef, kCFSocketWriteCallBack);
|
||
|
}
|
||
|
|
||
|
static void redictMacOSCleanup(void *privdata) {
|
||
|
RedictRunLoop *redictRunLoop = (RedictRunLoop*)privdata;
|
||
|
freeRedictRunLoop(redictRunLoop);
|
||
|
}
|
||
|
|
||
|
static void redictMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) {
|
||
|
redictAsyncContext* context = (redictAsyncContext*) info;
|
||
|
|
||
|
switch (callbackType) {
|
||
|
case kCFSocketReadCallBack:
|
||
|
redictAsyncHandleRead(context);
|
||
|
break;
|
||
|
|
||
|
case kCFSocketWriteCallBack:
|
||
|
redictAsyncHandleWrite(context);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int redictMacOSAttach(redictAsyncContext *redictAsyncCtx, CFRunLoopRef runLoop) {
|
||
|
redictContext *redictCtx = &(redictAsyncCtx->c);
|
||
|
|
||
|
/* Nothing should be attached when something is already attached */
|
||
|
if( redictAsyncCtx->ev.data != NULL ) return REDICT_ERR;
|
||
|
|
||
|
RedictRunLoop* redictRunLoop = (RedictRunLoop*) hi_calloc(1, sizeof(RedictRunLoop));
|
||
|
if (redictRunLoop == NULL)
|
||
|
return REDICT_ERR;
|
||
|
|
||
|
/* Setup redict stuff */
|
||
|
redictRunLoop->context = redictAsyncCtx;
|
||
|
|
||
|
redictAsyncCtx->ev.addRead = redictMacOSAddRead;
|
||
|
redictAsyncCtx->ev.delRead = redictMacOSDelRead;
|
||
|
redictAsyncCtx->ev.addWrite = redictMacOSAddWrite;
|
||
|
redictAsyncCtx->ev.delWrite = redictMacOSDelWrite;
|
||
|
redictAsyncCtx->ev.cleanup = redictMacOSCleanup;
|
||
|
redictAsyncCtx->ev.data = redictRunLoop;
|
||
|
|
||
|
/* Initialize and install read/write events */
|
||
|
CFSocketContext socketCtx = { 0, redictAsyncCtx, NULL, NULL, NULL };
|
||
|
|
||
|
redictRunLoop->socketRef = CFSocketCreateWithNative(NULL, redictCtx->fd,
|
||
|
kCFSocketReadCallBack | kCFSocketWriteCallBack,
|
||
|
redictMacOSAsyncCallback,
|
||
|
&socketCtx);
|
||
|
if( !redictRunLoop->socketRef ) return freeRedictRunLoop(redictRunLoop);
|
||
|
|
||
|
redictRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redictRunLoop->socketRef, 0);
|
||
|
if( !redictRunLoop->sourceRef ) return freeRedictRunLoop(redictRunLoop);
|
||
|
|
||
|
CFRunLoopAddSource(runLoop, redictRunLoop->sourceRef, kCFRunLoopDefaultMode);
|
||
|
|
||
|
return REDICT_OK;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|