From: g0dil Date: Fri, 4 Jul 2008 18:21:06 +0000 (+0000) Subject: Scheduler: Implement FileDispatcher X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=c4c0c1809c65d2b369e7888895f95c09f82116b9;p=senf.git Scheduler: Implement FileDispatcher git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@889 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Scheduler/FdDispatcher.cc b/Scheduler/FdDispatcher.cc index a393be5..7d033a3 100644 --- a/Scheduler/FdDispatcher.cc +++ b/Scheduler/FdDispatcher.cc @@ -64,29 +64,29 @@ prefix_ void senf::scheduler::FdDispatcher::add(int fd, Callback const & cb, int if (events & EV_PRIO) event.FdEvent::PrioTask::cb = cb; if (events & EV_WRITE) event.FdEvent::WriteTask::cb = cb; - manager_.set(fd, event.activeEvents(), &event); - } - - prefix_ void senf::scheduler::FdDispatcher::remove(int fd, int events) - { - if (events == 0) - return; - - FdMap::iterator i (fds_.find(fd)); - if (i == fds_.end()) - return; - FdEvent & event (i->second); - - if (events & EV_READ) event.FdEvent::ReadTask::cb = 0; - if (events & EV_PRIO) event.FdEvent::PrioTask::cb = 0; - if (events & EV_WRITE) event.FdEvent::WriteTask::cb = 0; - - int activeEvents (event.activeEvents()); - if (! activeEvents) { - manager_.remove(fd); - runner_.dequeue(static_cast(&i->second)); - runner_.dequeue(static_cast(&i->second)); - runner_.dequeue(static_cast(&i->second)); + manager_.set(fd, event.activeEvents(), &event); +} + +prefix_ void senf::scheduler::FdDispatcher::remove(int fd, int events) +{ + if (events == 0) + return; + + FdMap::iterator i (fds_.find(fd)); + if (i == fds_.end()) + return; + FdEvent & event (i->second); + + if (events & EV_READ) event.FdEvent::ReadTask::cb = 0; + if (events & EV_PRIO) event.FdEvent::PrioTask::cb = 0; + if (events & EV_WRITE) event.FdEvent::WriteTask::cb = 0; + + int activeEvents (event.activeEvents()); + if (! activeEvents) { + manager_.remove(fd); + runner_.dequeue(static_cast(&i->second)); + runner_.dequeue(static_cast(&i->second)); + runner_.dequeue(static_cast(&i->second)); fds_.erase(fd); } else manager_.set(fd, activeEvents, &event); diff --git a/Scheduler/FdDispatcher.hh b/Scheduler/FdDispatcher.hh index e586592..696be2a 100644 --- a/Scheduler/FdDispatcher.hh +++ b/Scheduler/FdDispatcher.hh @@ -81,9 +81,7 @@ namespace scheduler { typedef detail::FdTask<2, FdEvent> WriteTask; virtual void signal(int events); - int activeEvents() const; - int events; }; diff --git a/Scheduler/FileDispatcher.cc b/Scheduler/FileDispatcher.cc new file mode 100644 index 0000000..1989c90 --- /dev/null +++ b/Scheduler/FileDispatcher.cc @@ -0,0 +1,117 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// 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 FileDispatcher non-inline non-template implementation */ + +#include "FileDispatcher.hh" +//#include "FileDispatcher.ih" + +// Custom includes + +//#include "FileDispatcher.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +prefix_ senf::scheduler::FileDispatcher::FileDispatcher(FdManager & manager, + FIFORunner & runner) + : manager_ (manager), runner_ (runner), managerTimeout_ (manager.timeout()) +{} + +prefix_ senf::scheduler::FileDispatcher::~FileDispatcher() +{ + manager_.timeout(-1); + + for (FileMap::iterator i (files_.begin()); i != files_.end(); ++i) { + runner_.dequeue(static_cast(&i->second)); + runner_.dequeue(static_cast(&i->second)); + } +} + +prefix_ void senf::scheduler::FileDispatcher::add(int fd, Callback const & cb, int events) +{ + if (events == 0) + return; + + FileMap::iterator i (files_.find(fd)); + if (i == files_.end()) { + i = files_.insert(std::make_pair(fd, FileEvent())).first; + runner_.enqueue(static_cast(&i->second)); + runner_.enqueue(static_cast(&i->second)); + } + FileEvent & event (i->second); + + if (events & EV_READ) event.FileEvent::ReadTask::cb = cb; + if (events & EV_WRITE) event.FileEvent::WriteTask::cb = cb; + + manager_.timeout(0); +} + +prefix_ void senf::scheduler::FileDispatcher::remove(int fd, int events) +{ + if (events == 0) + return; + + FileMap::iterator i (files_.find(fd)); + if (i == files_.end()) + return; + FileEvent & event (i->second); + + if (events & EV_READ) event.FileEvent::ReadTask::cb = 0; + if (events & EV_WRITE) event.FileEvent::WriteTask::cb = 0; + + int activeEvents (event.activeEvents()); + if (! activeEvents) { + runner_.dequeue(static_cast(&i->second)); + runner_.dequeue(static_cast(&i->second)); + files_.erase(fd); + } + + if (files_.empty()) + manager_.timeout(managerTimeout_); +} + +prefix_ void senf::scheduler::FileDispatcher::prepareRun() +{ + for (FileMap::iterator i (files_.begin()); i != files_.end(); ++i) { + i->second.events = i->second.activeEvents(); + if (i->second.FileEvent::ReadTask::cb) + i->second.FileEvent::ReadTask::runnable = true; + if (i->second.FileEvent::WriteTask::cb) + i->second.FileEvent::WriteTask::runnable = true; + } +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ +//#include "FileDispatcher.mpp" + + +// 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/FileDispatcher.cci b/Scheduler/FileDispatcher.cci new file mode 100644 index 0000000..7d932d1 --- /dev/null +++ b/Scheduler/FileDispatcher.cci @@ -0,0 +1,66 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// 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 FileDispatcher inline non-template implementation */ + +//#include "FileDispatcher.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cci.p/////////////////////////////////////// + +prefix_ int senf::scheduler::FileDispatcher::FileEvent::activeEvents() + const +{ + return + (ReadTask::cb ? EV_READ : 0) | + (WriteTask::cb ? EV_WRITE : 0); +} + +prefix_ void senf::scheduler::FileDispatcher::timeout(int t) +{ + managerTimeout_ = t; + if (files_.empty()) + manager_.timeout(managerTimeout_); +} + +prefix_ int senf::scheduler::FileDispatcher::timeout() + const +{ + return managerTimeout_; +} + +///////////////////////////////cci.e/////////////////////////////////////// +#undef prefix_ + + +// 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/FileDispatcher.hh b/Scheduler/FileDispatcher.hh new file mode 100644 index 0000000..cd4b884 --- /dev/null +++ b/Scheduler/FileDispatcher.hh @@ -0,0 +1,115 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// 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 FileDispatcher public header */ + +#ifndef HH_FileDispatcher_ +#define HH_FileDispatcher_ 1 + +// Custom includes +#include +#include "FdManager.hh" +#include "FIFORunner.hh" +#include "FdDispatcher.hh" + +//#include "FileDispatcher.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace senf { +namespace scheduler { + + /** \brief + */ + class FileDispatcher + { + public: + /////////////////////////////////////////////////////////////////////////// + // Types + + typedef boost::function Callback; + + enum Events { + EV_READ = FdManager::EV_READ, EV_WRITE = FdManager::EV_WRITE, + EV_HUP = FdManager::EV_HUP, EV_ERR = FdManager::EV_ERR, + EV_ALL = FdManager::EV_READ | FdManager::EV_WRITE + }; + + /////////////////////////////////////////////////////////////////////////// + ///\name Structors and default members + ///@{ + + FileDispatcher(FdManager & manager, FIFORunner & runner); + ~FileDispatcher(); + + ///@} + /////////////////////////////////////////////////////////////////////////// + + void add(int fd, Callback const & cb, int events = EV_ALL); + void remove(int fd, int events = EV_ALL); + + void prepareRun(); + + void timeout(int t); + int timeout() const; + + protected: + + private: + struct FileEvent + : public detail::FdTask<0, FileEvent>, + public detail::FdTask<1, FileEvent> + { + typedef detail::FdTask<0, FileEvent> ReadTask; + typedef detail::FdTask<1, FileEvent> WriteTask; + + int activeEvents() const; + int events; + }; + + typedef std::map FileMap; + + FileMap files_; + FdManager & manager_; + FIFORunner & runner_; + int managerTimeout_; + }; + + +}} + +///////////////////////////////hh.e//////////////////////////////////////// +#include "FileDispatcher.cci" +//#include "FileDispatcher.ct" +//#include "FileDispatcher.cti" +#endif + + +// 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/FileDispatcher.test.cc b/Scheduler/FileDispatcher.test.cc new file mode 100644 index 0000000..045f125 --- /dev/null +++ b/Scheduler/FileDispatcher.test.cc @@ -0,0 +1,103 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// 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 FileDispatcher.test unit tests */ + +//#include "FileDispatcher.test.hh" +//#include "FileDispatcher.test.ih" + +// Custom includes +#include +#include +#include +#include +#include "FileDispatcher.hh" +#include "ClockService.hh" + +#include "../Utils/auto_unit_test.hh" +#include + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +namespace { + + bool is_close(senf::ClockService::clock_type a, senf::ClockService::clock_type b) + { + return (a