From: g0dil Date: Fri, 19 Sep 2008 14:03:55 +0000 (+0000) Subject: Scheduler: Remove obsolete 'Scheduler' class X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=ac90835cbb00ca83a51ab9efb23fdcb75518e808;p=senf.git Scheduler: Remove obsolete 'Scheduler' class Scheduler: Move remaining non-public implementation classes into 'detail' namespace Adjust rest of SENF accordingly git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@911 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Console/Mainpage.dox b/Console/Mainpage.dox index 07c55d4..b1636e3 100644 --- a/Console/Mainpage.dox +++ b/Console/Mainpage.dox @@ -87,7 +87,7 @@ .name("someServer"); // Run the scheduler - senf::Scheduler::instance().process(); + senf::scheduler::process(); } \endcode @@ -449,7 +449,7 @@ .name("myserver"); // You need to enter the scheduler main-loop for the server to work - senf::Scheduler::instance().process(); + senf::scheduler::process(); // Alternatively enter the main-loop via the PPI // senf::ppi::run(); diff --git a/Console/Readline.cc b/Console/Readline.cc index a02e2a8..188bc77 100644 --- a/Console/Readline.cc +++ b/Console/Readline.cc @@ -117,7 +117,7 @@ namespace { prefix_ senf::console::detail::ReadlineClientReader::ReadlineClientReader(Client & client) : ClientReader(client), ch_ (-1), skipChars_ (0), readevent_ ( "ReadlineClientReader", senf::membind(&ReadlineClientReader::charEvent, this), - client.handle(), Scheduler::EV_READ, false ), + client.handle(), scheduler::FdEvent::EV_READ, false ), terminate_ (false) { if (instance_ != 0) @@ -199,7 +199,7 @@ prefix_ void senf::console::detail::ReadlineClientReader::v_translate(std::strin prefix_ void senf::console::detail::ReadlineClientReader::charEvent(int event) { char ch; - if (event != Scheduler::EV_READ || handle().read(&ch, &ch+1) <= &ch) { + if (event != scheduler::FdEvent::EV_READ || handle().read(&ch, &ch+1) <= &ch) { stopClient(); return; } diff --git a/Console/Server.cc b/Console/Server.cc index df6c421..63b922b 100644 --- a/Console/Server.cc +++ b/Console/Server.cc @@ -85,9 +85,6 @@ senf::console::Server::start(senf::INet6SocketAddress const & address) prefix_ senf::console::Server & senf::console::Server::start(ServerHandle handle) { - // Uah .... ensure the scheduler is created before the instance pointer so it get's destructed - // AFTER it. - (void) senf::Scheduler::instance(); boost::intrusive_ptr p (new Server(handle)); detail::ServerManager::add(boost::intrusive_ptr(p)); return *p; @@ -184,7 +181,7 @@ senf::console::detail::NoninteractiveClientReader::NoninteractiveClientReader(Cl : ClientReader (client), readevent_ ("NoninteractiveClientReader", senf::membind(&NoninteractiveClientReader::newData, this), - handle(), senf::Scheduler::EV_READ) + handle(), senf::scheduler::FdEvent::EV_READ) {} prefix_ void senf::console::detail::NoninteractiveClientReader::v_disablePrompt() @@ -199,7 +196,7 @@ prefix_ void senf::console::detail::NoninteractiveClientReader::v_translate(std: prefix_ void senf::console::detail::NoninteractiveClientReader::newData(int event) { - if (event != senf::Scheduler::EV_READ || handle().eof()) { + if (event != senf::scheduler::FdEvent::EV_READ || handle().eof()) { if (! buffer_.empty()) handleInput(buffer_); stopClient(); @@ -221,10 +218,10 @@ prefix_ senf::console::Client::Client(Server & server, ClientHandle handle) : out_t(boost::ref(*this)), senf::log::IOStreamTarget(out_t::member), server_ (server), handle_ (handle), readevent_ ("senf::console::Client", boost::bind(&Client::setNoninteractive,this), - handle, Scheduler::EV_READ, false), + handle, scheduler::FdEvent::EV_READ, false), timer_ ("senf::console::Client interactive timeout", boost::bind(&Client::setInteractive, this), - Scheduler::instance().eventTime() + ClockService::milliseconds(INTERACTIVE_TIMEOUT), + scheduler::eventTime() + ClockService::milliseconds(INTERACTIVE_TIMEOUT), false), name_ (server.name()), reader_ (), mode_ (server.mode()) { diff --git a/Console/testServer.cc b/Console/testServer.cc index 1d0ed58..7458055 100644 --- a/Console/testServer.cc +++ b/Console/testServer.cc @@ -62,7 +62,7 @@ struct TestObject void shutdownServer() { - senf::Scheduler::instance().terminate(); + senf::scheduler::terminate(); throw senf::console::Executor::ExitException(); } @@ -113,7 +113,7 @@ int main(int, char **) senf::console::Server::start( senf::INet4SocketAddress(23232u) ) .name("testServer"); - senf::Scheduler::instance().process(); + senf::scheduler::process(); } diff --git a/Examples/MCSniffer/MCSniffer.cc b/Examples/MCSniffer/MCSniffer.cc index 0d6fb37..b82dc2a 100644 --- a/Examples/MCSniffer/MCSniffer.cc +++ b/Examples/MCSniffer/MCSniffer.cc @@ -82,7 +82,7 @@ int main(int argc, char const * argv[]) MCSniffer sniffer2 ( senf::INet4Address::from_string("233.132.152.2"), f2); - senf::Scheduler::instance().process(); + senf::scheduler::process(); } catch (std::exception const & ex) { std::cerr << senf::prettyName(typeid(ex)) << ": " << ex.what() << "\n"; diff --git a/Examples/Sniffer/Sniffer.cc b/Examples/Sniffer/Sniffer.cc index 48e17ed..2582ad0 100644 --- a/Examples/Sniffer/Sniffer.cc +++ b/Examples/Sniffer/Sniffer.cc @@ -79,7 +79,7 @@ public: void run() { - senf::Scheduler::instance().process(); + senf::scheduler::process(); } private: diff --git a/Examples/TCPClientServer/server.cc b/Examples/TCPClientServer/server.cc index 6eab3a2..40e3139 100644 --- a/Examples/TCPClientServer/server.cc +++ b/Examples/TCPClientServer/server.cc @@ -48,7 +48,7 @@ public: void run() { - senf::Scheduler::instance().process(); + senf::scheduler::process(); } private: diff --git a/Examples/UDPClientServer/udpServer.cc b/Examples/UDPClientServer/udpServer.cc index 201ca3f..fbc16e4 100644 --- a/Examples/UDPClientServer/udpServer.cc +++ b/Examples/UDPClientServer/udpServer.cc @@ -41,7 +41,7 @@ public: void run() { event.enable(); - senf::Scheduler::instance().process(); + senf::scheduler::process(); } private: diff --git a/PPI/EventManager.cci b/PPI/EventManager.cci index 156e374..bc3f5e0 100644 --- a/PPI/EventManager.cci +++ b/PPI/EventManager.cci @@ -42,7 +42,7 @@ prefix_ senf::ppi::EventManager & senf::ppi::EventManager::instance() prefix_ senf::ClockService::clock_type senf::ppi::EventManager::now() { - return Scheduler::instance().eventTime(); + return scheduler::eventTime(); } prefix_ senf::ClockService::clock_type senf::ppi::EventManager::time() diff --git a/PPI/IOEvent.hh b/PPI/IOEvent.hh index 7707cfb..d9d771d 100644 --- a/PPI/IOEvent.hh +++ b/PPI/IOEvent.hh @@ -77,11 +77,11 @@ namespace ppi { // with the enumeration symbols enum EventFlags { - Read = Scheduler::EV_READ /**< FileHandle is readable */ - , Prio = Scheduler::EV_PRIO /**< FileHandle priority data is readable */ - , Write = Scheduler::EV_WRITE /**< FileHandle is writable */ - , Hup = Scheduler::EV_HUP /**< Hangup condition on FileHandle */ - , Err = Scheduler::EV_ERR /**< Some other error condition on FileHandle */ + Read = scheduler::FdEvent::EV_READ /**< FileHandle is readable */ + , Prio = scheduler::FdEvent::EV_PRIO /**< FileHandle priority data is readable */ + , Write = scheduler::FdEvent::EV_WRITE /**< FileHandle is writable */ + , Hup = scheduler::FdEvent::EV_HUP /**< Hangup condition on FileHandle */ + , Err = scheduler::FdEvent::EV_ERR /**< Some other error condition on FileHandle */ }; /////////////////////////////////////////////////////////////////////////// diff --git a/PPI/ModuleManager.cc b/PPI/ModuleManager.cc index a356eee..490bb01 100644 --- a/PPI/ModuleManager.cc +++ b/PPI/ModuleManager.cc @@ -60,7 +60,7 @@ prefix_ void senf::ppi::ModuleManager::run() { init(); RunGuard guard (*this); - Scheduler::instance().process(); + scheduler::process(); } //////////////////////////////////////// diff --git a/PPI/SocketSink.test.cc b/PPI/SocketSink.test.cc index d2b9435..fa2f062 100644 --- a/PPI/SocketSink.test.cc +++ b/PPI/SocketSink.test.cc @@ -47,7 +47,7 @@ namespace debug = module::debug; namespace { void timeout() { - senf::Scheduler::instance().terminate(); + senf::scheduler::terminate(); } } diff --git a/PPI/SocketSource.test.cc b/PPI/SocketSource.test.cc index bb1c59d..a1f3711 100644 --- a/PPI/SocketSource.test.cc +++ b/PPI/SocketSource.test.cc @@ -47,7 +47,7 @@ namespace debug = module::debug; namespace { void timeout() { - senf::Scheduler::instance().terminate(); + senf::scheduler::terminate(); } } diff --git a/Scheduler/FIFORunner.cc b/Scheduler/FIFORunner.cc index 35858a0..2b54eb6 100644 --- a/Scheduler/FIFORunner.cc +++ b/Scheduler/FIFORunner.cc @@ -36,7 +36,7 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ senf::scheduler::FIFORunner::FIFORunner() +prefix_ senf::scheduler::detail::FIFORunner::FIFORunner() : tasks_ (), next_ (tasks_.end()), watchdogMs_ (1000), watchdogCount_(0), hangCount_ (0) { struct sigevent ev; @@ -61,7 +61,7 @@ prefix_ senf::scheduler::FIFORunner::FIFORunner() SENF_THROW_SYSTEM_EXCEPTION("sigprocmask()"); } -prefix_ senf::scheduler::FIFORunner::~FIFORunner() +prefix_ senf::scheduler::detail::FIFORunner::~FIFORunner() { timer_delete(watchdogId_); signal(SIGURG, SIG_DFL); @@ -89,7 +89,7 @@ prefix_ senf::scheduler::FIFORunner::~FIFORunner() // will mostly be localized to the end of the queue. only occasionally one of the dormant tasks will // be runnable. This additional traversal time will be amortized over a larger time. -prefix_ void senf::scheduler::FIFORunner::dequeue(TaskInfo * task) +prefix_ void senf::scheduler::detail::FIFORunner::dequeue(TaskInfo * task) { TaskList::iterator i (TaskList::current(*task)); if (next_ == i) @@ -99,14 +99,14 @@ prefix_ void senf::scheduler::FIFORunner::dequeue(TaskInfo * task) namespace { struct NullTask - : public senf::scheduler::FIFORunner::TaskInfo + : public senf::scheduler::detail::FIFORunner::TaskInfo { - NullTask() : senf::scheduler::FIFORunner::TaskInfo ("") {} + NullTask() : senf::scheduler::detail::FIFORunner::TaskInfo ("") {} void run() {}; }; } -prefix_ void senf::scheduler::FIFORunner::run() +prefix_ void senf::scheduler::detail::FIFORunner::run() { // This algorithm is carefully adjusted to make it work even when arbitrary tasks are removed // from the queue @@ -169,7 +169,7 @@ prefix_ void senf::scheduler::FIFORunner::run() next_ = tasks_.end(); } -prefix_ void senf::scheduler::FIFORunner::watchdog(int, siginfo_t * si, void *) +prefix_ void senf::scheduler::detail::FIFORunner::watchdog(int, siginfo_t * si, void *) { FIFORunner & runner (*static_cast(si->si_value.sival_ptr)); if (runner.watchdogCount_ > 0) { diff --git a/Scheduler/FIFORunner.cci b/Scheduler/FIFORunner.cci index 209bd99..536865c 100644 --- a/Scheduler/FIFORunner.cci +++ b/Scheduler/FIFORunner.cci @@ -34,19 +34,19 @@ #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// -prefix_ senf::scheduler::FIFORunner::TaskInfo::TaskInfo(std::string const & name) +prefix_ senf::scheduler::detail::FIFORunner::TaskInfo::TaskInfo(std::string const & name) : runnable_ (false), name_ (name) {} -prefix_ senf::scheduler::FIFORunner::TaskInfo::~TaskInfo() +prefix_ senf::scheduler::detail::FIFORunner::TaskInfo::~TaskInfo() {} -prefix_ void senf::scheduler::FIFORunner::TaskInfo::setRunnable() +prefix_ void senf::scheduler::detail::FIFORunner::TaskInfo::setRunnable() { runnable_ = true; } -prefix_ void senf::scheduler::FIFORunner::enqueue(TaskInfo * task) +prefix_ void senf::scheduler::detail::FIFORunner::enqueue(TaskInfo * task) { tasks_.push_back(*task); #ifdef SENF_DEBUG @@ -56,18 +56,18 @@ prefix_ void senf::scheduler::FIFORunner::enqueue(TaskInfo * task) #endif } -prefix_ void senf::scheduler::FIFORunner::taskTimeout(unsigned ms) +prefix_ void senf::scheduler::detail::FIFORunner::taskTimeout(unsigned ms) { watchdogMs_ = ms; } -prefix_ unsigned senf::scheduler::FIFORunner::taskTimeout() +prefix_ unsigned senf::scheduler::detail::FIFORunner::taskTimeout() const { return watchdogMs_; } -prefix_ unsigned senf::scheduler::FIFORunner::hangCount() +prefix_ unsigned senf::scheduler::detail::FIFORunner::hangCount() const { return hangCount_; diff --git a/Scheduler/FIFORunner.hh b/Scheduler/FIFORunner.hh index 3887a3d..a6db0a5 100644 --- a/Scheduler/FIFORunner.hh +++ b/Scheduler/FIFORunner.hh @@ -37,20 +37,12 @@ ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { - - class Scheduler; - namespace scheduler { - /** \brief Task execution scheduler + void restart(); - The FIFORunner implements a simple FIFO scheduler for callback tasks. All tasks are held in - a queue. Whenever a task is run, it is moved to the end of the queue. Running the queue will - run all tasks which have been marked runnable. +namespace detail { - When running a task, it's runnable flag is always reset. The flag is set whenever an event - is posted for the task. - */ class FIFORunner : public singleton { @@ -63,13 +55,6 @@ namespace scheduler { typedef boost::intrusive::ilist, false> TaskList; public: - /////////////////////////////////////////////////////////////////////////// - // Types - - /** \brief Task structure - - TaskInfo is the base-class for all tasks. - */ class TaskInfo : public TaskListBase { @@ -91,24 +76,16 @@ namespace scheduler { friend class FIFORunner; }; - - /////////////////////////////////////////////////////////////////////////// - ///\name Structors and default members - ///@{ - using singleton::instance; using singleton::alive; - ///@} - /////////////////////////////////////////////////////////////////////////// - - void enqueue(TaskInfo * task); ///< Add task to queue - void dequeue(TaskInfo * task); ///< Remove task from queue + void enqueue(TaskInfo * task); + void dequeue(TaskInfo * task); - void run(); ///< Run queue + void run(); - void taskTimeout(unsigned ms); ///< Set task timeout to \a ms milliseconds - unsigned taskTimeout() const; ///< Get task timeout in milliseconds + void taskTimeout(unsigned ms); + unsigned taskTimeout() const; unsigned hangCount() const; ///< Number of task expirations /**< The FIFORunner manages a watchdog which checks, that a @@ -135,11 +112,11 @@ namespace scheduler { unsigned watchdogCount_; unsigned hangCount_; + friend void senf::scheduler::restart(); friend class singleton; - friend class senf::Scheduler; }; -}} +}}} ///////////////////////////////hh.e//////////////////////////////////////// #include "FIFORunner.cci" diff --git a/Scheduler/FdEvent.cc b/Scheduler/FdEvent.cc index 58c3d7e..f6a6396 100644 --- a/Scheduler/FdEvent.cc +++ b/Scheduler/FdEvent.cc @@ -39,8 +39,8 @@ prefix_ senf::scheduler::detail::FdDispatcher::~FdDispatcher() { for (FdSet::iterator i (fds_.begin()); i != fds_.end(); ++i) { - FdManager::instance().remove(i->fd_); - FIFORunner::instance().dequeue(&(*i)); + detail::FdManager::instance().remove(i->fd_); + detail::FIFORunner::instance().dequeue(&(*i)); } } @@ -53,10 +53,10 @@ prefix_ bool senf::scheduler::detail::FdDispatcher::add(FdEvent & event) if (event.events_ & events) throw FdEvent::DuplicateEventRegistrationException(); - if (! FdManager::instance().set(event.fd_, events | event.events_, &event)) + if (! detail::FdManager::instance().set(event.fd_, events | event.events_, &event)) return false; - FIFORunner::instance().enqueue(&event); + detail::FIFORunner::instance().enqueue(&event); fds_.insert(range.first, event); return true; @@ -65,16 +65,16 @@ prefix_ bool senf::scheduler::detail::FdDispatcher::add(FdEvent & event) prefix_ void senf::scheduler::detail::FdDispatcher::remove(FdEvent & event) { fds_.erase(FdSet::current(event)); - FIFORunner::instance().dequeue(&event); + detail::FIFORunner::instance().dequeue(&event); std::pair range (fds_.equal_range(event)); if (range.first == range.second) - FdManager::instance().remove(event.fd_); + detail::FdManager::instance().remove(event.fd_); else { int events (0); for (FdSet::iterator i (range.first); i != range.second; ++i) events |= i->events_; - FdManager::instance().set(event.fd_, events, &(*range.first)); + detail::FdManager::instance().set(event.fd_, events, &(*range.first)); } } @@ -90,21 +90,21 @@ prefix_ void senf::scheduler::detail::FileDispatcher::add(FdEvent & event) if (event.events_ & events) throw FdEvent::DuplicateEventRegistrationException(); - FIFORunner::instance().enqueue(&event); + detail::FIFORunner::instance().enqueue(&event); fds_.insert(range.first, event); - FdManager::instance().timeout(0); + detail::FdManager::instance().timeout(0); } prefix_ senf::scheduler::detail::FileDispatcher::FileDispatcher() - : managerTimeout_ (scheduler::FdManager::instance().timeout()) + : managerTimeout_ (scheduler::detail::FdManager::instance().timeout()) {} prefix_ senf::scheduler::detail::FileDispatcher::~FileDispatcher() { - FdManager::instance().timeout(-1); + detail::FdManager::instance().timeout(-1); for (FdSet::iterator i (fds_.begin()); i != fds_.end(); ++i) - FIFORunner::instance().dequeue(&(*i)); + detail::FIFORunner::instance().dequeue(&(*i)); } prefix_ void senf::scheduler::detail::FileDispatcher::prepareRun() @@ -118,9 +118,9 @@ prefix_ void senf::scheduler::detail::FileDispatcher::prepareRun() prefix_ void senf::scheduler::detail::FileDispatcher::remove(FdEvent & event) { fds_.erase(FdSet::current(event)); - FIFORunner::instance().dequeue(&event); + detail::FIFORunner::instance().dequeue(&event); if (fds_.empty()) - FdManager::instance().timeout(managerTimeout_); + detail::FdManager::instance().timeout(managerTimeout_); } /////////////////////////////////////////////////////////////////////////// diff --git a/Scheduler/FdEvent.cci b/Scheduler/FdEvent.cci index 5391f71..6573739 100644 --- a/Scheduler/FdEvent.cci +++ b/Scheduler/FdEvent.cci @@ -36,7 +36,7 @@ // senf::scheduler::FdEvent prefix_ senf::scheduler::FdEvent::FdEvent(std::string const & name, Callback const & cb) - : FIFORunner::TaskInfo (name), cb_ (cb), fd_ (-1), pollable_ (true), events_ (0) + : detail::FIFORunner::TaskInfo (name), cb_ (cb), fd_ (-1), pollable_ (true), events_ (0) {} prefix_ senf::scheduler::FdEvent::~FdEvent() @@ -92,7 +92,7 @@ prefix_ void senf::scheduler::detail::FileDispatcher::timeout(int t) { managerTimeout_ = t; if (fds_.empty()) - FdManager::instance().timeout(managerTimeout_); + detail::FdManager::instance().timeout(managerTimeout_); } prefix_ int senf::scheduler::detail::FileDispatcher::timeout() diff --git a/Scheduler/FdEvent.cti b/Scheduler/FdEvent.cti index f33ef1c..44b7299 100644 --- a/Scheduler/FdEvent.cti +++ b/Scheduler/FdEvent.cti @@ -37,7 +37,7 @@ template prefix_ senf::scheduler::FdEvent::FdEvent(std::string const & name, Callback const & cb, Handle const & handle, int events, bool initiallyEnabled) - : FIFORunner::TaskInfo (name), cb_ (cb), fd_ (retrieve_filehandle(handle)), pollable_ (true), + : detail::FIFORunner::TaskInfo (name), cb_ (cb), fd_ (retrieve_filehandle(handle)), pollable_ (true), events_ (events) { if (initiallyEnabled) diff --git a/Scheduler/FdEvent.hh b/Scheduler/FdEvent.hh index 736c3cf..b22c4b2 100644 --- a/Scheduler/FdEvent.hh +++ b/Scheduler/FdEvent.hh @@ -76,9 +76,9 @@ namespace scheduler { callback is a member function it should be defined as a class member). */ class FdEvent - : public FIFORunner::TaskInfo, + : public detail::FIFORunner::TaskInfo, public detail::FdSetBase, - public FdManager::Event + public detail::FdManager::Event { public: /////////////////////////////////////////////////////////////////////////// @@ -87,9 +87,15 @@ namespace scheduler { typedef boost::function Callback; enum Events { - EV_READ = FdManager::EV_READ, EV_PRIO = FdManager::EV_PRIO, EV_WRITE = FdManager::EV_WRITE, - EV_HUP = FdManager::EV_HUP, EV_ERR = FdManager::EV_ERR, - EV_ALL = FdManager::EV_READ | FdManager::EV_WRITE | FdManager::EV_PRIO + EV_NONE = 0, + EV_READ = detail::FdManager::EV_READ, + EV_PRIO = detail::FdManager::EV_PRIO, + EV_WRITE = detail::FdManager::EV_WRITE, + EV_HUP = detail::FdManager::EV_HUP, + EV_ERR = detail::FdManager::EV_ERR, + EV_ALL = (detail::FdManager::EV_READ + | detail::FdManager::EV_WRITE + | detail::FdManager::EV_PRIO) }; /////////////////////////////////////////////////////////////////////////// diff --git a/Scheduler/FdEvent.ih b/Scheduler/FdEvent.ih index 15d106c..d958436 100644 --- a/Scheduler/FdEvent.ih +++ b/Scheduler/FdEvent.ih @@ -32,10 +32,10 @@ ///////////////////////////////ih.p//////////////////////////////////////// namespace senf { +namespace scheduler { - class Scheduler; + void restart(); -namespace scheduler { namespace detail { struct FdSetCompare { @@ -74,7 +74,7 @@ namespace detail { FdSet fds_; - friend class senf::Scheduler; + friend void senf::scheduler::restart(); friend class singleton; friend class senf::scheduler::FdEvent; }; @@ -111,7 +111,7 @@ namespace detail { FdSet fds_; int managerTimeout_; - friend class senf::Scheduler; + friend void senf::scheduler::restart(); friend class singleton; }; diff --git a/Scheduler/FdEvent.test.cc b/Scheduler/FdEvent.test.cc index 39c0acf..6ca3572 100644 --- a/Scheduler/FdEvent.test.cc +++ b/Scheduler/FdEvent.test.cc @@ -164,7 +164,7 @@ namespace { BOOST_AUTO_UNIT_TEST(fdDispatcher) { - senf::scheduler::FdManager::instance().timeout(1000); + senf::scheduler::detail::FdManager::instance().timeout(1000); int pid (start_server()); BOOST_REQUIRE( pid ); @@ -190,8 +190,8 @@ BOOST_AUTO_UNIT_TEST(fdDispatcher) senf::scheduler::FdEvent sockwrite ("testHandler", boost::bind(&callback, sock, _1), sock, senf::scheduler::FdEvent::EV_WRITE, false); event = 0; - SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() ); - SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FdManager::instance().processOnce() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FIFORunner::instance().run() ); BOOST_CHECK_EQUAL( event, senf::scheduler::FdEvent::EV_READ ); BOOST_CHECK_EQUAL( size, 4 ); buffer[size] = 0; @@ -202,29 +202,29 @@ BOOST_AUTO_UNIT_TEST(fdDispatcher) SENF_CHECK_NO_THROW( sockwrite.enable() ); event = 0; sleep(1); - SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() ); - SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FdManager::instance().processOnce() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FIFORunner::instance().run() ); BOOST_CHECK_EQUAL( event, senf::scheduler::FdEvent::EV_WRITE ); SENF_CHECK_NO_THROW( sockwrite.disable() ); event = 0; sleep(1); - SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() ); - SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FdManager::instance().processOnce() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FIFORunner::instance().run() ); BOOST_CHECK_EQUAL( event, senf::scheduler::FdEvent::EV_HUP | senf::scheduler::FdEvent::EV_READ ); BOOST_CHECK_EQUAL( size, 2 ); buffer[size]=0; BOOST_CHECK_EQUAL( buffer, "OK" ); BOOST_CHECK_EQUAL( calls, 3 ); - SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FIFORunner::instance().run() ); BOOST_CHECK_EQUAL( calls, 3 ); // Ensure, removing an already closed file-descriptor doesn't wreak havoc close(sock); } - SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FIFORunner::instance().run() ); BOOST_CHECK_EQUAL( calls, 3 ); BOOST_CHECK (stop_server(pid)); @@ -254,9 +254,9 @@ BOOST_AUTO_UNIT_TEST(fileDispatcher) try { senf::scheduler::FdEvent fde ("testHandler", &handler, fd, senf::scheduler::FdEvent::EV_READ); - SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FdManager::instance().processOnce() ); SENF_CHECK_NO_THROW( senf::scheduler::detail::FileDispatcher::instance().prepareRun() ); - SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FIFORunner::instance().run() ); BOOST_CHECK( called ); BOOST_CHECK_PREDICATE( is_close, (t)(senf::ClockService::now()) ); @@ -269,9 +269,9 @@ BOOST_AUTO_UNIT_TEST(fileDispatcher) called = false; t = senf::ClockService::now(); - SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FdManager::instance().processOnce() ); SENF_CHECK_NO_THROW( senf::scheduler::detail::FileDispatcher::instance().prepareRun() ); - SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FIFORunner::instance().run() ); BOOST_CHECK( ! called ); BOOST_CHECK_PREDICATE( diff --git a/Scheduler/FdManager.cc b/Scheduler/FdManager.cc index db17838..68cf31f 100644 --- a/Scheduler/FdManager.cc +++ b/Scheduler/FdManager.cc @@ -32,7 +32,7 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ void senf::scheduler::FdManager::processOnce() +prefix_ void senf::scheduler::detail::FdManager::processOnce() { Poller::range events (poller_.wait()); eventTime_ = ClockService::now(); diff --git a/Scheduler/FdManager.cci b/Scheduler/FdManager.cci index 467a97a..7fa9583 100644 --- a/Scheduler/FdManager.cci +++ b/Scheduler/FdManager.cci @@ -33,41 +33,41 @@ /////////////////////////////////////////////////////////////////////////// // senf::scheduler::FdManager -prefix_ senf::scheduler::FdManager::FdManager() +prefix_ senf::scheduler::detail::FdManager::FdManager() : eventTime_ (senf::ClockService::now()) {} -prefix_ bool senf::scheduler::FdManager::set(int fd, int events, Event * entry) +prefix_ bool senf::scheduler::detail::FdManager::set(int fd, int events, Event * entry) { return poller_.set(fd, events, entry); } -prefix_ void senf::scheduler::FdManager::remove(int fd) +prefix_ void senf::scheduler::detail::FdManager::remove(int fd) { poller_.remove(fd); } -prefix_ void senf::scheduler::FdManager::timeout(int t) +prefix_ void senf::scheduler::detail::FdManager::timeout(int t) { poller_.timeout(t); } -prefix_ int senf::scheduler::FdManager::timeout() +prefix_ int senf::scheduler::detail::FdManager::timeout() const { return poller_.timeout(); } -prefix_ senf::ClockService::clock_type senf::scheduler::FdManager::eventTime() +prefix_ senf::ClockService::clock_type senf::scheduler::detail::FdManager::eventTime() const { return eventTime_; } /////////////////////////////////////////////////////////////////////////// -// senf::scheduler::FdManager::Event +// senf::scheduler::detail::FdManager::Event -prefix_ senf::scheduler::FdManager::Event::~Event() +prefix_ senf::scheduler::detail::FdManager::Event::~Event() {} ///////////////////////////////cci.e/////////////////////////////////////// diff --git a/Scheduler/FdManager.hh b/Scheduler/FdManager.hh index 4845233..f432032 100644 --- a/Scheduler/FdManager.hh +++ b/Scheduler/FdManager.hh @@ -35,34 +35,16 @@ ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { - - class Scheduler; - namespace scheduler { - /** \brief Manage file descriptor event processing - - The FdManager is the internal class which manages all events (all events need to somehow be - made accessible via a file descriptor). File descriptors are added or removed from the - FdManager which then allows waiting until an event occurs on one of the descriptors. + void restart(); - Registered events must be derived from FdManager::Event. The FdManager does \e not manage - the event classes, it just manages pointers to externally owned events (the events are owned - by the respective dispatchers). +namespace detail { - When an event is posted, it's \c signal() member is called. However, this call will \e not - execute the user callback registered for the event, it will just mark the relevant tasks as - runnable. - - \implementation - */ class FdManager : public singleton { public: - /////////////////////////////////////////////////////////////////////////// - // Types - ///< Event baseclass struct Event { virtual ~Event(); @@ -74,39 +56,19 @@ namespace scheduler { EV_HUP = Poller::EV_HUP, EV_ERR = Poller::EV_ERR }; - /////////////////////////////////////////////////////////////////////////// - ///\name Structors and default members - ///@{ - using singleton::instance; using singleton::alive; - ///@} - /////////////////////////////////////////////////////////////////////////// - - bool set(int fd, int events, Event * entry); ///< Set file descriptor event mask - /**< This sets the event mask for \a fd to \a events which - is a combination of values from the \c Events enum. If - \a fd is already registered, the registration is - changed to conform to the parameters passed, otherwise - a new registration is added. - \param[in] fd file descriptor - \param[in] events events to register for - \param[in] entry event to signal - \returns \c true, if \a fd supports polling, \c false - otherwise */ - void remove(int fd); ///< Remove \a fd from the manager - + 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. */ - int timeout() const; ///< Get timeout in milliseconds - + 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(). */ - ClockService::clock_type eventTime() const; ///< Time of last event protected: @@ -117,11 +79,11 @@ namespace scheduler { Poller poller_; senf::ClockService::clock_type eventTime_; + friend void senf::scheduler::restart(); friend class singleton; - friend class senf::Scheduler; }; -}} +}}} ///////////////////////////////hh.e//////////////////////////////////////// #include "FdManager.cci" diff --git a/Scheduler/Mainpage.dox b/Scheduler/Mainpage.dox index 40f3f0e..24719ee 100644 --- a/Scheduler/Mainpage.dox +++ b/Scheduler/Mainpage.dox @@ -93,7 +93,7 @@ \li The Dispatcher registeres all callbacks as tasks with the runner (senf::scheduler::FIFORunner). - \li The senf::scheduler::FdManager uses senf::scheduler::Poller to access the low-level epoll() + \li The senf::scheduler::FdManager uses senf::scheduler::detail::Poller to access the low-level epoll() API. All these classes are \e not singletons. They are all instantiatied by the senf::Scheduler diff --git a/Scheduler/Poller.ct b/Scheduler/Poller.ct index 41a4c08..92a13e6 100644 --- a/Scheduler/Poller.ct +++ b/Scheduler/Poller.ct @@ -33,7 +33,7 @@ ///////////////////////////////ct.p//////////////////////////////////////// template -prefix_ bool senf::scheduler::Poller::set(int fd, int events, Value * data) +prefix_ bool senf::scheduler::detail::Poller::set(int fd, int events, Value * data) { struct epoll_event ev = { events, { data } }; if (epoll_ctl(epollFd_, EPOLL_CTL_ADD, fd, &ev) != -1) @@ -47,7 +47,7 @@ prefix_ bool senf::scheduler::Poller::set(int fd, int events, Value * dat } template -prefix_ void senf::scheduler::Poller::remove(int fd) +prefix_ void senf::scheduler::detail::Poller::remove(int fd) { if (epoll_ctl(epollFd_, EPOLL_CTL_DEL, fd, 0) == -1) if (errno != ENOENT && errno != EBADF && errno != EPERM) @@ -61,7 +61,7 @@ prefix_ void senf::scheduler::Poller::remove(int fd) } template -prefix_ typename senf::scheduler::Poller::range senf::scheduler::Poller::wait() +prefix_ typename senf::scheduler::detail::Poller::range senf::scheduler::detail::Poller::wait() { static epoll_event events[NumEvents]; int rv (0); diff --git a/Scheduler/Poller.cti b/Scheduler/Poller.cti index c05fe4a..56e6c42 100644 --- a/Scheduler/Poller.cti +++ b/Scheduler/Poller.cti @@ -32,7 +32,7 @@ ///////////////////////////////cti.p/////////////////////////////////////// template -prefix_ senf::scheduler::Poller::Poller() +prefix_ senf::scheduler::detail::Poller::Poller() : timeout_ (-1) { epollFd_ = epoll_create(NumEvents); @@ -41,27 +41,27 @@ prefix_ senf::scheduler::Poller::Poller() } template -prefix_ senf::scheduler::Poller::~Poller() +prefix_ senf::scheduler::detail::Poller::~Poller() { close(epollFd_); } template -prefix_ void senf::scheduler::Poller::timeout(int t) +prefix_ void senf::scheduler::detail::Poller::timeout(int t) { timeout_ = t; } template -prefix_ int senf::scheduler::Poller::timeout() +prefix_ int senf::scheduler::detail::Poller::timeout() const { return timeout_; } template -prefix_ typename senf::scheduler::Poller::GetPollResult::result_type -senf::scheduler::Poller::GetPollResult::operator()(epoll_event const & ev) +prefix_ typename senf::scheduler::detail::Poller::GetPollResult::result_type +senf::scheduler::detail::Poller::GetPollResult::operator()(epoll_event const & ev) const { diff --git a/Scheduler/Poller.hh b/Scheduler/Poller.hh index 0bedf72..68f96fe 100644 --- a/Scheduler/Poller.hh +++ b/Scheduler/Poller.hh @@ -37,6 +37,7 @@ namespace senf { namespace scheduler { +namespace detail { /** \brief Epoll abstraction @@ -69,8 +70,8 @@ namespace scheduler { enum Events { EV_READ = EPOLLIN, EV_PRIO = EPOLLPRI, EV_WRITE = EPOLLOUT, EV_HUP = EPOLLHUP, EV_ERR = EPOLLERR -}; - + }; + /////////////////////////////////////////////////////////////////////////// ///\name Structors and default members ///@{ @@ -99,7 +100,7 @@ namespace scheduler { }; -}} +}}} ///////////////////////////////hh.e//////////////////////////////////////// //#include "Poller.cci" diff --git a/Scheduler/ReadHelper.ct b/Scheduler/ReadHelper.ct index a3947ea..d5553c9 100644 --- a/Scheduler/ReadHelper.ct +++ b/Scheduler/ReadHelper.ct @@ -67,7 +67,7 @@ template prefix_ void senf::ReadHelper::process(Handle handle,int event) { try { - if (event != senf::Scheduler::EV_READ) + if (event != senf::scheduler::FdEvent::EV_READ) throw SystemException(EPIPE SENF_EXC_DEBUGINFO); std::string rcv; handle.read(rcv, maxSize_ - data_.size()); diff --git a/Scheduler/Scheduler.cc b/Scheduler/Scheduler.cc index 2d13781..1d7b28b 100644 --- a/Scheduler/Scheduler.cc +++ b/Scheduler/Scheduler.cc @@ -40,53 +40,62 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ void senf::Scheduler::process() +namespace { + bool terminate_ (false); +} + +prefix_ void senf::scheduler::terminate() +{ + terminate_ = true; +} + +prefix_ void senf::scheduler::process() { terminate_ = false; - while(! terminate_ && ! (scheduler::detail::FdDispatcher::instance().empty() && - scheduler::detail::TimerDispatcher::instance().empty() && - scheduler::detail::FileDispatcher::instance().empty())) { - scheduler::detail::SignalDispatcher::instance().unblockSignals(); - scheduler::detail::TimerDispatcher::instance().unblockSignals(); - scheduler::FdManager::instance().processOnce(); - scheduler::detail::TimerDispatcher::instance().blockSignals(); - scheduler::detail::SignalDispatcher::instance().blockSignals(); - scheduler::detail::FileDispatcher::instance().prepareRun(); - scheduler::FIFORunner::instance().run(); + while(! terminate_ && ! (detail::FdDispatcher::instance().empty() && + detail::TimerDispatcher::instance().empty() && + detail::FileDispatcher::instance().empty())) { + detail::SignalDispatcher::instance().unblockSignals(); + detail::TimerDispatcher::instance().unblockSignals(); + detail::FdManager::instance().processOnce(); + detail::TimerDispatcher::instance().blockSignals(); + detail::SignalDispatcher::instance().blockSignals(); + detail::FileDispatcher::instance().prepareRun(); + detail::FIFORunner::instance().run(); } } -prefix_ void senf::Scheduler::restart() +prefix_ void senf::scheduler::restart() { - scheduler::FdManager* fdm (&scheduler::FdManager::instance()); - scheduler::FIFORunner* ffr (&scheduler::FIFORunner::instance()); - scheduler::detail::FdDispatcher* fdd (&scheduler::detail::FdDispatcher::instance()); - scheduler::detail::TimerDispatcher* td (&scheduler::detail::TimerDispatcher::instance()); - scheduler::detail::SignalDispatcher* sd (&scheduler::detail::SignalDispatcher::instance()); - scheduler::detail::FileDispatcher* fld (&scheduler::detail::FileDispatcher::instance()); + detail::FdManager* fdm (&detail::FdManager::instance()); + detail::FIFORunner* ffr (&detail::FIFORunner::instance()); + detail::FdDispatcher* fdd (&detail::FdDispatcher::instance()); + detail::TimerDispatcher* tdd (&detail::TimerDispatcher::instance()); + detail::SignalDispatcher* sdd (&detail::SignalDispatcher::instance()); + detail::FileDispatcher* fld (&detail::FileDispatcher::instance()); fld->~FileDispatcher(); - sd->~SignalDispatcher(); - td->~TimerDispatcher(); + sdd->~SignalDispatcher(); + tdd->~TimerDispatcher(); fdd->~FdDispatcher(); ffr->~FIFORunner(); fdm->~FdManager(); - new (fdm) scheduler::FdManager(); - new (ffr) scheduler::FIFORunner(); - new (fdd) scheduler::detail::FdDispatcher(); - new (td) scheduler::detail::TimerDispatcher(); - new (sd) scheduler::detail::SignalDispatcher(); - new (fld) scheduler::detail::FileDispatcher(); + new (fdm) detail::FdManager(); + new (ffr) detail::FIFORunner(); + new (fdd) detail::FdDispatcher(); + new (tdd) detail::TimerDispatcher(); + new (sdd) detail::SignalDispatcher(); + new (fld) detail::FileDispatcher(); } /////////////////////////////////////////////////////////////////////////// -// senf::SchedulerLogTimeSource +// senf::schedulerLogTimeSource -prefix_ senf::log::time_type senf::SchedulerLogTimeSource::operator()() +prefix_ senf::log::time_type senf::scheduler::LogTimeSource::operator()() const { - return Scheduler::instance().eventTime(); + return eventTime(); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Scheduler/Scheduler.cci b/Scheduler/Scheduler.cci index 7fe4f53..1e69ee1 100644 --- a/Scheduler/Scheduler.cci +++ b/Scheduler/Scheduler.cci @@ -34,44 +34,26 @@ // public members -prefix_ senf::Scheduler::Scheduler & senf::Scheduler::instance() +prefix_ senf::ClockService::clock_type senf::scheduler::eventTime() { - static Scheduler instance; - return instance; + return scheduler::detail::FdManager::instance().eventTime(); } -prefix_ void senf::Scheduler::terminate() +prefix_ void senf::scheduler::taskTimeout(unsigned ms) { - terminate_ = true; + scheduler::detail::FIFORunner::instance().taskTimeout(ms); } -prefix_ senf::ClockService::clock_type senf::Scheduler::eventTime() - const +prefix_ unsigned senf::scheduler::taskTimeout() { - return scheduler::FdManager::instance().eventTime(); + return scheduler::detail::FIFORunner::instance().taskTimeout(); } -prefix_ void senf::Scheduler::taskTimeout(unsigned ms) +prefix_ unsigned senf::scheduler::hangCount() { - scheduler::FIFORunner::instance().taskTimeout(ms); + return scheduler::detail::FIFORunner::instance().hangCount(); } -prefix_ unsigned senf::Scheduler::taskTimeout() - const -{ - return scheduler::FIFORunner::instance().taskTimeout(); -} - -prefix_ unsigned senf::Scheduler::hangCount() - const -{ - return scheduler::FIFORunner::instance().hangCount(); -} - -prefix_ senf::Scheduler::Scheduler() - : terminate_ (false) -{} - ///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ diff --git a/Scheduler/Scheduler.hh b/Scheduler/Scheduler.hh index 7f66821..a5abfad 100644 --- a/Scheduler/Scheduler.hh +++ b/Scheduler/Scheduler.hh @@ -32,227 +32,177 @@ #include "FdEvent.hh" #include "TimerEvent.hh" #include "SignalEvent.hh" -#include "../Utils/Logger/SenfLog.hh" //#include "scheduler.mpp" ///////////////////////////////hh.p//////////////////////////////////////// -/** \brief SENF Project namespace */ namespace senf { - /** \brief Visible scheduler interface - - The %scheduler singleton manages access to the %scheduler library. It provides access to - several event dispatchers: - \li File descriptor notifications - \li Timeouts - \li UNIX Signals - - The %scheduler is entered by calling it's process() member. This call will continue to run as - long as there is something to do, or until one of the handlers calls terminate(). The - %scheduler has 'something to do' as long as there is any file descriptor or timeout active. - - The %scheduler only provides low level primitive scheduling capability. Additional helpers - are defined on top of this functionality (e.g. ReadHelper or WriteHelper or the interval - timers of the PPI). +/** \brief Visible scheduler interface + + The %scheduler singleton manages access to the %scheduler library. It provides access to + several event dispatchers: + \li File descriptor notifications + \li Timeouts + \li UNIX Signals + + The %scheduler is entered by calling it's process() member. This call will continue to run as + long as there is something to do, or until one of the handlers calls terminate(). The + %scheduler has 'something to do' as long as there is any file descriptor or timeout active. + + The %scheduler only provides low level primitive scheduling capability. Additional helpers + are defined on top of this functionality (e.g. ReadHelper or WriteHelper or the interval + timers of the PPI). + + + \section sched_handlers Specifying handlers + + All handlers are passed as generic Boost.Function objects. This allows + to pass any callable as a handler. Depending on the type of handler, some additional + arguments may be passed to the handler by the %scheduler. + + If you need to pass additional information to your handler, use Boost.Bind: + \code + // Handle callback function + void callback(UDPv4ClientSocketHandle handle, senf::Scheduler::EventId event) {..} + // Pass 'handle' as additional first argument to callback() + Scheduler::instance().add(handle, boost::bind(&callback, handle, _1), EV_READ) + // Timeout function + void timeout( int n) {..} + // Call timeout() handler with argument 'n' + Scheduler::instance().timeout(boost::bind(&timeout, n)) + \endcode + + To use member-functions as callbacks, use either Boost.Bind or senf::membind() + \code + // e.g. in Foo::Foo() constructor: + Scheduler::instance().add(handle_, senf::membind(&Foo::callback, this)), EV_READ) + \endcode + + The handler can also be identified by an arbitrary, user specified name. This name is used + in error messages to identify the failing handler. + + + \section sched_fd Registering file descriptors + + File descriptors are managed using add() or remove() + \code + Scheduler::instance().add(handle, &callback, EV_ALL); + Scheduler::instance().remove(handle); + \endcode + + The callback will be called with one additional argument. This argument is the event mask of + type EventId. This mask will tell, which of the registered events are signaled. The + additional flags EV_HUP or EV_ERR (on hangup or error condition) may be set additionally. + + Only a single handler may be registered for any combination of file descriptor and event + (registering multiple callbacks for a single fd and event does not make sense). + + The %scheduler will accept any object as \a handle argument as long as retrieve_filehandle() + may be called on that object + \code + int fd = retrieve_filehandle(handle); + \endcode + to fetch the file handle given some abstract handle type. retrieve_filehandle() will be + found using ADL depending on the argument namespace. A default implementation is provided + for \c int arguments (file descriptors) + + + \section sched_timers Registering timers + + The %scheduler has very simple timer support. There is only one type of timer: A single-shot + deadline timer. More complex timers are built based on this. Timers are managed using + timeout() and cancelTimeout() + \code + int id = Scheduler::instance().timeout(Scheduler::instance().eventTime() + ClockService::milliseconds(100), + &callback); + Scheduler::instance().cancelTimeout(id); + \endcode + Timing is based on the ClockService, which provides a high resolution and strictly + monotonous time source which again is based on POSIX timers. Registering a timeout will fire + the callback when the target time is reached. The timer may be canceled by passing the + returned \a id to cancelTimeout(). + + + \section sched_signals Registering POSIX/UNIX signals + + The %scheduler also incorporates standard POSIX/UNIX signals. Signals registered with the + %scheduler will be handled \e synchronously within the event loop. + \code + Scheduler::instance().registerSignal(SIGUSR1, &callback); + Scheduler::instance().unregisterSignal(SIGUSR1); + \endcode + When registering a signal with the %scheduler, that signal will automatically be blocked so + it can be handled within the %scheduler. + + A registered signal does \e not count as 'something to do'. It is therefore not possible to + wait for signals \e only. + + \todo Change the Scheduler API to use RAII. Additionally, this will remove all dynamic + memory allocations from the scheduler. + \todo Fix the file support to use threads (?) fork (?) and a pipe so it works reliably even + over e.g. NFS. + */ +namespace scheduler { + + /** \brief Event handler main loop + + This member must be called at some time to enter the event handler main loop. Only while + this function is running any events are handled. The call will return if + \li a callback calls terminate() + \li the run queue becomes empty. + */ + void process(); + /** \brief Called by callbacks to terminate the main loop - \section sched_handlers Specifying handlers + This member may be called by any callback to tell the main loop to terminate. The main loop + will return to it's caller after the currently running callback returns. + */ + void terminate(); - All handlers are passed as generic Boost.Function objects. This allows - to pass any callable as a handler. Depending on the type of handler, some additional - arguments may be passed to the handler by the %scheduler. + /** \brief Return date/time of last event - If you need to pass additional information to your handler, use Boost.Bind: - \code - // Handle callback function - void callback(UDPv4ClientSocketHandle handle, senf::Scheduler::EventId event) {..} - // Pass 'handle' as additional first argument to callback() - Scheduler::instance().add(handle, boost::bind(&callback, handle, _1), EV_READ) - // Timeout function - void timeout( int n) {..} - // Call timeout() handler with argument 'n' - Scheduler::instance().timeout(boost::bind(&timeout, n)) - \endcode + This is the timestamp, the last event has been signaled. This is the real time at which the + event is delivered \e not the time it should have been delivered (in the case of timers). + */ + ClockService::clock_type eventTime(); - To use member-functions as callbacks, use either Boost.Bind or senf::membind() - \code - // e.g. in Foo::Foo() constructor: - Scheduler::instance().add(handle_, senf::membind(&Foo::callback, this)), EV_READ) - \endcode + /** \brief Set task watchdog timeout */ + void taskTimeout(unsigned ms); - The handler can also be identified by an arbitrary, user specified name. This name is used - in error messages to identify the failing handler. + /** \brief Current task watchdog timeout */ + unsigned taskTimeout(); + /** \brief Number of watchdog events */ + unsigned hangCount(); - \section sched_fd Registering file descriptors - - File descriptors are managed using add() or remove() - \code - Scheduler::instance().add(handle, &callback, EV_ALL); - Scheduler::instance().remove(handle); - \endcode - - The callback will be called with one additional argument. This argument is the event mask of - type EventId. This mask will tell, which of the registered events are signaled. The - additional flags EV_HUP or EV_ERR (on hangup or error condition) may be set additionally. - - Only a single handler may be registered for any combination of file descriptor and event - (registering multiple callbacks for a single fd and event does not make sense). - - The %scheduler will accept any object as \a handle argument as long as retrieve_filehandle() - may be called on that object - \code - int fd = retrieve_filehandle(handle); - \endcode - to fetch the file handle given some abstract handle type. retrieve_filehandle() will be - found using ADL depending on the argument namespace. A default implementation is provided - for \c int arguments (file descriptors) - - - \section sched_timers Registering timers - - The %scheduler has very simple timer support. There is only one type of timer: A single-shot - deadline timer. More complex timers are built based on this. Timers are managed using - timeout() and cancelTimeout() - \code - int id = Scheduler::instance().timeout(Scheduler::instance().eventTime() + ClockService::milliseconds(100), - &callback); - Scheduler::instance().cancelTimeout(id); - \endcode - Timing is based on the ClockService, which provides a high resolution and strictly - monotonous time source which again is based on POSIX timers. Registering a timeout will fire - the callback when the target time is reached. The timer may be canceled by passing the - returned \a id to cancelTimeout(). - - - \section sched_signals Registering POSIX/UNIX signals - - The %scheduler also incorporates standard POSIX/UNIX signals. Signals registered with the - %scheduler will be handled \e synchronously within the event loop. - \code - Scheduler::instance().registerSignal(SIGUSR1, &callback); - Scheduler::instance().unregisterSignal(SIGUSR1); - \endcode - When registering a signal with the %scheduler, that signal will automatically be blocked so - it can be handled within the %scheduler. - - A registered signal does \e not count as 'something to do'. It is therefore not possible to - wait for signals \e only. - - \todo Change the Scheduler API to use RAII. Additionally, this will remove all dynamic - memory allocations from the scheduler. - \todo Fix the file support to use threads (?) fork (?) and a pipe so it works reliably even - over e.g. NFS. - */ - class Scheduler - : boost::noncopyable - { - public: - - SENF_LOG_CLASS_AREA(); - - /////////////////////////////////////////////////////////////////////////// - // Types - - /** \brief Types of file descriptor events - - These events are grouped into to classes: - \li Ordinary file descriptor events for which handlers may be registered. These are - EV_READ, EV_PRIO and EV_WRITE. EV_ALL is a combination of these three. - \li Error flags. These additional flags may be passed to a handler to pass an error - condition to the handler. - */ - enum EventId { - EV_NONE = 0 /**< No event */ - , EV_READ = scheduler::FdManager::EV_READ /**< File descriptor is readable */ - , EV_PRIO = scheduler::FdManager::EV_PRIO /**< File descriptor has OOB data */ - , EV_WRITE = scheduler::FdManager::EV_WRITE /**< File descriptor is writable */ - , EV_ALL = scheduler::FdManager::EV_READ - | scheduler::FdManager::EV_PRIO - | scheduler::FdManager::EV_WRITE /**< Used to register all events at once - (read/prio/write) */ - , EV_HUP = scheduler::FdManager::EV_HUP /**< Hangup condition on file handle */ - , EV_ERR = scheduler::FdManager::EV_ERR /**< Error condition on file handle */ - }; - - /** \brief Callback type for file descriptor events */ - typedef boost::function FdCallback; - - /** \brief Callback type for timer events */ - typedef boost::function SimpleCallback; - - /** \brief Callback type for signal events */ - typedef boost::function SignalCallback; - - /////////////////////////////////////////////////////////////////////////// - ///\name Structors and default members - ///@{ - - // private default constructor - // no copy constructor - // no copy assignment - // default destructor - // no conversion constructors - - /** \brief Return %scheduler instance - - This static member is used to access the singleton instance. This member is save to - return a correctly initialized %scheduler instance even if called at global construction - time - */ - static Scheduler & instance(); - - ///@} - /////////////////////////////////////////////////////////////////////////// - - void process(); ///< Event handler main loop - /**< This member must be called at some time to enter the - event handler main loop. Only while this function is - running any events are handled. The call will return - only, if any callback calls terminate(). */ - - void terminate(); ///< Called by callbacks to terminate the main loop - /**< This member may be called by any callback to tell the - main loop to terminate. The main loop will return to - it's caller after the currently running callback - returns. */ + /** \brief Restart scheduler - ClockService::clock_type eventTime() const; ///< Return date/time of last event - /**< This is the timestamp, the last event has been - signaled. This is the real time at which the event is - delivered \e not the time it should have been delivered - (in the case of timers). */ - - void taskTimeout(unsigned ms); - unsigned taskTimeout() const; - unsigned hangCount() const; - - void restart(); - - protected: - - private: - Scheduler(); - - bool terminate_; - }; + This call will restart all scheduler dispatchers (timers, signals, file descriptors). This + is necessary after a fork(). + \warning This call will \e remove all registered events from the scheduler + */ + void restart(); /** \brief %scheduler specific time source for Utils/Logger framework This time source may be used to provide timing information for log messages within the Utils/Logger framework. This time source will use Scheduler::eventTime() to provide timing information. + + Using this information reduces the number of necessary ClockService::now() calls and thus + the number of system calls. */ - struct SchedulerLogTimeSource : public senf::log::TimeSource + struct LogTimeSource : public senf::log::TimeSource { senf::log::time_type operator()() const; }; -} +}} ///////////////////////////////hh.e//////////////////////////////////////// #include "Scheduler.cci" diff --git a/Scheduler/Scheduler.test.cc b/Scheduler/Scheduler.test.cc index 95ff5bd..e270b06 100644 --- a/Scheduler/Scheduler.test.cc +++ b/Scheduler/Scheduler.test.cc @@ -145,27 +145,25 @@ namespace { void callback(int fd, int ev) { event = ev; - switch (event & Scheduler::EV_ALL) { - case Scheduler::EV_READ: + switch (event & senf::scheduler::FdEvent::EV_ALL) { + case senf::scheduler::FdEvent::EV_READ: size = recv(fd,buffer,1024,0); break; - case Scheduler::EV_PRIO: + case senf::scheduler::FdEvent::EV_PRIO: size = recv(fd,buffer,1024,MSG_OOB); - Scheduler::instance().terminate(); break; - case Scheduler::EV_WRITE: + case senf::scheduler::FdEvent::EV_WRITE: size = write(fd,buffer,size); - Scheduler::instance().terminate(); break; } - Scheduler::instance().terminate(); + senf::scheduler::terminate(); } bool timeoutCalled = false; void timeout() { timeoutCalled = true; - Scheduler::instance().terminate(); + senf::scheduler::terminate(); } struct HandleWrapper @@ -197,7 +195,7 @@ namespace { void sigusr(siginfo_t const &) { sigtime = ClockService::now(); - Scheduler::instance().terminate(); + senf::scheduler::terminate(); } void delay(unsigned long milliseconds) @@ -211,7 +209,7 @@ namespace { void blockingHandler() { delay(2200); - Scheduler::instance().terminate(); + senf::scheduler::terminate(); } } @@ -238,14 +236,12 @@ BOOST_AUTO_UNIT_TEST(testScheduler) /////////////////////////////////////////////////////////////////////////// - BOOST_CHECK_NO_THROW( Scheduler::instance() ); - { senf::scheduler::FdEvent fde1 ("testFdEvent", boost::bind(&callback, sock, _1), sock, senf::scheduler::FdEvent::EV_READ); - event = Scheduler::EV_NONE; - BOOST_CHECK_NO_THROW( Scheduler::instance().process() ); - BOOST_CHECK_EQUAL( event, Scheduler::EV_READ ); + event = senf::scheduler::FdEvent::EV_NONE; + BOOST_CHECK_NO_THROW( senf::scheduler::process() ); + BOOST_CHECK_EQUAL( event, senf::scheduler::FdEvent::EV_READ ); BOOST_REQUIRE_EQUAL( size, 4 ); buffer[size]=0; BOOST_CHECK_EQUAL( buffer, "READ" ); @@ -255,15 +251,15 @@ BOOST_AUTO_UNIT_TEST(testScheduler) handle, senf::scheduler::FdEvent::EV_WRITE); strcpy(buffer,"WRITE"); size=5; - event = Scheduler::EV_NONE; - BOOST_CHECK_NO_THROW( Scheduler::instance().process() ); - BOOST_CHECK_EQUAL( event, Scheduler::EV_WRITE ); + event = senf::scheduler::FdEvent::EV_NONE; + BOOST_CHECK_NO_THROW( senf::scheduler::process() ); + BOOST_CHECK_EQUAL( event, senf::scheduler::FdEvent::EV_WRITE ); SENF_CHECK_NO_THROW( fde2.disable() ); - event = Scheduler::EV_NONE; + event = senf::scheduler::FdEvent::EV_NONE; sleep(1); - BOOST_CHECK_NO_THROW( Scheduler::instance().process() ); - BOOST_CHECK_EQUAL( event, Scheduler::EventId(Scheduler::EV_READ|Scheduler::EV_HUP) ); + BOOST_CHECK_NO_THROW( senf::scheduler::process() ); + BOOST_CHECK_EQUAL( event, senf::scheduler::FdEvent::EV_READ|senf::scheduler::FdEvent::EV_HUP ); BOOST_REQUIRE_EQUAL( size, 2 ); buffer[size]=0; BOOST_CHECK_EQUAL( buffer, "OK" ); @@ -275,26 +271,26 @@ BOOST_AUTO_UNIT_TEST(testScheduler) senf::scheduler::TimerEvent timer2 ("testTimer2", &timeout, ClockService::now()+ClockService::milliseconds(400)); - event = Scheduler::EV_NONE; + event = senf::scheduler::FdEvent::EV_NONE; ClockService::clock_type t (ClockService::now()); - BOOST_CHECK_NO_THROW( Scheduler::instance().process() ); + BOOST_CHECK_NO_THROW( senf::scheduler::process() ); BOOST_CHECK_PREDICATE( is_close, (ClockService::now()-t) (ClockService::milliseconds(200)) ); BOOST_CHECK( timeoutCalled ); BOOST_CHECK( ! timer1.enabled() ); - BOOST_CHECK_EQUAL( event, Scheduler::EV_NONE ); - BOOST_CHECK_PREDICATE( is_close, (ClockService::now()) (Scheduler::instance().eventTime()) ); + BOOST_CHECK_EQUAL( event, senf::scheduler::FdEvent::EV_NONE ); + BOOST_CHECK_PREDICATE( is_close, (ClockService::now()) (senf::scheduler::eventTime()) ); timeoutCalled = false; - BOOST_CHECK_NO_THROW( Scheduler::instance().process() ); + BOOST_CHECK_NO_THROW( senf::scheduler::process() ); BOOST_CHECK_PREDICATE( is_close, (ClockService::now()-t) (ClockService::milliseconds(400)) ); BOOST_CHECK( timeoutCalled ); - BOOST_CHECK_EQUAL( event, Scheduler::EV_NONE ); + BOOST_CHECK_EQUAL( event, senf::scheduler::FdEvent::EV_NONE ); BOOST_CHECK( ! timer2.enabled() ); BOOST_WARN_MESSAGE( false, "A 'Scheduler task hanging' error is expected to be signaled here." ); BOOST_CHECK_NO_THROW( timer1.action(&blockingHandler) ); BOOST_CHECK_NO_THROW( timer1.timeout(ClockService::now()) ); - BOOST_CHECK_NO_THROW( Scheduler::instance().process() ); - BOOST_CHECK_EQUAL( Scheduler::instance().hangCount(), 1u ); + BOOST_CHECK_NO_THROW( senf::scheduler::process() ); + BOOST_CHECK_EQUAL( senf::scheduler::hangCount(), 1u ); } { @@ -305,10 +301,10 @@ BOOST_AUTO_UNIT_TEST(testScheduler) ClockService::clock_type t = ClockService::now(); ::kill(::getpid(), SIGUSR1); delay(100); - BOOST_CHECK_NO_THROW( Scheduler::instance().process() ); + BOOST_CHECK_NO_THROW( senf::scheduler::process() ); BOOST_CHECK_PREDICATE( is_close, (ClockService::now()) (t+ClockService::milliseconds(200)) ); BOOST_CHECK_PREDICATE( is_close, (sigtime) (t+ClockService::milliseconds(200)) ); - BOOST_CHECK_NO_THROW( Scheduler::instance().process() ); + BOOST_CHECK_NO_THROW( senf::scheduler::process() ); } /////////////////////////////////////////////////////////////////////////// diff --git a/Scheduler/SignalEvent.cc b/Scheduler/SignalEvent.cc index 46ebd22..32c5461 100644 --- a/Scheduler/SignalEvent.cc +++ b/Scheduler/SignalEvent.cc @@ -40,17 +40,17 @@ prefix_ senf::scheduler::detail::SignalDispatcher::SignalDispatcher() if (pipe(sigPipe_) <0) SENF_THROW_SYSTEM_EXCEPTION("pipe()"); sigemptyset(&sigSet_); - FdManager::instance().set(sigPipe_[0], FdManager::EV_READ, this); + detail::FdManager::instance().set(sigPipe_[0], detail::FdManager::EV_READ, this); } prefix_ senf::scheduler::detail::SignalDispatcher::~SignalDispatcher() { for (SignalSet::iterator i (handlers_.begin()); i != handlers_.end(); ++i) { ::signal(i->signal_, SIG_DFL); - FIFORunner::instance().dequeue(&(*i)); + detail::FIFORunner::instance().dequeue(&(*i)); } sigprocmask(SIG_UNBLOCK, &sigSet_, 0); - FdManager::instance().remove(sigPipe_[0]); + detail::FdManager::instance().remove(sigPipe_[0]); close(sigPipe_[0]); close(sigPipe_[1]); } @@ -64,7 +64,7 @@ prefix_ void senf::scheduler::detail::SignalDispatcher::add(SignalEvent & event) handlers_.insert(event); sigaddset(&sigSet_, event.signal_); - FIFORunner::instance().enqueue(&event); + detail::FIFORunner::instance().enqueue(&event); sigset_t sig; sigemptyset(&sig); @@ -89,7 +89,7 @@ prefix_ void senf::scheduler::detail::SignalDispatcher::add(SignalEvent & event) prefix_ void senf::scheduler::detail::SignalDispatcher::remove(SignalEvent & event) { ::signal(event.signal_, SIG_DFL); - FIFORunner::instance().dequeue(&event); + detail::FIFORunner::instance().dequeue(&event); handlers_.erase(event); sigset_t sig; sigemptyset(&sig); diff --git a/Scheduler/SignalEvent.cci b/Scheduler/SignalEvent.cci index df29dd7..71b224c 100644 --- a/Scheduler/SignalEvent.cci +++ b/Scheduler/SignalEvent.cci @@ -58,7 +58,7 @@ prefix_ bool senf::scheduler::detail::SignalDispatcher::empty() prefix_ senf::scheduler::SignalEvent::SignalEvent(int signal, Callback const & cb, bool initiallyEnabled) - : FIFORunner::TaskInfo(signalName(signal)), signal_ (signal), cb_ (cb) + : detail::FIFORunner::TaskInfo(signalName(signal)), signal_ (signal), cb_ (cb) { if (initiallyEnabled) enable(); diff --git a/Scheduler/SignalEvent.hh b/Scheduler/SignalEvent.hh index e5f2add..bd6540d 100644 --- a/Scheduler/SignalEvent.hh +++ b/Scheduler/SignalEvent.hh @@ -60,7 +60,7 @@ namespace scheduler { callback is a member function it should be defined as a class member). */ class SignalEvent - : public FIFORunner::TaskInfo, + : public detail::FIFORunner::TaskInfo, public detail::SignalSetBase { public: @@ -104,7 +104,6 @@ namespace scheduler { friend class detail::SignalSetCompare; friend class detail::FindNumericSignal; friend class detail::SignalDispatcher; - friend class senf::Scheduler; }; diff --git a/Scheduler/SignalEvent.ih b/Scheduler/SignalEvent.ih index 7e96134..96f01cf 100644 --- a/Scheduler/SignalEvent.ih +++ b/Scheduler/SignalEvent.ih @@ -35,10 +35,10 @@ ///////////////////////////////ih.p//////////////////////////////////////// namespace senf { - - class Scheduler; - namespace scheduler { + + void restart(); + namespace detail { struct SignalSetCompare { @@ -54,7 +54,7 @@ namespace detail { }; class SignalDispatcher - : public FdManager::Event, + : public detail::FdManager::Event, public singleton { typedef boost::intrusive::iset< SignalSetBase::value_traits, @@ -92,9 +92,9 @@ namespace detail { bool blocked_; sigset_t sigSet_; + friend void senf::scheduler::restart(); friend class senf::scheduler::SignalEvent; friend class singleton; - friend class senf::Scheduler; }; }}} diff --git a/Scheduler/SignalEvent.test.cc b/Scheduler/SignalEvent.test.cc index d579acb..62376a1 100644 --- a/Scheduler/SignalEvent.test.cc +++ b/Scheduler/SignalEvent.test.cc @@ -47,7 +47,7 @@ namespace { BOOST_AUTO_UNIT_TEST(signalDispatcher) { - senf::scheduler::FdManager::instance().timeout(1000); + senf::scheduler::detail::FdManager::instance().timeout(1000); senf::scheduler::SignalEvent sig (SIGUSR1, &handler); SENF_CHECK_NO_THROW( sig.disable() ); @@ -58,9 +58,9 @@ BOOST_AUTO_UNIT_TEST(signalDispatcher) ::kill(::getpid(), SIGUSR1); sleep(1); SENF_CHECK_NO_THROW( senf::scheduler::detail::SignalDispatcher::instance().unblockSignals() ); - SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FdManager::instance().processOnce() ); SENF_CHECK_NO_THROW( senf::scheduler::detail::SignalDispatcher::instance().blockSignals() ); - SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FIFORunner::instance().run() ); BOOST_CHECK( called ); } diff --git a/Scheduler/TimerEvent.cc b/Scheduler/TimerEvent.cc index 7c3278b..6e75a3d 100644 --- a/Scheduler/TimerEvent.cc +++ b/Scheduler/TimerEvent.cc @@ -37,7 +37,7 @@ prefix_ senf::scheduler::detail::TimerDispatcher::TimerDispatcher() { if (pipe(timerPipe_) < 0) SENF_THROW_SYSTEM_EXCEPTION("pipe()"); - senf::scheduler::FdManager::instance().set(timerPipe_[0], FdManager::EV_READ, this); + senf::scheduler::detail::FdManager::instance().set(timerPipe_[0], detail::FdManager::EV_READ, this); sigemptyset(&sigSet_); sigaddset(&sigSet_, SIGALRM); @@ -64,12 +64,12 @@ prefix_ senf::scheduler::detail::TimerDispatcher::~TimerDispatcher() TimerSet::iterator i (timers_.begin()); TimerSet::iterator const i_end (timers_.end()); for (; i != i_end; ++i) - senf::scheduler::FIFORunner::instance().dequeue(&(*i)); + senf::scheduler::detail::FIFORunner::instance().dequeue(&(*i)); timer_delete(timerId_); ::signal(SIGALRM, SIG_IGN); sigprocmask(SIG_UNBLOCK, &sigSet_, 0); - senf::scheduler::FdManager::instance().remove(timerPipe_[0]); + senf::scheduler::detail::FdManager::instance().remove(timerPipe_[0]); close(timerPipe_[0]); close(timerPipe_[1]); } @@ -77,7 +77,7 @@ prefix_ senf::scheduler::detail::TimerDispatcher::~TimerDispatcher() void senf::scheduler::detail::TimerDispatcher::add(TimerEvent & event) { TimerSet::iterator i (timers_.insert(event)); - senf::scheduler::FIFORunner::instance().enqueue(&(*i)); + senf::scheduler::detail::FIFORunner::instance().enqueue(&(*i)); if (! blocked_) reschedule(); } @@ -87,7 +87,7 @@ prefix_ void senf::scheduler::detail::TimerDispatcher::remove(TimerEvent & event TimerSet::iterator i (TimerSet::current(event)); if (i == timers_.end()) return; - senf::scheduler::FIFORunner::instance().dequeue(&(*i)); + senf::scheduler::detail::FIFORunner::instance().dequeue(&(*i)); timers_.erase(i); if (! blocked_) reschedule(); @@ -117,7 +117,7 @@ prefix_ void senf::scheduler::detail::TimerDispatcher::signal(int events) return; TimerSet::iterator i (timers_.begin()); TimerSet::iterator const i_end (timers_.end()); - ClockService::clock_type now (senf::scheduler::FdManager::instance().eventTime()); + ClockService::clock_type now (senf::scheduler::detail::FdManager::instance().eventTime()); for (; i != i_end && i->timeout_ <= now ; ++i) i->setRunnable(); } diff --git a/Scheduler/TimerEvent.cci b/Scheduler/TimerEvent.cci index 0dffcd9..372565d 100644 --- a/Scheduler/TimerEvent.cci +++ b/Scheduler/TimerEvent.cci @@ -37,14 +37,14 @@ prefix_ senf::scheduler::TimerEvent::TimerEvent(std::string const & name, Callback const & cb, ClockService::clock_type timeout, bool initiallyEnabled) - : FIFORunner::TaskInfo (name), cb_ (cb), timeout_ (timeout) + : detail::FIFORunner::TaskInfo (name), cb_ (cb), timeout_ (timeout) { if (initiallyEnabled) enable(); } prefix_ senf::scheduler::TimerEvent::TimerEvent(std::string const & name, Callback const & cb) - : FIFORunner::TaskInfo (name), cb_ (cb), timeout_ (0) + : detail::FIFORunner::TaskInfo (name), cb_ (cb), timeout_ (0) {} prefix_ senf::scheduler::TimerEvent::~TimerEvent() diff --git a/Scheduler/TimerEvent.hh b/Scheduler/TimerEvent.hh index cbbb230..b228890 100644 --- a/Scheduler/TimerEvent.hh +++ b/Scheduler/TimerEvent.hh @@ -66,7 +66,7 @@ namespace scheduler { callback is a member function it should be defined as a class member). */ class TimerEvent - : public FIFORunner::TaskInfo, + : public detail::FIFORunner::TaskInfo, public detail::TimerSetBase { public: diff --git a/Scheduler/TimerEvent.ih b/Scheduler/TimerEvent.ih index 7062de2..5cda3c0 100644 --- a/Scheduler/TimerEvent.ih +++ b/Scheduler/TimerEvent.ih @@ -32,10 +32,10 @@ ///////////////////////////////ih.p//////////////////////////////////////// namespace senf { +namespace scheduler { - class Scheduler; + void restart(); -namespace scheduler { namespace detail { struct TimerSetCompare { @@ -44,7 +44,7 @@ namespace detail { }; class TimerDispatcher - : public FdManager::Event, + : public detail::FdManager::Event, public singleton { SENF_LOG_CLASS_AREA(); @@ -82,7 +82,7 @@ namespace detail { bool blocked_; timer_t timerId_; - friend class senf::Scheduler; + friend void senf::scheduler::restart(); friend class singleton; }; diff --git a/Scheduler/TimerEvent.test.cc b/Scheduler/TimerEvent.test.cc index e7f777e..b626944 100644 --- a/Scheduler/TimerEvent.test.cc +++ b/Scheduler/TimerEvent.test.cc @@ -52,7 +52,7 @@ namespace { BOOST_AUTO_UNIT_TEST(timerDispatcher) { - senf::scheduler::FdManager::instance().timeout(1000); + senf::scheduler::detail::FdManager::instance().timeout(1000); senf::ClockService::clock_type t (senf::ClockService::now()); { @@ -62,9 +62,9 @@ BOOST_AUTO_UNIT_TEST(timerDispatcher) SENF_CHECK_NO_THROW( timer.enable() ); BOOST_CHECK( timer.enabled() ); SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().unblockSignals() ); - SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FdManager::instance().processOnce() ); SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().blockSignals() ); - SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FIFORunner::instance().run() ); senf::ClockService::clock_type t2 (senf::ClockService::now()); BOOST_CHECK( called ); BOOST_CHECK( ! timer.enabled() ); @@ -75,9 +75,9 @@ BOOST_AUTO_UNIT_TEST(timerDispatcher) SENF_CHECK_NO_THROW( timer.timeout(t) ); BOOST_CHECK( timer.enabled() ); SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().unblockSignals() ); - SENF_CHECK_NO_THROW( senf::scheduler::FdManager::instance().processOnce() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FdManager::instance().processOnce() ); SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().blockSignals() ); - SENF_CHECK_NO_THROW( senf::scheduler::FIFORunner::instance().run() ); + SENF_CHECK_NO_THROW( senf::scheduler::detail::FIFORunner::instance().run() ); BOOST_CHECK_PREDICATE( is_close, (t) (senf::ClockService::now()) ); BOOST_CHECK( called ); } diff --git a/Scheduler/WriteHelper.ct b/Scheduler/WriteHelper.ct index 16f386b..3d688ef 100644 --- a/Scheduler/WriteHelper.ct +++ b/Scheduler/WriteHelper.ct @@ -61,9 +61,8 @@ prefix_ void senf::WriteHelper::revoke() } template -prefix_ void -senf::WriteHelper::dispatchProcess(ptr helper, Handle handle, - senf::Scheduler::EventId event) +prefix_ void senf::WriteHelper::dispatchProcess(ptr helper, Handle handle, + senf::scheduler::FdEvent::Events event) { // since we have a 'ptr' argument, the instance cannot be deleted // before this method returns @@ -72,11 +71,11 @@ senf::WriteHelper::dispatchProcess(ptr helper, Handle handle, template prefix_ void senf::WriteHelper::process(Handle handle, - senf::Scheduler::EventId event) + senf::scheduler::FdEvent::Events event) { bool complete_ (false); try { - if (event != senf::Scheduler::EV_WRITE) + if (event != senf::scheduler::FdEvent::EV_WRITE) throw SystemException(EPIPE SENF_EXC_DEBUGINFO); offset_ = handle.write(std::make_pair(offset_,data_.end())); if (offset_ == data_.end()) { diff --git a/Scheduler/WriteHelper.hh b/Scheduler/WriteHelper.hh index c48aed5..2280975 100644 --- a/Scheduler/WriteHelper.hh +++ b/Scheduler/WriteHelper.hh @@ -97,8 +97,9 @@ namespace senf { private: WriteHelper(Handle handle, std::string const & data, Callback callback); - static void dispatchProcess(ptr helper, Handle handle, senf::Scheduler::EventId event); - void process(Handle handle, senf::Scheduler::EventId event); + static void dispatchProcess(ptr helper, Handle handle, + senf::scheduler::FdEvent::Events event); + void process(Handle handle, senf::scheduler::FdEvent::Events event); void done(); Handle handle_; diff --git a/Socket/FileHandle.hh b/Socket/FileHandle.hh index f578635..bbbeab1 100644 --- a/Socket/FileHandle.hh +++ b/Socket/FileHandle.hh @@ -195,7 +195,7 @@ namespace senf { friend class FileBody; }; - /** \brief Adapt FileHandle to senf::Scheduler + /** \brief Adapt FileHandle to senf::scheduler \related senf::FileHandle \internal diff --git a/Utils/Daemon/Daemon.cc b/Utils/Daemon/Daemon.cc index b04eef7..2b09cc0 100644 --- a/Utils/Daemon/Daemon.cc +++ b/Utils/Daemon/Daemon.cc @@ -378,7 +378,7 @@ prefix_ void senf::Daemon::fork() LIBC_CALL( ::setsid, () ); LIBC_CALL( ::sigprocmask, (SIG_SETMASK, &oldsig, 0) ); - senf::Scheduler::instance().restart(); + senf::scheduler::restart(); return; } @@ -388,7 +388,7 @@ prefix_ void senf::Daemon::fork() LIBC_CALL( ::close, (coutpipe[1]) ); LIBC_CALL( ::close, (cerrpipe[1]) ); - senf::Scheduler::instance().restart(); + senf::scheduler::restart(); detail::DaemonWatcher watcher (pid, coutpipe[0], cerrpipe[0], stdout_, stderr_); watcher.run(); @@ -577,7 +577,7 @@ prefix_ senf::detail::DaemonWatcher::DaemonWatcher(int pid, int coutpipe, int ce prefix_ void senf::detail::DaemonWatcher::run() { - Scheduler::instance().process(); + scheduler::process(); } //////////////////////////////////////// @@ -595,7 +595,7 @@ prefix_ void senf::detail::DaemonWatcher::pipeClosed(int id) childDied(); // does not return if (::kill(childPid_, SIGUSR1) < 0 && errno != ESRCH) SENF_THROW_SYSTEM_EXCEPTION("::kill()"); - timer_.timeout(Scheduler::instance().eventTime() + ClockService::seconds(1)); + timer_.timeout(scheduler::eventTime() + ClockService::seconds(1)); } } @@ -623,7 +623,7 @@ prefix_ void senf::detail::DaemonWatcher::childDied() prefix_ void senf::detail::DaemonWatcher::childOk() { - Scheduler::instance().terminate(); + scheduler::terminate(); } /////////////////////////////////////////////////////////////////////////// @@ -680,7 +680,7 @@ prefix_ void senf::detail::DaemonWatcher::Forwarder::readData(int event) prefix_ void senf::detail::DaemonWatcher::Forwarder::writeData(int event, Target * target) { - if (event != Scheduler::EV_WRITE) { + if (event != scheduler::FdEvent::EV_WRITE) { // Broken pipe while writing data ? Not much, we can do here, we just drop the data targets_.erase_and_destroy(Targets::current(*target),DestroyDelete()); if (targets_.empty() && src_ == -1) diff --git a/Utils/Logger/Config.hh b/Utils/Logger/Config.hh index ec23c7f..34566b1 100644 --- a/Utils/Logger/Config.hh +++ b/Utils/Logger/Config.hh @@ -125,8 +125,8 @@ By default, the logging library will call gettimeofday() for each log message. To change the time source, just pass the new class or instance to senf::log::timeSource: \code - // Use senf::Scheduler::instance().eventTime() to time log messages - senf::log::timeSource(); + // Use senf::scheduler::eventTime() to time log messages + senf::log::timeSource(); \endcode */