4 * OS X networking support functions. Currently this is just for activity callbacks.
6 * Copyright (c) 2009 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
19 #include <CoreFoundation/CoreFoundation.h>
22 struct io_osx_cbinfo {
24 io_callback_t callback;
26 void (*cbdealloc)(void *);
28 CFRunLoopSourceRef sourceRef;
30 struct io_osx_cbinfo *next;
33 void io_unregister_callback( struct io_osx_cbinfo *cbinfo )
35 CFRunLoopRemoveSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
36 CFRelease(cbinfo->sourceRef);
37 cbinfo->sourceRef = NULL;
38 CFRelease(cbinfo->fdRef); /* Note this implicitly releases the cbinfo itself as well */
41 static void io_osx_net_callback( CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *unused, void *data )
43 struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
44 if(!cbinfo->callback( CFSocketGetNative(s), cbinfo->cbdata) ) {
45 io_unregister_callback(cbinfo);
49 static void io_osx_fd_callback( CFFileDescriptorRef f, CFOptionFlags type, void *data )
51 struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
52 if(!cbinfo->callback( CFFileDescriptorGetNativeDescriptor(f), cbinfo->cbdata) ) {
53 io_unregister_callback(cbinfo);
57 static void io_osx_release( const void *data )
59 struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
60 if( cbinfo->cbdealloc != NULL ) {
61 cbinfo->cbdealloc(cbinfo->cbdata);
67 * Register a TCP server socket listener on an already open (and listening)
68 * socket. The socket must not have been previously registered.
69 * @return TRUE on success, FALSE on failure.
71 * Defined in netutil.h
73 io_listener_t io_register_tcp_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void*) )
75 CFSocketContext socketContext;
76 struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) );
77 assert(cbinfo != NULL);
79 cbinfo->callback = callback;
80 cbinfo->cbdata = data;
81 cbinfo->cbdealloc = dealloc;
82 socketContext.version = 0;
83 socketContext.info = cbinfo;
84 socketContext.retain = NULL;
85 socketContext.release = io_osx_release;
86 socketContext.copyDescription = NULL;
88 CFSocketRef ref = CFSocketCreateWithNative( kCFAllocatorDefault, fd, kCFSocketReadCallBack,
89 io_osx_net_callback, &socketContext );
91 cbinfo->sourceRef = CFSocketCreateRunLoopSource( kCFAllocatorDefault, ref, 0 );
92 CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
98 * Register a file descriptor listener on an already open (and listening)
99 * file descriptor. The file descriptor must not have been previously registered.
100 * @return TRUE on success, FALSE on failure.
103 io_listener_t io_register_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void *) )
105 CFFileDescriptorContext fdContext;
106 struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) );
107 assert(cbinfo != NULL);
109 cbinfo->callback = callback;
110 cbinfo->cbdata = data;
111 cbinfo->cbdealloc = dealloc;
112 fdContext.version = 0;
113 fdContext.retain = NULL;
114 fdContext.info = cbinfo;
115 fdContext.release = ( void (*)(void *) )io_osx_release;
116 fdContext.copyDescription = NULL;
118 CFFileDescriptorRef ref = CFFileDescriptorCreate( kCFAllocatorDefault, fd, FALSE,
119 io_osx_fd_callback, &fdContext);
121 cbinfo->sourceRef = CFFileDescriptorCreateRunLoopSource( kCFAllocatorDefault, ref, 0 );
122 CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
126 void io_unregister_listener( io_listener_t data )
128 struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
129 io_unregister_callback(cbinfo);
.