diff options
author | Kjell Ahlstedt <kjell.ahlstedt@bredband.net> | 2014-05-15 13:09:07 +0200 |
---|---|---|
committer | Kjell Ahlstedt <kjell.ahlstedt@bredband.net> | 2014-05-15 13:09:07 +0200 |
commit | 1e626a1885e99f7fb120505ee2b9427f1fc6c1d1 (patch) | |
tree | d625e534e8aba1de06513c7a7686d2fbe749c562 | |
parent | ea7c6c8dac3286b12e9fa15dca4aa30f3b502b19 (diff) | |
download | glibmm-1e626a1885e99f7fb120505ee2b9427f1fc6c1d1.tar.gz |
Add Gio:SocketSource, SignalSocket and Socket::create_source()
* .gitignore: Add !gio/giomm/socketsource.[cc|h].
* gio/giomm.h:
* gio/giomm/filelist.am: Add socketsource.h.
* gio/giomm/socketsource.[cc|h]: New files. SocketSource and SignalSocket.
* gio/src/socket.[ccg|hg]: Add create_source().
Remove many trailing blanks in socket.hg.
* glib/glibmm/main.[cc|h]: Add functions required when a class derived from
Source is defined in another file. Bug #725281.
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | gio/giomm.h | 1 | ||||
-rw-r--r-- | gio/giomm/filelist.am | 4 | ||||
-rw-r--r-- | gio/giomm/socketsource.cc | 101 | ||||
-rw-r--r-- | gio/giomm/socketsource.h | 115 | ||||
-rw-r--r-- | gio/src/socket.ccg | 9 | ||||
-rw-r--r-- | gio/src/socket.hg | 107 | ||||
-rw-r--r-- | glib/glibmm/main.cc | 39 | ||||
-rw-r--r-- | glib/glibmm/main.h | 23 |
9 files changed, 357 insertions, 46 deletions
@@ -84,10 +84,12 @@ giommconfig.h !/gio/giomm/contenttype.cc !/gio/giomm/init.cc !/gio/giomm/slot_async.cc +!/gio/giomm/socketsource.cc /gio/giomm/*.h !/gio/giomm/contenttype.h !/gio/giomm/init.h !/gio/giomm/slot_async.h +!/gio/giomm/socketsource.h !/gio/giomm/wrap_init.h # glib/ @@ -149,6 +151,8 @@ giommconfig.h /glib/glibmm/variant.h /glib/glibmm/variant_basictypes.cc /glib/glibmm/variant_basictypes.h +/glib/glibmm/variantdict.cc +/glib/glibmm/variantdict.h /glib/glibmm/variantiter.cc /glib/glibmm/variantiter.h /glib/glibmm/varianttype.cc diff --git a/gio/giomm.h b/gio/giomm.h index 5f31f092..1199a2fa 100644 --- a/gio/giomm.h +++ b/gio/giomm.h @@ -124,6 +124,7 @@ #include <giomm/socketcontrolmessage.h> #include <giomm/socketlistener.h> #include <giomm/socketservice.h> +#include <giomm/socketsource.h> #include <giomm/srvtarget.h> #include <giomm/tcpconnection.h> #include <giomm/themedicon.h> diff --git a/gio/giomm/filelist.am b/gio/giomm/filelist.am index ceee372a..24c0784e 100644 --- a/gio/giomm/filelist.am +++ b/gio/giomm/filelist.am @@ -4,6 +4,6 @@ giomm_files_built_cc = $(giomm_files_used_hg:.hg=.cc) wrap_init.cc giomm_files_built_h = $(giomm_files_used_hg:.hg=.h) giomm_files_built_ph = $(patsubst %.hg,private/%_p.h,$(giomm_files_used_hg)) -giomm_files_extra_cc = contenttype.cc init.cc slot_async.cc -giomm_files_extra_h = contenttype.h init.h wrap_init.h +giomm_files_extra_cc = contenttype.cc init.cc slot_async.cc socketsource.cc +giomm_files_extra_h = contenttype.h init.h socketsource.h wrap_init.h giomm_files_extra_ph = diff --git a/gio/giomm/socketsource.cc b/gio/giomm/socketsource.cc new file mode 100644 index 00000000..f17b41a3 --- /dev/null +++ b/gio/giomm/socketsource.cc @@ -0,0 +1,101 @@ +/* Copyright (C) 2014 The giomm Development Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <giomm/socketsource.h> +#include <giomm/socket.h> +#include <glibmm/exceptionhandler.h> +#include <glibmm/wrap.h> +#include <gio/gio.h> + +namespace +{ + +gboolean giomm_generic_socket_callback(sigc::slot_base* slot, GIOCondition condition) +{ + g_return_val_if_fail(slot != 0, 0); + + try + { + // Recreate the specific slot from the generic slot node. + return (*static_cast<sigc::slot<bool, Glib::IOCondition>*>(slot))((Glib::IOCondition)condition); + } + catch (...) + { + Glib::exception_handlers_invoke(); + } + return 0; +} + +gboolean giomm_signalsocket_callback(GSocket*, GIOCondition condition, void* user_data) +{ + sigc::slot_base* const slot = Glib::Source::get_slot_from_connection_node(user_data); + return giomm_generic_socket_callback(slot, condition); +} + +gboolean giomm_socketsource_callback(GSocket*, GIOCondition condition, void* user_data) +{ + sigc::slot_base* const slot = Glib::Source::get_slot_from_callback_data(user_data); + return giomm_generic_socket_callback(slot, condition); +} + +} // anonymous namespace + + +namespace Gio +{ + +/**** Glib::SignalSocket *******************************************************/ + +inline +SignalSocket::SignalSocket(GMainContext* context) +: + context_(context) +{} + +sigc::connection SignalSocket::connect(const sigc::slot<bool,Glib::IOCondition>& slot, + const Glib::RefPtr<Socket>& socket, Glib::IOCondition condition, + const Glib::RefPtr<Cancellable>& cancellable, int priority) +{ + GSource* const source = g_socket_create_source(socket->gobj(), (GIOCondition)condition, Glib::unwrap(cancellable)); + return Glib::Source::attach_signal_source(slot, priority, source, context_, + (GSourceFunc)&giomm_signalsocket_callback); +} + +SignalSocket signal_socket(const Glib::RefPtr<Glib::MainContext>& context) +{ + return SignalSocket(Glib::unwrap(context)); // 0 means default context +} + +/**** Glib::SocketSource *******************************************************/ + +// static +Glib::RefPtr<SocketSource> SocketSource::create(const Glib::RefPtr<Socket>& socket, Glib::IOCondition condition, + const Glib::RefPtr<Cancellable>& cancellable) +{ + return Glib::RefPtr<SocketSource>(new SocketSource(socket, condition, cancellable)); +} + +SocketSource::SocketSource(const Glib::RefPtr<Socket>& socket, Glib::IOCondition condition, + const Glib::RefPtr<Cancellable>& cancellable) +: + IOSource(g_socket_create_source(socket->gobj(), (GIOCondition)condition, Glib::unwrap(cancellable)), + (GSourceFunc)&giomm_socketsource_callback) +{} + +SocketSource::~SocketSource() +{} + +} // namespace Gio diff --git a/gio/giomm/socketsource.h b/gio/giomm/socketsource.h new file mode 100644 index 00000000..f166d753 --- /dev/null +++ b/gio/giomm/socketsource.h @@ -0,0 +1,115 @@ +#ifndef _GIOMM_SOCKETSOURCE_H +#define _GIOMM_SOCKETSOURCE_H + +/* Copyright (C) 2014 The giomm Development Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <glibmm/refptr.h> +#include <glibmm/main.h> +#include <glibmm/priorities.h> +#include <giomm/cancellable.h> +#include <sigc++/sigc++.h> + +namespace Gio +{ +class Socket; + +/** @newin{2,42} + * @ingroup NetworkIO + */ +class SignalSocket +{ +public: +#ifndef DOXYGEN_SHOULD_SKIP_THIS + explicit inline SignalSocket(GMainContext* context); +#endif + + /** Connects an I/O handler that watches a socket. + * @code + * bool io_handler(Glib::IOCondition io_condition) { ... } + * Gio::signal_socket().connect(sigc::ptr_fun(&io_handler), socket, Glib::IO_IN | Glib::IO_OUT); + * @endcode + * is equivalent to: + * @code + * bool io_handler(Glib::IOCondition io_condition) { ... } + * const Glib::RefPtr<Gio::SocketSource> socket_source = Gio::SocketSource::create(socket, Glib::IO_IN | Glib::IO_OUT); + * socket_source->connect(sigc::ptr_fun(&io_handler)); + * socket_source->attach(Glib::MainContext::get_default()); + * @endcode + * + * This method is not thread-safe. You should call it, or manipulate the + * returned sigc::connection object, only from the thread where the SignalSocket + * object's MainContext runs. + * + * @newin{2,42} + * @param slot A slot to call when polling @a socket results in an event that matches @a condition. + * The event will be passed as a parameter to @a slot. + * If <tt>io_handler()</tt> returns <tt>false</tt> the handler is disconnected. + * @param socket The Socket object to watch. + * @param condition The conditions to watch for. + * @param cancellable A Cancellable object which can be used to cancel the source, + * which will cause the source to trigger, reporting the current condition + * (which is likely 0 unless cancellation happened at the same time as a condition change). + * You can check for this in the callback using Cancellable::is_cancelled(). + * @param priority The priority of the new event source. + * @return A connection handle, which can be used to disconnect the handler. + */ + sigc::connection connect(const sigc::slot<bool, Glib::IOCondition>& slot, + const Glib::RefPtr<Socket>& socket, Glib::IOCondition condition, + const Glib::RefPtr<Cancellable>& cancellable = Glib::RefPtr<Cancellable>(), + int priority = Glib::PRIORITY_DEFAULT); + +private: + GMainContext* context_; + + // no copy assignment + SignalSocket& operator=(const SignalSocket&); +}; + + +/** Convenience socket signal. + * @param context The main context to which the signal shall be attached. + * @return A signal proxy; you want to use SignalSocket::connect(). + * + * @newin{2,42} + * @ingroup NetworkIO + */ +SignalSocket signal_socket(const Glib::RefPtr<Glib::MainContext>& context = Glib::RefPtr<Glib::MainContext>()); + + +/** An event source that can monitor a Gio::Socket. + * @see Gio::Socket::create_source(). + * + * @newin{2,42} + * @ingroup NetworkIO + */ +class SocketSource : public Glib::IOSource +{ +public: + typedef Gio::SocketSource CppObjectType; + + static Glib::RefPtr<SocketSource> create(const Glib::RefPtr<Socket>& socket, Glib::IOCondition condition, + const Glib::RefPtr<Cancellable>& cancellable = Glib::RefPtr<Cancellable>()); + +protected: + SocketSource(const Glib::RefPtr<Socket>& socket, Glib::IOCondition condition, + const Glib::RefPtr<Cancellable>& cancellable); + virtual ~SocketSource(); +}; + +} // namespace Gio + +#endif /* _GIOMM_SOCKETSOURCE_H */ diff --git a/gio/src/socket.ccg b/gio/src/socket.ccg index db7b095f..7a4a211d 100644 --- a/gio/src/socket.ccg +++ b/gio/src/socket.ccg @@ -20,6 +20,7 @@ #include <gio/gio.h> #include <glibmm/error.h> #include <giomm/asyncresult.h> +#include <giomm/socketsource.h> #include "slot_async.h" namespace Gio @@ -105,4 +106,12 @@ gssize Socket::send_with_blocking(gchar* buffer, gsize size, bool blocking, return retvalue; } +Glib::RefPtr<SocketSource> Socket::create_source(Glib::IOCondition condition, const Glib::RefPtr<Cancellable>& cancellable) +{ + // The corresponding unreference() takes place in the dtor + // of the Glib::RefPtr<Socket> object below. + reference(); + return SocketSource::create(Glib::RefPtr<Socket>(this), condition, cancellable); +} + } // namespace Gio diff --git a/gio/src/socket.hg b/gio/src/socket.hg index f0bce7bf..55236a40 100644 --- a/gio/src/socket.hg +++ b/gio/src/socket.hg @@ -31,6 +31,7 @@ _PINCLUDE(glibmm/private/object_p.h) namespace Gio { +class SocketSource; _WRAP_ENUM(SocketType, GSocketType) _WRAP_ENUM(SocketProtocol, GSocketProtocol) @@ -120,36 +121,36 @@ public: static Glib::RefPtr<Socket> create_from_fd(int fd, const Glib::RefPtr<Cancellable>& cancellable = Glib::RefPtr<Cancellable>()); - /** When a socket is created it is attached to an address family, but it doesn't - * have an address in this family. Socket::bind() assigns the address (sometimes + /** When a socket is created it is attached to an address family, but it doesn't + * have an address in this family. Socket::bind() assigns the address (sometimes * called name) of the socket. * - * It is generally required to bind to a local address before you can receive - * connections. (See Socket::listen() and Socket::accept()). In certain situations, - * you may also want to bind a socket that will be used to initiate connections, + * It is generally required to bind to a local address before you can receive + * connections. (See Socket::listen() and Socket::accept()). In certain situations, + * you may also want to bind a socket that will be used to initiate connections, * though this is not normally required. * - * If socket is a TCP socket, then @a allow_reuse controls the setting of the SO_REUSEADDR - * socket option; normally it should be <tt>true</tt> for server sockets (sockets that you - * will eventually call Socket::accept() on), and <tt>false</tt> for client sockets. - * (Failing to set this flag on a server socket may cause Socket::bind() to - * throw Gio::Error with ADDRESS_IN_USE if the server program + * If socket is a TCP socket, then @a allow_reuse controls the setting of the SO_REUSEADDR + * socket option; normally it should be <tt>true</tt> for server sockets (sockets that you + * will eventually call Socket::accept() on), and <tt>false</tt> for client sockets. + * (Failing to set this flag on a server socket may cause Socket::bind() to + * throw Gio::Error with ADDRESS_IN_USE if the server program * is stopped and then immediately restarted.) * - * If socket is a UDP socket, then @a allow_reuse determines whether or not - * other UDP sockets can be bound to the same address at the same time. In particular, - * you can have several UDP sockets bound to the same address, and they will all - * receive all of the multicast and broadcast packets sent to that address. + * If socket is a UDP socket, then @a allow_reuse determines whether or not + * other UDP sockets can be bound to the same address at the same time. In particular, + * you can have several UDP sockets bound to the same address, and they will all + * receive all of the multicast and broadcast packets sent to that address. * (The behavior of unicast UDP packets to an address with multiple listeners is not defined.) * - * @param address a SocketAddress specifying the local address. + * @param address a SocketAddress specifying the local address. * @param allow_reuse whether to allow reusing this address * * @throw Gio::Error */ _WRAP_METHOD(void bind(const Glib::RefPtr<SocketAddress>& address, bool allow_reuse), g_socket_bind, errthrow) - - /** Marks the socket as a server socket - a socket that is used to accept + + /** Marks the socket as a server socket - a socket that is used to accept * incoming requests using Socket::accept(). * * Before calling this the socket must be bound to a local address using Socket::bind(). @@ -159,17 +160,17 @@ public: * @throw Gio::Error */ _WRAP_METHOD(void listen(), g_socket_listen, errthrow) - - /** Accept incoming connections on a connection-based socket. This removes the - * first outstanding connection request from the listening socket and creates + + /** Accept incoming connections on a connection-based socket. This removes the + * first outstanding connection request from the listening socket and creates * a GSocket object for it. - * - * The socket must be bound to a local address with g_socket_bind() and must + * + * The socket must be bound to a local address with g_socket_bind() and must * be listening for incoming connections (Socket::listen()). * - * If there are no outstanding connections then the operation will block or - * throw Gio::Error with ERROR_WOULD_BLOCK if non-blocking - * I/O is enabled. To be notified of an incoming connection, wait for the + * If there are no outstanding connections then the operation will block or + * throw Gio::Error with ERROR_WOULD_BLOCK if non-blocking + * I/O is enabled. To be notified of an incoming connection, wait for the * Glib::IO_IN condition. * * @param cancellable A Cancellable object which can be used to cancel the operation. @@ -182,20 +183,20 @@ public: /** Connect the socket to the specified remote address. * - * For connection oriented socket this generally means we attempt to make a - * connection to the address . For a connection-less socket it sets the default + * For connection oriented socket this generally means we attempt to make a + * connection to the address . For a connection-less socket it sets the default * address for Socket::send() and discards all incoming datagrams from other sources. * - * Generally connection oriented sockets can only connect once, but + * Generally connection oriented sockets can only connect once, but * connection-less sockets can connect multiple times to change the default address. * - * If the connect call needs to do network I/O it will block, unless non-blocking - * I/O is enabled. Then Gio::Error with ERROR_PENDING is thrown - * and the user can be notified of the connection finishing by waiting for the - * Glib::IO_OUT condition. The result of the connection must then be checked + * If the connect call needs to do network I/O it will block, unless non-blocking + * I/O is enabled. Then Gio::Error with ERROR_PENDING is thrown + * and the user can be notified of the connection finishing by waiting for the + * Glib::IO_OUT condition. The result of the connection must then be checked * with Socket::check_connect_result(). * - * @param address a SocketAddress specifying the remote address. + * @param address a SocketAddress specifying the remote address. * @param cancellable A Cancellable object which can be used to cancel the operation. * * @throw Gio::Error @@ -223,17 +224,43 @@ public: _WRAP_METHOD(void close(), g_socket_close, errthrow) _WRAP_METHOD(bool is_closed(), g_socket_is_closed) - //TODO: Glib::Source has no wrap() method: _WRAP_METHOD(Glib::RefPtr<Glib::Source> create_source(Glib::IOCondition condition, const Glib::RefPtr<Cancellable>& cancellable{?}), g_socket_create_source) + /** Creates a SocketSource that can be attached to a Glib::MainContext to monitor + * for the availability of the specified @a condition on the socket. + * + * Create a slot from a function to be called when @a condition is met + * for the socket with sigc::ptr_fun() or sigc::mem_fun() and pass + * it into the connect() function of the returned SocketSource object. + * Polling of the socket will start when you attach a Glib::MainContext + * object to the returned SocketSource object using its attach() function. + * + * It is meaningless to specify Glib::IO_ERR or Glib::IO_HUP in @a condition; + * these conditions will always be reported output if they are true. + * + * @a cancellable can be used to cancel the source, which will + * cause the source to trigger, reporting the current condition (which + * is likely 0 unless cancellation happened at the same time as a + * condition change). You can check for this in the callback using + * Cancellable::is_cancelled(). + * + * If the socket has a timeout set, and it is reached before @a condition + * occurs, the source will then trigger anyway, reporting Glib::IO_IN or + * Glib::IO_OUT depending on @a condition. However, the socket will have been + * marked as having had a timeout, and so the next Socket I/O method + * you call will then fail with a Gio::IO_ERROR_TIMED_OUT. + * + * Gio::signal_socket().connect() is a simpler interface to the same functionality. + * + * @newin{2,42} + * @param condition A Glib::IOCondition mask to monitor. + * @param cancellable A Cancellable. The default value means the source is not cancellable. + * @return A newly allocated SocketSource. + */ + Glib::RefPtr<SocketSource> create_source(Glib::IOCondition condition, const Glib::RefPtr<Cancellable>& cancellable = Glib::RefPtr<Cancellable>()); + _IGNORE(g_socket_create_source) _WRAP_METHOD(void shutdown(bool shutdown_read, bool shutdown_write), g_socket_shutdown, errthrow) _WRAP_METHOD(bool is_connected(), g_socket_is_connected) - // TODO: non-cancellable version - // This won't work because Glib::Source is abstract, and Glib::IOSource has no - // constructor that takes a GSource* -//#m4 _CONVERSION(`GSource*',`Glib::RefPtr<Glib::Source>',`Glib::RefPtr<Glib::Source>(new ::Glib::Source($3))') - //_WRAP_METHOD(Glib::RefPtr<Glib::Source> create_source(Glib::IOCondition condition, const Glib::RefPtr<Cancellable>& cancellable{?}), g_socket_create_source) - _WRAP_METHOD(gssize get_available_bytes() const, g_socket_get_available_bytes) _WRAP_METHOD(Glib::IOCondition condition_check(Glib::IOCondition condition), g_socket_condition_check) diff --git a/glib/glibmm/main.cc b/glib/glibmm/main.cc index f6707b7c..1d9d9152 100644 --- a/glib/glibmm/main.cc +++ b/glib/glibmm/main.cc @@ -1064,6 +1064,40 @@ void Source::destroy_notify_callback(void* data) } } +// static +sigc::connection Source::attach_signal_source(const sigc::slot_base& slot, int priority, + GSource* source, GMainContext* context, GSourceFunc callback_func) +{ + SourceConnectionNode* const conn_node = new SourceConnectionNode(slot); + const sigc::connection connection(*conn_node->get_slot()); + + if (priority != G_PRIORITY_DEFAULT) + g_source_set_priority(source, priority); + + g_source_set_callback(source, callback_func, conn_node, + &SourceConnectionNode::destroy_notify_callback); + + conn_node->install(source); + g_source_attach(source, context); + g_source_unref(source); // GMainContext holds a reference + + return connection; +} + +// static +sigc::slot_base* Source::get_slot_from_connection_node(void* data) +{ + return static_cast<SourceConnectionNode*>(data)->get_slot(); +} + +// static +sigc::slot_base* Source::get_slot_from_callback_data(void* data) +{ + SourceCallbackData* const callback_data = static_cast<SourceCallbackData*>(data); + g_return_val_if_fail(callback_data->node != 0, 0); + return callback_data->node->get_slot(); +} + /**** Glib::TimeoutSource **************************************************/ @@ -1229,6 +1263,11 @@ IOSource::IOSource(const Glib::RefPtr<IOChannel>& channel, IOCondition condition (GSourceFunc) &glibmm_iosource_callback) {} +IOSource::IOSource(GSource* cast_item, GSourceFunc callback_func) +: + Source(cast_item, callback_func) +{} + IOSource::~IOSource() {} diff --git a/glib/glibmm/main.h b/glib/glibmm/main.h index 0664610b..94d495c1 100644 --- a/glib/glibmm/main.h +++ b/glib/glibmm/main.h @@ -784,8 +784,7 @@ protected: private: GSource* gobject_; -#ifndef DOXGEN_SHOULD_SKIP_THIS - +#ifndef DOXYGEN_SHOULD_SKIP_THIS static inline Source* get_wrapper(GSource* source); static const GSourceFuncs vfunc_table_; @@ -793,11 +792,19 @@ private: static gboolean prepare_vfunc(GSource* source, int* timeout); static gboolean check_vfunc(GSource* source); static gboolean dispatch_vfunc(GSource* source, GSourceFunc callback, void* user_data); + public: static void destroy_notify_callback(void* data); -private: + // Used by SignalXyz, possibly in other files. + static sigc::connection attach_signal_source(const sigc::slot_base& slot, int priority, + GSource* source, GMainContext* context, GSourceFunc callback_func); + // Used by SignalXyz in other files. + static sigc::slot_base* get_slot_from_connection_node(void* data); + // Used by derived Source classes in other files. + static sigc::slot_base* get_slot_from_callback_data(void* data); -#endif /* DOXGEN_SHOULD_SKIP_THIS */ +private: +#endif /* DOXYGEN_SHOULD_SKIP_THIS */ // noncopyable Source(const Source&); @@ -859,6 +866,14 @@ public: protected: IOSource(int fd, IOCondition condition); IOSource(const Glib::RefPtr<IOChannel>& channel, IOCondition condition); + + /** Wrap an existing GSource object and install the given callback function. + * This constructor is for use by derived types that need to wrap a GSource object. + * @see Source::Source(GSource*, GSourceFunc). + * @newin{2,42} + */ + IOSource(GSource* cast_item, GSourceFunc callback_func); + virtual ~IOSource(); virtual bool prepare(int& timeout); |