Search
lxdream.org :: lxdream/src/drivers/io_osx.m
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/io_osx.m
changeset 1077:136fc24d17ef
prev1071:182cfe43c09e
next1298:d0eb2307b847
author nkeynes
date Fri Feb 24 21:11:58 2012 +1000 (12 years ago)
permissions -rw-r--r--
last change Add preprocessing support to genglsl
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 }
.