filename | src/drivers/io_osx.m |
changeset | 1077:136fc24d17ef |
prev | 1071:182cfe43c09e |
next | 1298:d0eb2307b847 |
author | nkeynes |
date | Fri Jul 13 21:05:10 2012 +1000 (11 years ago) |
permissions | -rw-r--r-- |
last change | Add check that glGenFencesNV is actually defined, to try to guard against installations with a broken libGL |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * OS X networking support functions. Currently this is just for activity callbacks.
5 *
6 * Copyright (c) 2009 Nathan Keynes.
7 *
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.
12 *
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.
17 */
19 #include <CoreFoundation/CoreFoundation.h>
20 #include "ioutil.h"
22 struct io_osx_cbinfo {
23 int fd;
24 io_callback_t callback;
25 void * cbdata;
26 void (*cbdealloc)(void *);
27 void *fdRef;
28 CFRunLoopSourceRef sourceRef;
30 struct io_osx_cbinfo *next;
31 };
33 static struct io_osx_cbinfo *cbinfo_list = NULL;
35 void io_unregister_callback( struct io_osx_cbinfo *cbinfo )
36 {
37 CFRunLoopRemoveSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
38 CFRelease(cbinfo->sourceRef);
39 cbinfo->sourceRef = NULL;
40 CFRelease(cbinfo->fdRef); /* Note this implicitly releases the cbinfo itself as well */
41 }
43 static void io_osx_net_callback( CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *unused, void *data )
44 {
45 struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
46 if(!cbinfo->callback( CFSocketGetNative(s), cbinfo->cbdata) ) {
47 io_unregister_callback(cbinfo);
48 }
49 }
51 static void io_osx_fd_callback( CFFileDescriptorRef f, CFOptionFlags type, void *data )
52 {
53 struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
54 if(!cbinfo->callback( CFFileDescriptorGetNativeDescriptor(f), cbinfo->cbdata) ) {
55 io_unregister_callback(cbinfo);
56 }
57 }
59 static void io_osx_release( const void *data )
60 {
61 struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
62 if( cbinfo->cbdealloc != NULL ) {
63 cbinfo->cbdealloc(cbinfo->cbdata);
64 }
65 free( cbinfo );
66 }
68 /**
69 * Register a TCP server socket listener on an already open (and listening)
70 * socket. The socket must not have been previously registered.
71 * @return TRUE on success, FALSE on failure.
72 *
73 * Defined in netutil.h
74 */
75 io_listener_t io_register_tcp_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void*) )
76 {
77 CFSocketContext socketContext;
78 struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) );
79 assert(cbinfo != NULL);
81 cbinfo->callback = callback;
82 cbinfo->cbdata = data;
83 cbinfo->cbdealloc = dealloc;
84 socketContext.version = 0;
85 socketContext.info = cbinfo;
86 socketContext.retain = NULL;
87 socketContext.release = io_osx_release;
88 socketContext.copyDescription = NULL;
90 CFSocketRef ref = CFSocketCreateWithNative( kCFAllocatorDefault, fd, kCFSocketReadCallBack,
91 io_osx_net_callback, &socketContext );
92 cbinfo->fdRef = ref;
93 cbinfo->sourceRef = CFSocketCreateRunLoopSource( kCFAllocatorDefault, ref, 0 );
94 CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
96 return cbinfo;
97 }
99 /**
100 * Register a file descriptor listener on an already open (and listening)
101 * file descriptor. The file descriptor must not have been previously registered.
102 * @return TRUE on success, FALSE on failure.
103 *
104 */
105 io_listener_t io_register_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void *) )
106 {
107 CFFileDescriptorContext fdContext;
108 struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) );
109 assert(cbinfo != NULL);
111 cbinfo->callback = callback;
112 cbinfo->cbdata = data;
113 cbinfo->cbdealloc = dealloc;
114 fdContext.version = 0;
115 fdContext.retain = NULL;
116 fdContext.info = cbinfo;
117 fdContext.release = io_osx_release;
118 fdContext.copyDescription = NULL;
120 CFFileDescriptorRef ref = CFFileDescriptorCreate( kCFAllocatorDefault, fd, FALSE,
121 io_osx_fd_callback, &fdContext);
122 cbinfo->fdRef = ref;
123 cbinfo->sourceRef = CFFileDescriptorCreateRunLoopSource( kCFAllocatorDefault, ref, 0 );
124 CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
125 return cbinfo;
126 }
128 void io_unregister_listener( io_listener_t data )
129 {
130 struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
131 io_unregister_callback(cbinfo);
132 }
.