Skip to content
Snippets Groups Projects
Commit c747ff7e authored by g0dil's avatar g0dil
Browse files

Scheduler: Implement IdleEvent

parent f0353f93
No related branches found
No related tags found
No related merge requests found
......@@ -91,6 +91,7 @@ namespace detail {
void prepareRun();
// Called by IdleEventDispatcher
void timeout(int t);
int timeout() const;
......
......@@ -61,11 +61,11 @@ namespace detail {
bool set(int fd, int events, Event * entry);
void remove(int fd);
void timeout(int t); ///< Set event timeout
/**< proceseOnce() will wait for max \a t milliseconds for
an event to occur. If set to -1, processOnce() will
wait forever. */
// Called by FileDispatcher
void timeout(int t);
int timeout() const;
void processOnce(); ///< Wait for events
/**< This call waits until at least one event is posted but
no longer than the current timeout(). */
......
// $Id$
//
// Copyright (C) 2009
// 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 IdleEvent non-inline non-template implementation */
#include "IdleEvent.hh"
#include "IdleEvent.ih"
// Custom includes
//#include "IdleEvent.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::scheduler::IdleEvent
prefix_ void senf::scheduler::IdleEvent::v_run()
{
cb_();
}
prefix_ char const * senf::scheduler::IdleEvent::v_type()
const
{
return "id";
}
prefix_ std::string senf::scheduler::IdleEvent::v_info()
const
{
return "";
}
///////////////////////////////////////////////////////////////////////////
// senf::scheduler::detail::IdleEventDispatcher
prefix_ void senf::scheduler::detail::IdleEventDispatcher::remove(IdleEvent & event)
{
EventList::iterator i (EventList::current(event));
if (i == events_.end())
return;
FIFORunner::instance().dequeue(&event);
events_.erase(i);
if (events_.empty())
detail::FileDispatcher::instance().timeout(managerTimeout_);
}
prefix_ void senf::scheduler::detail::IdleEventDispatcher::prepareRun()
{
for (EventList::iterator i (events_.begin()), i_end (events_.end()); i != i_end; ++i)
i->setRunnable();
}
prefix_ senf::scheduler::detail::IdleEventDispatcher::~IdleEventDispatcher()
{
for (EventList::iterator i (events_.begin()), i_end (events_.end()); i != i_end; ++i)
FIFORunner::instance().dequeue(&(*i));
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "IdleEvent.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:
// $Id$
//
// Copyright (C) 2009
// 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 IdleEvent inline non-template implementation */
#include "IdleEvent.ih"
// Custom includes
#include "FdEvent.hh"
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::scheduler::IdleEvent
prefix_ senf::scheduler::IdleEvent::IdleEvent(std::string const & name, Callback const & cb,
bool initiallyEnabled)
: detail::FIFORunner::TaskInfo(name), cb_ (cb)
{
if (initiallyEnabled)
enable();
}
prefix_ senf::scheduler::IdleEvent::~IdleEvent()
{
if (detail::IdleEventDispatcher::alive())
disable();
}
prefix_ void senf::scheduler::IdleEvent::disable()
{
if (enabled())
detail::IdleEventDispatcher::instance().remove(*this);
}
prefix_ void senf::scheduler::IdleEvent::enable()
{
if (! enabled()) {
detail::IdleEventDispatcher::instance().add(*this);
setRunnable();
}
}
prefix_ void senf::scheduler::IdleEvent::action(Callback const & cb)
{
cb_ = cb;
}
///////////////////////////////////////////////////////////////////////////
// senf::scheduler::detail::IdleEventDispatcher
prefix_ void senf::scheduler::detail::IdleEventDispatcher::add(IdleEvent & event)
{
events_.push_back(event);
FIFORunner::instance().enqueue(&event);
detail::FileDispatcher::instance().timeout(0);
}
prefix_ void senf::scheduler::detail::IdleEventDispatcher::timeout(int t)
{
managerTimeout_ = t;
if (events_.empty())
detail::FileDispatcher::instance().timeout(managerTimeout_);
}
prefix_ int senf::scheduler::detail::IdleEventDispatcher::timeout()
const
{
return managerTimeout_;
}
prefix_ bool senf::scheduler::detail::IdleEventDispatcher::empty()
const
{
return events_.empty();
}
prefix_ senf::scheduler::detail::IdleEventDispatcher::IdleEventDispatcher()
: managerTimeout_ (scheduler::detail::FileDispatcher::instance().timeout())
{}
/////////////////////////////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:
// $Id$
//
// Copyright (C) 2009
// 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 IdleEvent public header */
#ifndef HH_SENF_Scheduler_IdleEvent_
#define HH_SENF_Scheduler_IdleEvent_ 1
// Custom includes
#include <boost/function.hpp>
#include "../boost/intrusive/ilist_hook.hpp"
#include "FIFORunner.hh"
//#include "IdleEvent.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
namespace scheduler {
namespace detail {
struct IdleEventListTag;
typedef boost::intrusive::ilist_base_hook<IdleEventListTag> IdleEventListBase;
class IdleEventDispatcher;
}
class IdleEvent
: public detail::FIFORunner::TaskInfo,
public detail::IdleEventListBase
{
public:
///////////////////////////////////////////////////////////////////////////
// Types
typedef boost::function<void ()> Callback;
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///\{
IdleEvent(std::string const & name, Callback const & cb,
bool initiallyEnabled = true);
~IdleEvent();
///\}
///////////////////////////////////////////////////////////////////////////
void disable(); ///< Disable event
void enable(); ///< Enable event
void action(Callback const & cb); ///< Change event callback
protected:
private:
virtual void v_run();
virtual char const * v_type() const;
virtual std::string v_info() const;
Callback cb_;
friend class detail::IdleEventDispatcher;
};
}}
///////////////////////////////hh.e////////////////////////////////////////
#include "IdleEvent.cci"
//#include "IdleEvent.ct"
//#include "IdleEvent.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:
// $Id$
//
// Copyright (C) 2009
// 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 IdleEvent internal header */
#ifndef IH_SENF_Scheduler_IdleEvent_
#define IH_SENF_Scheduler_IdleEvent_ 1
// Custom includes
#include "../Utils/singleton.hh"
///////////////////////////////ih.p////////////////////////////////////////
namespace senf {
namespace scheduler {
void restart();
namespace detail {
class IdleEventDispatcher
: public singleton<IdleEventDispatcher>
{
public:
using singleton<IdleEventDispatcher>::instance;
using singleton<IdleEventDispatcher>::alive;
void add(IdleEvent & event);
void remove(IdleEvent & event);
void prepareRun();
// Called by PollTimerSource
void timeout(int t);
int timeout() const;
bool empty() const;
private:
IdleEventDispatcher();
~IdleEventDispatcher();
typedef boost::intrusive::ilist<
IdleEventListBase::value_traits<IdleEvent>, false > EventList;
EventList events_;
int managerTimeout_;
friend void senf::scheduler::restart();
friend class singleton<IdleEventDispatcher>;
};
}}}
///////////////////////////////ih.e////////////////////////////////////////
#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:
// $Id$
//
// Copyright (C) 2009
// 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 IdleEvent.test unit tests */
//#include "IdleEvent.test.hh"
//#include "IdleEvent.test.ih"
// Custom includes
#include "Scheduler.hh"
#include "../Utils/auto_unit_test.hh"
#include <boost/test/test_tools.hpp>
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
namespace {
bool timeoutFlag (false);
void timeout()
{
timeoutFlag = true;
senf::scheduler::terminate();
}
unsigned calls (0u);
void cb()
{
if (++calls >= 4)
senf::scheduler::terminate();
}
}
BOOST_AUTO_UNIT_TEST(idleEvent)
{
senf::scheduler::IdleEvent idle ("idle event unit test", &cb);
senf::scheduler::TimerEvent watchdog (
"IdleEvent unit test watchdog", &timeout,
senf::ClockService::now() + senf::ClockService::milliseconds(100));
senf::scheduler::process();
BOOST_CHECK( ! timeoutFlag );
BOOST_CHECK_EQUAL( calls, 4u );
}
///////////////////////////////cc.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:
......@@ -92,15 +92,16 @@ prefix_ void senf::scheduler::process()
{
SchedulerScopedInit initScheduler;
terminate_ = false;
running_ = true;
detail::TimerDispatcher::instance().reschedule();
while(! terminate_ && ! (detail::FdDispatcher::instance().empty() &&
detail::TimerDispatcher::instance().empty() &&
detail::FileDispatcher::instance().empty())) {
detail::FileDispatcher::instance().empty() &&
detail::IdleEventDispatcher::instance().empty()) ) {
detail::FdManager::instance().processOnce();
detail::FileDispatcher::instance().prepareRun();
detail::EventHookDispatcher::instance().prepareRun();
detail::TimerDispatcher::instance().prepareRun();
detail::IdleEventDispatcher::instance().prepareRun();
detail::FIFORunner::instance().run();
detail::TimerDispatcher::instance().reschedule();
}
......@@ -114,9 +115,11 @@ prefix_ void senf::scheduler::restart()
detail::TimerDispatcher* tdd (&detail::TimerDispatcher::instance());
detail::SignalDispatcher* sdd (&detail::SignalDispatcher::instance());
detail::FileDispatcher* fld (&detail::FileDispatcher::instance());
detail::IdleEventDispatcher* ied (&detail::IdleEventDispatcher::instance());
detail::EventHookDispatcher* eed (&detail::EventHookDispatcher::instance());
eed->~EventHookDispatcher();
ied->~IdleEventDispatcher();
fld->~FileDispatcher();
sdd->~SignalDispatcher();
tdd->~TimerDispatcher();
......@@ -130,6 +133,7 @@ prefix_ void senf::scheduler::restart()
new (tdd) detail::TimerDispatcher();
new (sdd) detail::SignalDispatcher();
new (fld) detail::FileDispatcher();
new (ied) detail::IdleEventDispatcher();
new (eed) detail::EventHookDispatcher();
}
......@@ -139,6 +143,7 @@ prefix_ bool senf::scheduler::empty()
&& detail::TimerDispatcher::instance().empty()
&& detail::FileDispatcher::instance().empty()
&& detail::SignalDispatcher::instance().empty()
&& detail::IdleEventDispatcher::instance().empty()
&& detail::EventHookDispatcher::instance().empty();
}
......@@ -160,7 +165,7 @@ prefix_ void senf::scheduler::hiresTimers()
prefix_ senf::log::time_type senf::scheduler::LogTimeSource::operator()()
const
{
return eventTime();
return now();
}
///////////////////////////////////////////////////////////////////////////
......
......@@ -33,6 +33,7 @@
#include "FdEvent.hh"
#include "TimerEvent.hh"
#include "SignalEvent.hh"
#include "IdleEvent.hh"
#include "EventHook.hh"
//#include "scheduler.mpp"
......
......@@ -27,7 +27,7 @@
//#include "TimerSource.ih"
// Custom includes
#include "FdEvent.hh"
#include "IdleEvent.hh"
#ifdef HAVE_TIMERFD
#include <sys/timerfd.h>
#endif
......@@ -157,12 +157,12 @@ prefix_ void senf::scheduler::detail::PollTimerSource::timeout(ClockService::clo
{
ClockService::clock_type now (ClockService::now());
int delay (ClockService::in_milliseconds(timeout-now)+1);
FileDispatcher::instance().timeout(delay<0?0:delay);
IdleEventDispatcher::instance().timeout(delay<0?0:delay);
}
prefix_ void senf::scheduler::detail::PollTimerSource::notimeout()
{
FileDispatcher::instance().timeout(-1);
IdleEventDispatcher::instance().timeout(-1);
}
prefix_ void senf::scheduler::detail::PollTimerSource::enable()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment