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 Mon Mar 05 22:20:33 2012 +1000 (12 years ago)
permissions -rw-r--r--
last change Fix boundary of the first vertical gap in view
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
static struct io_osx_cbinfo *cbinfo_list = NULL;
nkeynes@1077
    34
nkeynes@1077
    35
void io_unregister_callback( struct io_osx_cbinfo *cbinfo )
nkeynes@998
    36
{
nkeynes@1077
    37
    CFRunLoopRemoveSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
nkeynes@1077
    38
    CFRelease(cbinfo->sourceRef);
nkeynes@1077
    39
    cbinfo->sourceRef = NULL;
nkeynes@1077
    40
    CFRelease(cbinfo->fdRef); /* Note this implicitly releases the cbinfo itself as well */
nkeynes@1077
    41
}
nkeynes@1077
    42
nkeynes@1077
    43
static void io_osx_net_callback( CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *unused, void *data )
nkeynes@1077
    44
{
nkeynes@1077
    45
    struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
nkeynes@998
    46
    if(!cbinfo->callback( CFSocketGetNative(s), cbinfo->cbdata) ) {
nkeynes@1077
    47
        io_unregister_callback(cbinfo);
nkeynes@998
    48
    }
nkeynes@998
    49
}
nkeynes@998
    50
nkeynes@1077
    51
static void io_osx_fd_callback( CFFileDescriptorRef f, CFOptionFlags type, void *data )
nkeynes@998
    52
{
nkeynes@1077
    53
    struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
nkeynes@1077
    54
    if(!cbinfo->callback( CFFileDescriptorGetNativeDescriptor(f), cbinfo->cbdata) ) {
nkeynes@1077
    55
        io_unregister_callback(cbinfo);
nkeynes@1077
    56
    }
nkeynes@1077
    57
}
nkeynes@1077
    58
nkeynes@1077
    59
static void io_osx_release( const void *data )
nkeynes@1077
    60
{
nkeynes@1077
    61
    struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
nkeynes@998
    62
    if( cbinfo->cbdealloc != NULL ) {
nkeynes@998
    63
        cbinfo->cbdealloc(cbinfo->cbdata);
nkeynes@998
    64
    }
nkeynes@998
    65
    free( cbinfo );
nkeynes@998
    66
}
nkeynes@998
    67
nkeynes@998
    68
/**
nkeynes@998
    69
 * Register a TCP server socket listener on an already open (and listening) 
nkeynes@998
    70
 * socket. The socket must not have been previously registered.
nkeynes@998
    71
 * @return TRUE on success, FALSE on failure.
nkeynes@998
    72
 * 
nkeynes@998
    73
 * Defined in netutil.h
nkeynes@998
    74
 */ 
nkeynes@1077
    75
io_listener_t io_register_tcp_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void*) )
nkeynes@998
    76
{
nkeynes@998
    77
    CFSocketContext socketContext;
nkeynes@1077
    78
    struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) );
nkeynes@998
    79
    assert(cbinfo != NULL);
nkeynes@998
    80
    
nkeynes@998
    81
    cbinfo->callback = callback;
nkeynes@998
    82
    cbinfo->cbdata = data;
nkeynes@998
    83
    cbinfo->cbdealloc = dealloc;
nkeynes@998
    84
    socketContext.version = 0;
nkeynes@998
    85
    socketContext.info = cbinfo;
nkeynes@998
    86
    socketContext.retain = NULL;
nkeynes@1077
    87
    socketContext.release = io_osx_release;
nkeynes@998
    88
    socketContext.copyDescription = NULL;
nkeynes@998
    89
    
nkeynes@1077
    90
    CFSocketRef ref = CFSocketCreateWithNative( kCFAllocatorDefault, fd, kCFSocketReadCallBack,
nkeynes@1077
    91
            io_osx_net_callback, &socketContext );
nkeynes@1077
    92
    cbinfo->fdRef = ref;
nkeynes@1077
    93
    cbinfo->sourceRef = CFSocketCreateRunLoopSource( kCFAllocatorDefault, ref, 0 );
nkeynes@998
    94
    CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
nkeynes@1071
    95
nkeynes@1077
    96
    return cbinfo;
nkeynes@998
    97
}
nkeynes@1077
    98
nkeynes@1077
    99
/**
nkeynes@1077
   100
 * Register a file descriptor listener on an already open (and listening)
nkeynes@1077
   101
 * file descriptor. The file descriptor must not have been previously registered.
nkeynes@1077
   102
 * @return TRUE on success, FALSE on failure.
nkeynes@1077
   103
 *
nkeynes@1077
   104
 */
nkeynes@1077
   105
io_listener_t io_register_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void *) )
nkeynes@1077
   106
{
nkeynes@1077
   107
    CFFileDescriptorContext fdContext;
nkeynes@1077
   108
    struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) );
nkeynes@1077
   109
    assert(cbinfo != NULL);
nkeynes@1077
   110
nkeynes@1077
   111
    cbinfo->callback = callback;
nkeynes@1077
   112
    cbinfo->cbdata = data;
nkeynes@1077
   113
    cbinfo->cbdealloc = dealloc;
nkeynes@1077
   114
    fdContext.version = 0;
nkeynes@1077
   115
    fdContext.retain = NULL;
nkeynes@1077
   116
    fdContext.info = cbinfo;
nkeynes@1077
   117
    fdContext.release = io_osx_release;
nkeynes@1077
   118
    fdContext.copyDescription = NULL;
nkeynes@1077
   119
nkeynes@1077
   120
    CFFileDescriptorRef ref = CFFileDescriptorCreate( kCFAllocatorDefault, fd, FALSE,
nkeynes@1077
   121
            io_osx_fd_callback, &fdContext);
nkeynes@1077
   122
    cbinfo->fdRef = ref;
nkeynes@1077
   123
    cbinfo->sourceRef = CFFileDescriptorCreateRunLoopSource( kCFAllocatorDefault, ref, 0 );
nkeynes@1077
   124
    CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes );
nkeynes@1077
   125
    return cbinfo;
nkeynes@1077
   126
}
nkeynes@1077
   127
nkeynes@1077
   128
void io_unregister_listener( io_listener_t data )
nkeynes@1077
   129
{
nkeynes@1077
   130
    struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data;
nkeynes@1077
   131
    io_unregister_callback(cbinfo);
nkeynes@1077
   132
}
.