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 1298:d0eb2307b847
prev1077:136fc24d17ef
author nkeynes
date Wed Feb 04 08:38:23 2015 +1000 (9 years ago)
permissions -rw-r--r--
last change Fix assorted compile warnings reported by Clang
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 void io_unregister_callback( struct io_osx_cbinfo *cbinfo )
    34 {
    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 */
    39 }
    41 static void io_osx_net_callback( CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *unused, void *data )
    42 {
    43     struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
    44     if(!cbinfo->callback( CFSocketGetNative(s), cbinfo->cbdata) ) {
    45         io_unregister_callback(cbinfo);
    46     }
    47 }
    49 static void io_osx_fd_callback( CFFileDescriptorRef f, CFOptionFlags type, void *data )
    50 {
    51     struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
    52     if(!cbinfo->callback( CFFileDescriptorGetNativeDescriptor(f), cbinfo->cbdata) ) {
    53         io_unregister_callback(cbinfo);
    54     }
    55 }
    57 static void io_osx_release( const void *data )
    58 {
    59     struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
    60     if( cbinfo->cbdealloc != NULL ) {
    61         cbinfo->cbdealloc(cbinfo->cbdata);
    62     }
    63     free( cbinfo );
    64 }
    66 /**
    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.
    70  * 
    71  * Defined in netutil.h
    72  */ 
    73 io_listener_t io_register_tcp_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void*) )
    74 {
    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 );
    90     cbinfo->fdRef = ref;
    91     cbinfo->sourceRef = CFSocketCreateRunLoopSource( kCFAllocatorDefault, ref, 0 );
    92     CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
    94     return cbinfo;
    95 }
    97 /**
    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.
   101  *
   102  */
   103 io_listener_t io_register_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void *) )
   104 {
   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);
   120     cbinfo->fdRef = ref;
   121     cbinfo->sourceRef = CFFileDescriptorCreateRunLoopSource( kCFAllocatorDefault, ref, 0 );
   122     CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
   123     return cbinfo;
   124 }
   126 void io_unregister_listener( io_listener_t data )
   127 {
   128     struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
   129     io_unregister_callback(cbinfo);
   130 }
.