Scheduler: Fix ReadHelper to conform to new Scheduler API
g0dil [Wed, 19 Mar 2008 18:06:54 +0000 (18:06 +0000)]
Console: Implement skeletal console server
Console: Implement a rudimentary test server

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

Console/SConscript
Console/Server.cc [new file with mode: 0644]
Console/Server.hh [new file with mode: 0644]
Console/Server.ih [new file with mode: 0644]
Console/Server.test.cc [new file with mode: 0644]
Console/testServer.cc [new file with mode: 0644]
Scheduler/ReadHelper.ct

index ce543c3..fb3fe30 100644 (file)
@@ -5,10 +5,17 @@ import SENFSCons
 
 ###########################################################################
 
-sources = SENFSCons.GlobSources()
+sources = SENFSCons.GlobSources( exclude = [ 'testServer.cc' ] )
 SENFSCons.StandardTargets(env)
+
 SENFSCons.Lib(env,
               library = 'Console',
               sources = sources,
               LIBS = [ 'Socket', 'Scheduler', 'Utils' ])
+
+SENFSCons.Binary(env, 'testServer',
+                 sources = [ 'testServer.cc' ],
+                 no_includes = True,
+                 LIBS = [ 'Console', 'Socket', 'Scheduler', 'Utils' ])
+
 SENFSCons.Doxygen(env)
