summaryrefslogtreecommitdiff
path: root/gio/giomm
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjell.ahlstedt@bredband.net>2014-05-15 13:09:07 +0200
committerKjell Ahlstedt <kjell.ahlstedt@bredband.net>2014-05-15 13:09:07 +0200
commit1e626a1885e99f7fb120505ee2b9427f1fc6c1d1 (patch)
treed625e534e8aba1de06513c7a7686d2fbe749c562 /gio/giomm
parentea7c6c8dac3286b12e9fa15dca4aa30f3b502b19 (diff)
downloadglibmm-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.am4
-rw-r--r--gio/giomm/socketsource.cc101
-rw-r--r--gio/giomm/socketsource.h115
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 */