filename | src/drivers/io_osx.m |
changeset | 1077:136fc24d17ef |
prev | 1071:182cfe43c09e |
next | 1298:d0eb2307b847 |
author | nkeynes |
date | Sun Feb 12 16:30:26 2012 +1000 (12 years ago) |
permissions | -rw-r--r-- |
last change | Add -Werror for mregparm check, so it actually fails if mregparm isn't accepted |
file | annotate | diff | log | raw |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00001.2 +++ b/src/drivers/io_osx.m Sun Feb 12 16:30:26 2012 +10001.3 @@ -0,0 +1,132 @@1.4 +/**1.5 + * $Id$1.6 + *1.7 + * OS X networking support functions. Currently this is just for activity callbacks.1.8 + *1.9 + * Copyright (c) 2009 Nathan Keynes.1.10 + *1.11 + * This program is free software; you can redistribute it and/or modify1.12 + * it under the terms of the GNU General Public License as published by1.13 + * the Free Software Foundation; either version 2 of the License, or1.14 + * (at your option) any later version.1.15 + *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 of1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1.19 + * GNU General Public License for more details.1.20 + */1.21 +1.22 +#include <CoreFoundation/CoreFoundation.h>1.23 +#include "ioutil.h"1.24 +1.25 +struct io_osx_cbinfo {1.26 + int fd;1.27 + io_callback_t callback;1.28 + void * cbdata;1.29 + void (*cbdealloc)(void *);1.30 + void *fdRef;1.31 + CFRunLoopSourceRef sourceRef;1.32 +1.33 + struct io_osx_cbinfo *next;1.34 +};1.35 +1.36 +static struct io_osx_cbinfo *cbinfo_list = NULL;1.37 +1.38 +void io_unregister_callback( struct io_osx_cbinfo *cbinfo )1.39 +{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.44 +}1.45 +1.46 +static void io_osx_net_callback( CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *unused, void *data )1.47 +{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.51 + }1.52 +}1.53 +1.54 +static void io_osx_fd_callback( CFFileDescriptorRef f, CFOptionFlags type, void *data )1.55 +{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.59 + }1.60 +}1.61 +1.62 +static void io_osx_release( const void *data )1.63 +{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.67 + }1.68 + free( cbinfo );1.69 +}1.70 +1.71 +/**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.75 + *1.76 + * Defined in netutil.h1.77 + */1.78 +io_listener_t io_register_tcp_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void*) )1.79 +{1.80 + CFSocketContext socketContext;1.81 + struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) );1.82 + assert(cbinfo != NULL);1.83 +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.92 +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.98 +1.99 + return cbinfo;1.100 +}1.101 +1.102 +/**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.106 + *1.107 + */1.108 +io_listener_t io_register_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void *) )1.109 +{1.110 + CFFileDescriptorContext fdContext;1.111 + struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) );1.112 + assert(cbinfo != NULL);1.113 +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.122 +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.128 + return cbinfo;1.129 +}1.130 +1.131 +void io_unregister_listener( io_listener_t data )1.132 +{1.133 + struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;1.134 + io_unregister_callback(cbinfo);1.135 +}
.