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 (5 years ago)
permissions -rw-r--r--
last change Fix assorted compile warnings reported by Clang
file annotate diff log raw
nkeynes@998
     1
/**
nkeynes@1021
     2
 * $Id$
nkeynes@998
     3
 *
nkeynes@998
     4
 * OS X networking support functions. Currently this is just for activity callbacks.
nkeynes@998
     5
 *
nkeynes@998
     6
 * Copyright (c) 2009 Nathan Keynes.
nkeynes@998
     7
 *
nkeynes@998
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@998
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@998
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@998
    11
 * (at your option) any later version.
nkeynes@998
    12
 *
nkeynes@998
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@998
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@998
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@998
    16
 * GNU General Public License for more details.
nkeynes@998
    17
 */
nkeynes@998
    18
nkeynes@998
    19
#include <CoreFoundation/CoreFoundation.h>
nkeynes@1077
    20
#include "ioutil.h"
nkeynes@998
    21
nkeynes@1077
    22
struct io_osx_cbinfo {
nkeynes@1077
    23
    int fd;
nkeynes@1077
    24
    io_callback_t callback;
nkeynes@998
    25
    void * cbdata;
nkeynes@998
    26
    void (*cbdealloc)(void *);
nkeynes@1077
    27
    void *fdRef;
nkeynes@998
    28
    CFRunLoopSourceRef sourceRef;
nkeynes@1077
    29
nkeynes@1077
    30
    struct io_osx_cbinfo *next;
nkeynes@998
    31
};
nkeynes@998
    32
nkeynes@1077
    33
void io_unregister_callback( struct io_osx_cbinfo *cbinfo )
nkeynes@998
    34
{
nkeynes@1077
    35
    CFRunLoopRemoveSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
nkeynes@1077
    36
    CFRelease(cbinfo->sourceRef);
nkeynes@1077
    37
    cbinfo->sourceRef = NULL;
nkeynes@1077
    38
    CFRelease(cbinfo->fdRef); /* Note this implicitly releases the cbinfo itself as well */
nkeynes@1077
    39
}
nkeynes@1077
    40
nkeynes@1077
    41
static void io_osx_net_callback( CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *unused, void *data )
nkeynes@1077
    42
{
nkeynes@1077
    43
    struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
nkeynes@998
    44
    if(!cbinfo->callback( CFSocketGetNative(s), cbinfo->cbdata) ) {
nkeynes@1077
    45
        io_unregister_callback(cbinfo);
nkeynes@998
    46
    }
nkeynes@998
    47
}
nkeynes@998
    48
nkeynes@1077
    49
static void io_osx_fd_callback( CFFileDescriptorRef f, CFOptionFlags type, void *data )
nkeynes@998
    50
{
nkeynes@1077
    51
    struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
nkeynes@1077
    52
    if(!cbinfo->callback( CFFileDescriptorGetNativeDescriptor(f), cbinfo->cbdata) ) {
nkeynes@1077
    53
        io_unregister_callback(cbinfo);
nkeynes@1077
    54
    }
nkeynes@1077
    55
}
nkeynes@1077
    56
nkeynes@1077
    57
static void io_osx_release( const void *data )
nkeynes@1077
    58
{
nkeynes@1077
    59
    struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
nkeynes@998
    60
    if( cbinfo->cbdealloc != NULL ) {
nkeynes@998
    61
        cbinfo->cbdealloc(cbinfo->cbdata);
nkeynes@998
    62
    }
nkeynes@998
    63
    free( cbinfo );
nkeynes@998
    64
}
nkeynes@998
    65
nkeynes@998
    66
/**
nkeynes@998
    67
 * Register a TCP server socket listener on an already open (and listening) 
nkeynes@998
    68
 * socket. The socket must not have been previously registered.
nkeynes@998
    69
 * @return TRUE on success, FALSE on failure.
nkeynes@998
    70
 * 
nkeynes@998
    71
 * Defined in netutil.h
nkeynes@998
    72
 */ 
nkeynes@1077
    73
io_listener_t io_register_tcp_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void*) )
nkeynes@998
    74
{
nkeynes@998
    75
    CFSocketContext socketContext;
nkeynes@1077
    76
    struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) );
nkeynes@998
    77
    assert(cbinfo != NULL);
nkeynes@998
    78
    
nkeynes@998
    79
    cbinfo->callback = callback;
nkeynes@998
    80
    cbinfo->cbdata = data;
nkeynes@998
    81
    cbinfo->cbdealloc = dealloc;
nkeynes@998
    82
    socketContext.version = 0;
nkeynes@998
    83
    socketContext.info = cbinfo;
nkeynes@998
    84
    socketContext.retain = NULL;
nkeynes@1077
    85
    socketContext.release = io_osx_release;
nkeynes@998
    86
    socketContext.copyDescription = NULL;
nkeynes@998
    87
    
nkeynes@1077
    88
    CFSocketRef ref = CFSocketCreateWithNative( kCFAllocatorDefault, fd, kCFSocketReadCallBack,
nkeynes@1077
    89
            io_osx_net_callback, &socketContext );
nkeynes@1077
    90
    cbinfo->fdRef = ref;
nkeynes@1077
    91
    cbinfo->sourceRef = CFSocketCreateRunLoopSource( kCFAllocatorDefault, ref, 0 );
nkeynes@998
    92
    CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
nkeynes@1071
    93
nkeynes@1077
    94
    return cbinfo;
nkeynes@998
    95
}
nkeynes@1077
    96
nkeynes@1077
    97
/**
nkeynes@1077
    98
 * Register a file descriptor listener on an already open (and listening)
nkeynes@1077
    99
 * file descriptor. The file descriptor must not have been previously registered.
nkeynes@1077
   100
 * @return TRUE on success, FALSE on failure.
nkeynes@1077
   101
 *
nkeynes@1077
   102
 */
nkeynes@1077
   103
io_listener_t io_register_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void *) )
nkeynes@1077
   104
{
nkeynes@1077
   105
    CFFileDescriptorContext fdContext;
nkeynes@1077
   106
    struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) );
nkeynes@1077
   107
    assert(cbinfo != NULL);
nkeynes@1077
   108
nkeynes@1077
   109
    cbinfo->callback = callback;
nkeynes@1077
   110
    cbinfo->cbdata = data;
nkeynes@1077
   111
    cbinfo->cbdealloc = dealloc;
nkeynes@1077
   112
    fdContext.version = 0;
nkeynes@1077
   113
    fdContext.retain = NULL;
nkeynes@1077
   114
    fdContext.info = cbinfo;
nkeynes@1298
   115
    fdContext.release = ( void (*)(void *) )io_osx_release;
nkeynes@1077
   116
    fdContext.copyDescription = NULL;
nkeynes@1077
   117
nkeynes@1077
   118
    CFFileDescriptorRef ref = CFFileDescriptorCreate( kCFAllocatorDefault, fd, FALSE,
nkeynes@1077
   119
            io_osx_fd_callback, &fdContext);
nkeynes@1077
   120
    cbinfo->fdRef = ref;
nkeynes@1077
   121
    cbinfo->sourceRef = CFFileDescriptorCreateRunLoopSource( kCFAllocatorDefault, ref, 0 );
nkeynes@1077
   122
    CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
nkeynes@1077
   123
    return cbinfo;
nkeynes@1077
   124
}
nkeynes@1077
   125
nkeynes@1077
   126
void io_unregister_listener( io_listener_t data )
nkeynes@1077
   127
{
nkeynes@1077
   128
    struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
nkeynes@1077
   129
    io_unregister_callback(cbinfo);
nkeynes@1077
   130
}
.