nkeynes@998 | 1 | /**
|
nkeynes@1021 | 2 | * $Id$
|
nkeynes@998 | 3 | *
|
nkeynes@998 | 4 | * Glib-based 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 <assert.h>
|
nkeynes@998 | 20 | #include <glib.h>
|
nkeynes@998 | 21 | #include <stdlib.h>
|
nkeynes@1077 | 22 | #include "ioutil.h"
|
nkeynes@998 | 23 |
|
nkeynes@1077 | 24 | struct io_glib_cbinfo {
|
nkeynes@1077 | 25 | io_callback_t callback;
|
nkeynes@1077 | 26 | guint sourceid;
|
nkeynes@998 | 27 | void * cbdata;
|
nkeynes@998 | 28 | void (*cbdealloc)(void *);
|
nkeynes@998 | 29 | };
|
nkeynes@998 | 30 |
|
nkeynes@1077 | 31 | static gboolean io_glib_callback( GIOChannel *source, GIOCondition cond, gpointer data )
|
nkeynes@998 | 32 | {
|
nkeynes@1077 | 33 | struct io_glib_cbinfo *cbinfo = (struct io_glib_cbinfo *)data;
|
nkeynes@998 | 34 | return cbinfo->callback( g_io_channel_unix_get_fd(source), cbinfo->cbdata);
|
nkeynes@998 | 35 | }
|
nkeynes@998 | 36 |
|
nkeynes@1077 | 37 | static void io_glib_release( void *data )
|
nkeynes@998 | 38 | {
|
nkeynes@1077 | 39 | struct io_glib_cbinfo *cbinfo = (struct io_glib_cbinfo *)data;
|
nkeynes@998 | 40 | if( cbinfo->cbdealloc ) {
|
nkeynes@998 | 41 | cbinfo->cbdealloc( cbinfo->cbdata );
|
nkeynes@998 | 42 | }
|
nkeynes@998 | 43 | free(cbinfo);
|
nkeynes@998 | 44 | }
|
nkeynes@998 | 45 |
|
nkeynes@998 | 46 | /**
|
nkeynes@998 | 47 | * Register a TCP server socket listener on an already open (and listening)
|
nkeynes@998 | 48 | * socket. The socket must not have been previously registered.
|
nkeynes@998 | 49 | * @return TRUE on success, FALSE on failure.
|
nkeynes@998 | 50 | *
|
nkeynes@998 | 51 | * Defined in netutil.h
|
nkeynes@998 | 52 | */
|
nkeynes@1077 | 53 | io_listener_t io_register_tcp_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void*) )
|
nkeynes@998 | 54 | {
|
nkeynes@1077 | 55 | return io_register_listener( fd, callback, data, dealloc );
|
nkeynes@1077 | 56 | }
|
nkeynes@1077 | 57 |
|
nkeynes@1077 | 58 | io_listener_t io_register_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void *) )
|
nkeynes@1077 | 59 | {
|
nkeynes@1077 | 60 | struct io_glib_cbinfo *cbinfo = malloc( sizeof(struct io_glib_cbinfo) );
|
nkeynes@998 | 61 | assert(cbinfo != NULL);
|
nkeynes@998 | 62 |
|
nkeynes@998 | 63 | cbinfo->callback = callback;
|
nkeynes@998 | 64 | cbinfo->cbdata = data;
|
nkeynes@998 | 65 | cbinfo->cbdealloc = dealloc;
|
nkeynes@998 | 66 |
|
nkeynes@998 | 67 | /**
|
nkeynes@998 | 68 | * Note magic here: the watch creates an event source which holds a
|
nkeynes@998 | 69 | * reference to the channel. We unref the channel so that the channel then
|
nkeynes@998 | 70 | * is automatically released when the event source goes away.
|
nkeynes@998 | 71 | */
|
nkeynes@998 | 72 | GIOChannel *chan = g_io_channel_unix_new(fd);
|
nkeynes@998 | 73 | g_io_channel_set_encoding( chan, NULL, NULL );
|
nkeynes@998 | 74 | g_io_channel_set_buffered(chan, FALSE);
|
nkeynes@1077 | 75 | cbinfo->sourceid = g_io_add_watch_full( chan, 0, G_IO_IN, io_glib_callback, cbinfo, io_glib_release );
|
nkeynes@998 | 76 | g_io_channel_unref( chan );
|
nkeynes@1077 | 77 | return cbinfo;
|
nkeynes@998 | 78 | }
|
nkeynes@1077 | 79 |
|
nkeynes@1077 | 80 |
|
nkeynes@1077 | 81 | void io_unregister_listener( io_listener_t data )
|
nkeynes@1077 | 82 | {
|
nkeynes@1077 | 83 | struct io_glib_cbinfo *cbinfo = (struct io_glib_cbinfo *)data;
|
nkeynes@1077 | 84 | g_source_remove(cbinfo->sourceid);
|
nkeynes@1077 | 85 | }
|