Socket/Protocols: Add SO_ERROR getsockopt (BSDSocketProtocol::error())
g0dil [Mon, 7 Apr 2008 08:24:23 +0000 (08:24 +0000)]
Scheduler: Implement binding helper

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@787 270642c3-0616-0410-b53a-bc976706d245

Scheduler/Binding.cci [new file with mode: 0644]
Scheduler/Binding.cti [new file with mode: 0644]
Scheduler/Binding.hh [new file with mode: 0644]
Scheduler/Binding.test.cc [new file with mode: 0644]
Socket/Protocols/BSDSocketProtocol.cc
Socket/Protocols/BSDSocketProtocol.hh

diff --git a/Scheduler/Binding.cci b/Scheduler/Binding.cci
new file mode 100644 (file)
index 0000000..fd2cec2
--- /dev/null
@@ -0,0 +1,68 @@
+// $Id$
+//
+// Copyright (C) 2008 
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief Binding inline non-template implementation */
+
+//#include "Binding.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+prefix_ senf::SchedulerBinding::~SchedulerBinding()
+{
+    disable();
+}
+
+prefix_ void senf::SchedulerBinding::enable()
+{
+    if (! enabled_) {
+        senf::Scheduler::instance().add(fd_, cb_, eventMask_);
+        enabled_ = true;
+    }
+}
+
+prefix_ void senf::SchedulerBinding::disable()
+{
+    if (enabled_) {
+        senf::Scheduler::instance().remove(fd_);
+        enabled_ = false;
+    }
+}
+
+prefix_ bool senf::SchedulerBinding::enabled()
+{
+    return enabled_;
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Scheduler/Binding.cti b/Scheduler/Binding.cti
new file mode 100644 (file)
index 0000000..3ae11e8
--- /dev/null
@@ -0,0 +1,52 @@
+// $Id$
+//
+// Copyright (C) 2008 
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief Binding inline template implementation */
+
+//#include "Binding.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Handle>
+prefix_ senf::SchedulerBinding::SchedulerBinding(Handle const & handle,
+                                                 Scheduler::FdCallback cb, int eventMask,
+                                                 bool enabled)
+    : fd_ (retrieve_filehandle(handle)), cb_ (cb), eventMask_ (eventMask), enabled_ (false)
+{
+    if (enabled)
+        enable();
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Scheduler/Binding.hh b/Scheduler/Binding.hh
new file mode 100644 (file)
index 0000000..e8b535b
--- /dev/null
@@ -0,0 +1,112 @@
+// $Id$
+//
+// Copyright (C) 2008 
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief Binding public header */
+
+#ifndef HH_Binding_
+#define HH_Binding_ 1
+
+// Custom includes
+#include <boost/utility.hpp>
+#include "Scheduler.hh"
+
+//#include "Binding.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+
+    /** \brief Manage scheduler handle binding
+
+        This class will manage the binding of an arbitrary handle to the scheduler: The handle will
+        automatically be removed from the Scheduler when this instance is destroyed. Example using a
+        SocketHandle instance for the handle:
+        \code
+        class Foo
+        {
+        public:
+            Foo(SocketHandle handle) : binding_ (handle, senf::membind(&cb, this),
+                                                 senf::Scheduler::EV_READ) {}
+
+            void blarf() { binding_.disable(); }
+
+        private:
+           void cb(Scheduler::EventId event);
+
+           senf::SchedulerBinding binding_;
+        };
+        \endcode
+
+        The handle will be registered automatically in the constructor and will be unregistered in
+        the destructor. Additionally, the helper has enable() and disable() members to register or
+        remove the handle to/from the Scheduler.
+     */
+    class SchedulerBinding
+        : boost::noncopyable
+    {
+    public:
+        template <class Handle>
+        SchedulerBinding(Handle const & handle, Scheduler::FdCallback cb, 
+                         int eventMask = Scheduler::EV_ALL, bool enabled = true);
+                                        ///< Register handle with the Scheduler
+                                        /**< This constructor is like calling Scheduler::add()
+                                             unless \a enabled is \c false, in which case the handle
+                                             is \e not initially registered (it may be registered by
+                                             caling enable() 
+                                             \param[in] handle Handle to register
+                                             \param[in] cb Callback
+                                             \param[in] eventMask type of events to register for
+                                             \param[in] enabled wether to add handle to Scheduler
+                                                 automatically  */
+
+        ~SchedulerBinding();            ///< Remove scheduler registration
+        
+        void enable();                  ///< Add handle to Scheduler
+                                        /**< Adds the handle if it is not already registered */
+        void disable();                 ///< Remove handle from Scheduler
+                                        /**< Remove handle from Scheduler if registered */
+
+        bool enabled();                 ///< \c true, if handle is registered
+
+    protected:
+
+    private:
+        int fd_;
+        Scheduler::FdCallback cb_;
+        int eventMask_;
+        bool enabled_;
+    };
+}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "Binding.cci"
+//#include "Binding.ct"
+#include "Binding.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Scheduler/Binding.test.cc b/Scheduler/Binding.test.cc
new file mode 100644 (file)
index 0000000..30e9526
--- /dev/null
@@ -0,0 +1,51 @@
+// $Id$
+//
+// Copyright (C) 2008 
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief Binding.test unit tests */
+
+//#include "Binding.test.hh"
+//#include "Binding.test.ih"
+
+// Custom includes
+#include "Binding.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(binding)
+{
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
index 79754e5..cfd06b5 100644 (file)
@@ -75,6 +75,16 @@ prefix_ void senf::BSDSocketProtocol::priority(boost::uint8_t value)
         SENF_THROW_SYSTEM_EXCEPTION("");
 }
 
+prefix_ int senf::BSDSocketProtocol::error()
+    const
+{
+    int err;
+    socklen_t len (sizeof(err));
+    if (::getsockopt(fd(),SOL_SOCKET,SO_ERROR,&err,&len) < 0)
+        SENF_THROW_SYSTEM_EXCEPTION("");
+    return err;
+}
+
 prefix_ unsigned senf::BSDSocketProtocol::rcvbuf()
     const
 {
index 341b70b..fbffeba 100644 (file)
@@ -71,6 +71,11 @@ namespace senf {
                                              sets the TOS field.
                                              \param[in] value new socket priority */
 
+        int error() const;              ///< Get and clear pending socket error
+                                        /**< This call will get <em>and clear</em> a pending socket
+                                             error. This includes asynchronous errors received via
+                                             the network (e.g. via ICMP). */
+
         unsigned rcvbuf() const;        ///< Check receive buffer size
                                         /**< \returns size of receive buffer in bytes 
                                              \internal Linux doubles the buffer size internally when