From: g0dil Date: Fri, 16 Jan 2009 22:24:01 +0000 (+0000) Subject: Utils: Add ScopeExit class X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=79e54eda6a7fb5ac3fa5b37f408dd386454c5bbd;p=senf.git Utils: Add ScopeExit class Utils/Console: Add '@' to 'ls' output for link nodes Utils/Console: Path completion in the LineEditor follows links in all cases Utils/Console: Path completion adds blank space after non-directories git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1063 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Scheduler/FIFORunner.cc b/Scheduler/FIFORunner.cc index 545b4ae..b39b5c2 100644 --- a/Scheduler/FIFORunner.cc +++ b/Scheduler/FIFORunner.cc @@ -29,8 +29,10 @@ // Custom includes #include #include +#include #include "../Utils/Exception.hh" #include "../Utils/senfassert.hh" +#include "../Utils/ScopeExit.hh" //#include "FIFORunner.mpp" #define prefix_ @@ -143,7 +145,6 @@ prefix_ void senf::scheduler::detail::FIFORunner::run() run(f, l); } - prefix_ void senf::scheduler::detail::FIFORunner::run(TaskList::iterator f, TaskList::iterator l) { if (f == l) @@ -164,32 +165,30 @@ prefix_ void senf::scheduler::detail::FIFORunner::run(TaskList::iterator f, Task tasks_.insert(l, null); TaskList::iterator end (TaskList::current(null)); next_ = f; - try { - while (next_ != end) { - TaskInfo & task (*next_); - if (task.runnable_) { - task.runnable_ = false; - runningName_ = task.name(); -# ifdef SENF_DEBUG - runningBacktrace_ = task.backtrace_; -# endif - TaskList::iterator i (next_); - ++ next_; - tasks_.splice(l, tasks_, i); - watchdogCount_ = 1; - task.run(); - } - else - ++ next_; + + using namespace boost::lambda; + ScopeExit atExit (( + var(watchdogCount_) = 0, + var(next_) = l + )); + + while (next_ != end) { + TaskInfo & task (*next_); + if (task.runnable_) { + task.runnable_ = false; + runningName_ = task.name(); +# ifdef SENF_DEBUG + runningBacktrace_ = task.backtrace_; +# endif + TaskList::iterator i (next_); + ++ next_; + tasks_.splice(l, tasks_, i); + watchdogCount_ = 1; + task.run(); } + else + ++ next_; } - catch (...) { - watchdogCount_ = 0; - next_ = l; - throw; - } - watchdogCount_ = 0; - next_ = l; } prefix_ senf::scheduler::detail::FIFORunner::TaskList::iterator diff --git a/Scheduler/Scheduler.cc b/Scheduler/Scheduler.cc index e7550bb..2467459 100644 --- a/Scheduler/Scheduler.cc +++ b/Scheduler/Scheduler.cc @@ -48,31 +48,40 @@ prefix_ void senf::scheduler::terminate() terminate_ = true; } +namespace { + + // We don't want try { } catch(...) { ... throw; } since that will make debugging more + // difficult: the stack backtrace for an unexpected exception would always end here. + struct SchedulerScopedInit + { + SchedulerScopedInit() + { + senf::scheduler::detail::FIFORunner::instance().startWatchdog(); + senf::scheduler::detail::SignalDispatcher::instance().unblockSignals(); + senf::scheduler::detail::TimerDispatcher::instance().unblockSignals(); + } + + ~SchedulerScopedInit() + { + senf::scheduler::detail::TimerDispatcher::instance().blockSignals(); + senf::scheduler::detail::SignalDispatcher::instance().blockSignals(); + senf::scheduler::detail::FIFORunner::instance().stopWatchdog(); + } + }; +} + prefix_ void senf::scheduler::process() { - try { - detail::FIFORunner::instance().startWatchdog(); - detail::SignalDispatcher::instance().unblockSignals(); - detail::TimerDispatcher::instance().unblockSignals(); - terminate_ = false; - while(! terminate_ && ! (detail::FdDispatcher::instance().empty() && - detail::TimerDispatcher::instance().empty() && - detail::FileDispatcher::instance().empty())) { - detail::FdManager::instance().processOnce(); - detail::FileDispatcher::instance().prepareRun(); - detail::EventHookDispatcher::instance().prepareRun(); - detail::FIFORunner::instance().run(); - } - } - catch(...) { - detail::TimerDispatcher::instance().blockSignals(); - detail::SignalDispatcher::instance().blockSignals(); - detail::FIFORunner::instance().stopWatchdog(); - throw; + SchedulerScopedInit initScheduler; + terminate_ = false; + while(! terminate_ && ! (detail::FdDispatcher::instance().empty() && + detail::TimerDispatcher::instance().empty() && + detail::FileDispatcher::instance().empty())) { + detail::FdManager::instance().processOnce(); + detail::FileDispatcher::instance().prepareRun(); + detail::EventHookDispatcher::instance().prepareRun(); + detail::FIFORunner::instance().run(); } - detail::TimerDispatcher::instance().blockSignals(); - detail::SignalDispatcher::instance().blockSignals(); - detail::FIFORunner::instance().stopWatchdog(); } prefix_ void senf::scheduler::restart() diff --git a/Utils/Console/Executor.cc b/Utils/Console/Executor.cc index f78a736..04cb751 100644 --- a/Utils/Console/Executor.cc +++ b/Utils/Console/Executor.cc @@ -194,8 +194,10 @@ prefix_ void senf::console::Executor::ls(std::ostream & output, DirectoryNode::child_iterator const i_end (node.children().end()); for (; i != i_end; ++i) { output << i->first; - if (boost::dynamic_pointer_cast(i->second)) + if (i->second->isDirectory()) output << "/"; + else if (i->second->isLink()) + output << "@"; output << "\n"; } } diff --git a/Utils/Console/LineEditor.cc b/Utils/Console/LineEditor.cc index bf4d869..31df1f7 100644 --- a/Utils/Console/LineEditor.cc +++ b/Utils/Console/LineEditor.cc @@ -145,7 +145,7 @@ completePath(term::LineEditor & editor, unsigned b, unsigned e, if (path.empty()) { DirectoryNode::ChildrenRange cs (client().cwd().children()); for (DirectoryNode::ChildrenRange::iterator i (cs.begin()); i != cs.end(); ++i) - completions.push_back(i->first + (i->second->isDirectory() ? "/" : "")); + completions.push_back(i->first + (i->second->followLink().isDirectory() ? "/" : " ")); return; } @@ -180,10 +180,10 @@ completePath(term::LineEditor & editor, unsigned b, unsigned e, else { DirectoryNode::ChildrenRange cs (dir->completions(i->value())); if (has_one_elt(cs)) { - GenericNode * node (cs.begin()->second.get()); - if (!node->isDirectory()) + GenericNode & node (cs.begin()->second->followLink()); + if (!node.isDirectory()) return; - dir = static_cast(node); + dir = static_cast(&node); basePath += cs.begin()->first + "/"; } else @@ -193,7 +193,8 @@ completePath(term::LineEditor & editor, unsigned b, unsigned e, DirectoryNode::ChildrenRange cs (dir->completions(i->value())); for (DirectoryNode::ChildrenRange::iterator j (cs.begin()); j != cs.end(); ++j) - completions.push_back(basePath + j->first + (j->second->isDirectory() ? "/" : "")); + completions.push_back(basePath + j->first + + (j->second->followLink().isDirectory() ? "/" : " ")); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Utils/Console/Node.cci b/Utils/Console/Node.cci index dabaec9..1c130cb 100644 --- a/Utils/Console/Node.cci +++ b/Utils/Console/Node.cci @@ -114,6 +114,21 @@ prefix_ bool senf::console::GenericNode::isCommand() return dynamic_cast(this); } +prefix_ senf::console::GenericNode const & senf::console::GenericNode::followLink() + const +{ + return isLink() + ? dynamic_cast(this)->follow() + : *this; +} + +prefix_ senf::console::GenericNode & senf::console::GenericNode::followLink() +{ + return isLink() + ? dynamic_cast(this)->follow() + : *this; +} + /////////////////////////////////////////////////////////////////////////// // senf::console::LinkNode @@ -154,10 +169,7 @@ prefix_ senf::console::GenericNode & senf::console::DirectoryNode::get(std::string const & name) const { - GenericNode & node (getLink(name)); - return node.isLink() - ? dynamic_cast(node).follow() - : node; + return getLink(name).followLink(); } prefix_ senf::console::DirectoryNode & diff --git a/Utils/Console/Node.hh b/Utils/Console/Node.hh index 137c8b0..6caef96 100644 --- a/Utils/Console/Node.hh +++ b/Utils/Console/Node.hh @@ -296,6 +296,9 @@ namespace console { bool isLink() const; ///< \c true, if this is a link node bool isCommand() const; ///< \c true, if this is a command node + GenericNode const & followLink() const; ///< Follow link if \c this node is a link node + GenericNode & followLink(); ///< Follow link if \c this node is a link node + protected: GenericNode(); @@ -491,7 +494,7 @@ namespace console { ///< \c true, if there is a child with name \a name GenericNode & get(std::string const & name) const; - ///< Get child node + ///< Get child node automatically dereferencing links /**< \throws UnknownNodeNameException if a child \a name does not exist */ GenericNode & getLink(std::string const & name) const; @@ -500,7 +503,7 @@ namespace console { does not exist */ DirectoryNode & getDirectory(std::string const & name) const; - ///< Get directory child node + ///< Get directory child node (dereferencing links) /**< Same as operator[] \throws UnknownNodeNameException if a child \a name does not exist. @@ -508,7 +511,7 @@ namespace console { directory node. */ DirectoryNode & operator[](std::string const & name) const; - ///< Get directory child node + ///< Get directory child node (dereferencing links) /**< Same as getDirectory \throws UnknownNodeNameException if a child \a name does not exist. @@ -516,7 +519,7 @@ namespace console { directory node. */ CommandNode & getCommand(std::string const & name) const; - ///< Get command child node + ///< Get command child node (dereferencing links) /**< Same as operator() \throws UnknownNodeNameException if a child \a name does not exist @@ -524,7 +527,7 @@ namespace console { command node. */ CommandNode & operator()(std::string const & name) const; - ///< Get command child node + ///< Get command child node (dereferencing links) /**< Same as getCommand() \throws UnknownNodeNameException if a child \a name does not exist diff --git a/Utils/Console/testServer.cc b/Utils/Console/testServer.cc index 7458055..5d1a323 100644 --- a/Utils/Console/testServer.cc +++ b/Utils/Console/testServer.cc @@ -97,6 +97,8 @@ int main(int, char **) .add("showlog", &enableLogging) .doc("Enable display of log messages on the current console"); + senf::console::root().link("sl", senf::console::root()["console"]("showlog")); + serverDir .add("shutdown", &shutdownServer) .doc("Terminate server application"); @@ -110,6 +112,8 @@ int main(int, char **) .add("extra", test.dir) .doc("Example of an instance directory"); + senf::console::root().link("ex", test.dir); + senf::console::Server::start( senf::INet4SocketAddress(23232u) ) .name("testServer"); diff --git a/Utils/ScopeExit.cci b/Utils/ScopeExit.cci new file mode 100644 index 0000000..09ff9cf --- /dev/null +++ b/Utils/ScopeExit.cci @@ -0,0 +1,54 @@ +// $Id$ +// +// Copyright (C) 2009 +// 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 ScopeExit inline non-template implementation */ + +//#include "ScopeExit.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cci.p/////////////////////////////////////// + +prefix_ senf::ScopeExit::ScopeExit(Function const & fn) + : fn_ (fn) +{} + +prefix_ senf::ScopeExit::~ScopeExit() +{ + fn_(); +} + +///////////////////////////////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/Utils/ScopeExit.hh b/Utils/ScopeExit.hh new file mode 100644 index 0000000..ee72622 --- /dev/null +++ b/Utils/ScopeExit.hh @@ -0,0 +1,67 @@ +// $Id$ +// +// Copyright (C) 2009 +// 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 ScopeExit public header */ + +#ifndef HH_SENF_Utils_ScopeExit_ +#define HH_SENF_Utils_ScopeExit_ 1 + +// Custom includes +#include +#include + +//#include "ScopeExit.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace senf { + + class ScopeExit : boost::noncopyable + { + public: + typedef boost::function Function; + + explicit ScopeExit(Function const & fn); + ~ScopeExit(); + + private: + Function fn_; + }; + +} + +///////////////////////////////hh.e//////////////////////////////////////// +#include "ScopeExit.cci" +//#include "ScopeExit.ct" +//#include "ScopeExit.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/Utils/Termlib/Editor.cc b/Utils/Termlib/Editor.cc index 9fc6e68..f3a0c19 100644 --- a/Utils/Termlib/Editor.cc +++ b/Utils/Termlib/Editor.cc @@ -276,7 +276,7 @@ prefix_ void senf::term::BaseEditor::write(std::string const & s) /////////////////////////////////////////////////////////////////////////// prefix_ senf::term::LineEditor::LineEditor(AbstractTerminal & terminal, AcceptCallback cb) - : BaseEditor(terminal), enabled_ (true), prompt_ ("$"), promptWidth_ (1u), editWidth_ (0u), + : BaseEditor(terminal), enabled_ (false), prompt_ ("$"), promptWidth_ (1u), editWidth_ (0u), text_ (""), point_ (0u), displayPos_ (0u), lastKey_ (0u), callback_ (cb), historyPoint_ (0u) { defineKey(KeyParser::Return, &bindings::accept); @@ -521,7 +521,7 @@ prefix_ bool senf::term::LineEditor::cb_init() if (!BaseEditor::cb_init()) return false; prompt(prompt_); - forceRedisplay(); + show(); return true; }