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 /gio/giomm | |
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.
Diffstat (limited to 'gio/giomm')
-rw-r--r-- | gio/giomm/filelist.am | 4 | ||||
-rw-r--r-- | gio/giomm/socketsource.cc | 101 | ||||
-rw-r--r-- | gio/giomm/socketsource.h | 115 |
3 files changed, 218 insertions, 2 deletions
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 */ |