1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/drivers/io_osx.m Sat Feb 25 21:30:49 2012 +1000
1.7 + * OS X networking support functions. Currently this is just for activity callbacks.
1.9 + * Copyright (c) 2009 Nathan Keynes.
1.11 + * This program is free software; you can redistribute it and/or modify
1.12 + * it under the terms of the GNU General Public License as published by
1.13 + * the Free Software Foundation; either version 2 of the License, or
1.14 + * (at your option) any later version.
1.16 + * This program is distributed in the hope that it will be useful,
1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.19 + * GNU General Public License for more details.
1.22 +#include <CoreFoundation/CoreFoundation.h>
1.23 +#include "ioutil.h"
1.25 +struct io_osx_cbinfo {
1.27 + io_callback_t callback;
1.29 + void (*cbdealloc)(void *);
1.31 + CFRunLoopSourceRef sourceRef;
1.33 + struct io_osx_cbinfo *next;
1.36 +static struct io_osx_cbinfo *cbinfo_list = NULL;
1.38 +void io_unregister_callback( struct io_osx_cbinfo *cbinfo )
1.40 + CFRunLoopRemoveSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
1.41 + CFRelease(cbinfo->sourceRef);
1.42 + cbinfo->sourceRef = NULL;
1.43 + CFRelease(cbinfo->fdRef); /* Note this implicitly releases the cbinfo itself as well */
1.46 +static void io_osx_net_callback( CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *unused, void *data )
1.48 + struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
1.49 + if(!cbinfo->callback( CFSocketGetNative(s), cbinfo->cbdata) ) {
1.50 + io_unregister_callback(cbinfo);
1.54 +static void io_osx_fd_callback( CFFileDescriptorRef f, CFOptionFlags type, void *data )
1.56 + struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
1.57 + if(!cbinfo->callback( CFFileDescriptorGetNativeDescriptor(f), cbinfo->cbdata) ) {
1.58 + io_unregister_callback(cbinfo);
1.62 +static void io_osx_release( const void *data )
1.64 + struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
1.65 + if( cbinfo->cbdealloc != NULL ) {
1.66 + cbinfo->cbdealloc(cbinfo->cbdata);
1.72 + * Register a TCP server socket listener on an already open (and listening)
1.73 + * socket. The socket must not have been previously registered.
1.74 + * @return TRUE on success, FALSE on failure.
1.76 + * Defined in netutil.h
1.78 +io_listener_t io_register_tcp_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void*) )
1.80 + CFSocketContext socketContext;
1.81 + struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) );
1.82 + assert(cbinfo != NULL);
1.84 + cbinfo->callback = callback;
1.85 + cbinfo->cbdata = data;
1.86 + cbinfo->cbdealloc = dealloc;
1.87 + socketContext.version = 0;
1.88 + socketContext.info = cbinfo;
1.89 + socketContext.retain = NULL;
1.90 + socketContext.release = io_osx_release;
1.91 + socketContext.copyDescription = NULL;
1.93 + CFSocketRef ref = CFSocketCreateWithNative( kCFAllocatorDefault, fd, kCFSocketReadCallBack,
1.94 + io_osx_net_callback, &socketContext );
1.95 + cbinfo->fdRef = ref;
1.96 + cbinfo->sourceRef = CFSocketCreateRunLoopSource( kCFAllocatorDefault, ref, 0 );
1.97 + CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
1.103 + * Register a file descriptor listener on an already open (and listening)
1.104 + * file descriptor. The file descriptor must not have been previously registered.
1.105 + * @return TRUE on success, FALSE on failure.
1.108 +io_listener_t io_register_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void *) )
1.110 + CFFileDescriptorContext fdContext;
1.111 + struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) );
1.112 + assert(cbinfo != NULL);
1.114 + cbinfo->callback = callback;
1.115 + cbinfo->cbdata = data;
1.116 + cbinfo->cbdealloc = dealloc;
1.117 + fdContext.version = 0;
1.118 + fdContext.retain = NULL;
1.119 + fdContext.info = cbinfo;
1.120 + fdContext.release = io_osx_release;
1.121 + fdContext.copyDescription = NULL;
1.123 + CFFileDescriptorRef ref = CFFileDescriptorCreate( kCFAllocatorDefault, fd, FALSE,
1.124 + io_osx_fd_callback, &fdContext);
1.125 + cbinfo->fdRef = ref;
1.126 + cbinfo->sourceRef = CFFileDescriptorCreateRunLoopSource( kCFAllocatorDefault, ref, 0 );
1.127 + CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
1.131 +void io_unregister_listener( io_listener_t data )
1.133 + struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
1.134 + io_unregister_callback(cbinfo);