diff --git a/Console/Server.cc b/Console/Server.cc
new file mode 100644 (file)
index 0000000..8137f86
--- /dev/null
@@ -0,0 +1,139 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// 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 Server non-inline non-template implementation */
+
+#include "Server.hh"
+#include "Server.ih"
+
+// Custom includes
+#include <boost/algorithm/string/trim.hpp>
+#include "../Utils/senfassert.hh"
+#include "../Utils/membind.hh"
+#include "../Utils/Logger/SenfLog.hh"
+
+//#include "Server.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ void senf::console::start(senf::INet4SocketAddress const & address)
+{
+    senf::console::detail::Server::start(senf::TCPv4ServerSocketHandle(address));
+    SENF_LOG((detail::Server::SENFLogArea)(log::NOTICE)( 
+                 "Console server started at " << address ));
+}
+
+prefix_ void senf::console::start(senf::INet6SocketAddress const & address)
+{
+    senf::console::detail::Server::start(senf::TCPv6ServerSocketHandle(address));
+    SENF_LOG((detail::Server::SENFLogArea)(log::NOTICE)( 
+                 "Console server started at " << address ));
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::detail::Server
+
+boost::scoped_ptr<senf::console::detail::Server> senf::console::detail::Server::instance_;
+
+prefix_ void senf::console::detail::Server::start(ServerHandle handle)
+{
+    SENF_ASSERT( ! instance_ );
+    instance_.reset(new Server(handle));
+}
+
+prefix_ senf::console::detail::Server::Server(ServerHandle handle)
+    : handle_ (handle)
+{
+    Scheduler::instance().add( handle_, senf::membind(&Server::newClient, this) );
+}
+
+prefix_ senf::console::detail::Server::~Server()
+{
+    Scheduler::instance().remove(handle_);
+}
+
+prefix_ void senf::console::detail::Server::newClient(Scheduler::EventId event)
+{
+    ServerHandle::ClientSocketHandle client (handle_.accept());
+    boost::intrusive_ptr<Client> p (new Client(client));
+    clients_.insert( p );
+    SENF_LOG(( "Registered new client " << p.get() ));
+}
+
+prefix_ void senf::console::detail::Server::removeClient(Client & client)
+{
+    SENF_LOG(( "Disposing client " << & client ));
+    // THIS DELETES THE CLIENT INSTANCE !!
+    clients_.erase(boost::intrusive_ptr<Client>(&client));
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::detail::Client
+
+prefix_ senf::console::detail::Client::Client(ClientHandle handle)
+    : handle_ (handle)
+{
+    ReadHelper<ClientHandle>::dispatch( handle_, 16384u, ReadUntil("\n"),
+                                        senf::membind(&Client::clientData, this) );
+}
+
+prefix_ senf::console::detail::Client::~Client()
+{}
+
+prefix_ void senf::console::detail::Client::stopClient()
+{
+    // THIS COMMITS SUICIDE. THE INSTANCE IS GONE AFTER removeClient RETURNS
+    Server::instance_->removeClient(*this);
+}
+
+prefix_ void senf::console::detail::Client::clientData(ReadHelper<ClientHandle>::ptr helper)
+{
+    if (helper->error() || handle_.eof()) {
+        // THIS COMMITS SUICIDE. THE INSTANCE IS GONE AFTER stopClient RETURNS
+        stopClient();
+        return;
+    }
+
+    std::string data (tail_ + helper->data());
+    tail_ = helper->tail();
+    boost::trim(data); // Gets rid of superfluous  \r or \n characters
+
+    SENF_LOG(( this << ": " << data ));
+    ReadHelper<ClientHandle>::dispatch( handle_, 16384u, ReadUntil("\n"),
+                                        senf::membind(&Client::clientData, this) );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "Server.mpp"
+
+\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/Console/Server.hh b/Console/Server.hh
new file mode 100644 (file)
index 0000000..09bfbaf
--- /dev/null
@@ -0,0 +1,58 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// 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 Server public header */
+
+#ifndef HH_Server_
+#define HH_Server_ 1
+
+// Custom includes
+#include "../Socket/Protocols/INet/INetAddressing.hh"
+
+//#include "Server.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace console {
+
+    void start(senf::INet4SocketAddress const & address);
+    void start(senf::INet6SocketAddress const & address);
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Server.cci"
+//#include "Server.ct"
+//#include "Server.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/Console/Server.ih b/Console/Server.ih
new file mode 100644 (file)
index 0000000..8355450
--- /dev/null
@@ -0,0 +1,126 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// 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 Server internal header */
+
+#ifndef IH_Server_
+#define IH_Server_ 1
+
+// Custom includes
+#include <set>
+#include <boost/utility.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+#include "../Utils/intrusive_refcount.hh"
+#include "../Socket/Protocols/INet/TCPSocketHandle.hh"
+#include "../Socket/ServerSocketHandle.hh"
+#include "../Scheduler/Scheduler.hh"
+#include "../Scheduler/ReadHelper.hh"
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace senf {
+namespace console {
+namespace detail {
+
+    class Client;
+
+    /** \brief
+      */
+    class Server
+        : boost::noncopyable
+    {
+        SENF_LOG_CLASS_AREA();
+        SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef senf::ServerSocketHandle<
+            senf::MakeSocketPolicy< senf::TCPv4SocketProtocol::Policy, 
+                                    senf::UnspecifiedAddressingPolicy>::policy > ServerHandle;
+
+        ~Server();
+
+        static void start(ServerHandle handle);
+
+    protected:
+
+    private:
+        Server(ServerHandle handle);
+
+        void newClient(Scheduler::EventId event);
+        void removeClient(Client & client);
+        
+        ServerHandle handle_;
+        
+        typedef std::set< boost::intrusive_ptr<Client> > Clients;
+        Clients clients_;
+        
+        static boost::scoped_ptr<Server> instance_;
+        
+        friend class Client;
+    };
+    
+    /** \brief
+     */
+    class Client
+        : public senf::intrusive_refcount
+    {
+        SENF_LOG_CLASS_AREA();
+        SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
+    public:
+        typedef Server::ServerHandle::ClientSocketHandle ClientHandle;
+
+        ~Client();
+
+        void stopClient();
+
+    protected:
+        
+    private:
+        Client(ClientHandle handle);
+
+        void clientData(ReadHelper<ClientHandle>::ptr helper);
+        
+        ClientHandle handle_;
+        std::string tail_;
+
+        friend class Server;
+    };
+
+}}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#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/Console/Server.test.cc b/Console/Server.test.cc
new file mode 100644 (file)
index 0000000..0e5e9f6
--- /dev/null
@@ -0,0 +1,53 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// 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 Server.test unit tests */
+
+//#include "Server.test.hh"
+//#include "Server.test.ih"
+
+// Custom includes
+#include "Server.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(server)
+{}
+
+///////////////////////////////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:
diff --git a/Console/testServer.cc b/Console/testServer.cc
new file mode 100644 (file)
index 0000000..caf9106
--- /dev/null
@@ -0,0 +1,61 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// 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 test non-inline non-template implementation */
+
+//#include "test.hh"
+//#include "test.ih"
+
+// Custom includes
+#include <iostream>
+#include "Server.hh"
+#include "../Scheduler/Scheduler.hh"
+#include "../Utils/Logger/SenfLog.hh"
+
+//#include "test.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+int main(int, char const **)
+{
+    senf::log::ConsoleTarget::instance().route< senf::SenfLog, senf::log::NOTICE >();
+
+    senf::console::start( senf::INet4SocketAddress("127.0.0.1:23232") );
+
+    senf::Scheduler::instance().process();
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "test.mpp"
+
+\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 testServer"
+// End:
index 25f0364..981d970 100644 (file)
@@ -43,7 +43,7 @@ prefix_ senf::ReadHelper<Handle>::ReadHelper(Handle handle, std::string::size_ty
     // scheduler. This ensures, that the refcount is at least 1 as
     // long as the helper is registered with the scheduler.
     senf::Scheduler::instance()
-        .add(handle,boost::bind(&ReadHelper::dispatchProcess,ptr(this),_1,_2),
+        .add(handle,boost::bind(&ReadHelper::dispatchProcess,ptr(this), handle, _1),
              senf::Scheduler::EV_READ);
 }