// Custom includes
#include <signal.h>
#include <time.h>
+#include <boost/lambda/lambda.hpp>
#include "../Utils/Exception.hh"
#include "../Utils/senfassert.hh"
+#include "../Utils/ScopeExit.hh"
//#include "FIFORunner.mpp"
#define prefix_
run(f, l);
}
-
prefix_ void senf::scheduler::detail::FIFORunner::run(TaskList::iterator f, TaskList::iterator l)
{
if (f == l)
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
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()
DirectoryNode::child_iterator const i_end (node.children().end());
for (; i != i_end; ++i) {
output << i->first;
- if (boost::dynamic_pointer_cast<DirectoryNode>(i->second))
+ if (i->second->isDirectory())
output << "/";
+ else if (i->second->isLink())
+ output << "@";
output << "\n";
}
}
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;
}
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<DirectoryNode*>(node);
+ dir = static_cast<DirectoryNode*>(&node);
basePath += cs.begin()->first + "/";
}
else
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////////////////////////////////////////
return dynamic_cast<CommandNode const *>(this);
}
+prefix_ senf::console::GenericNode const & senf::console::GenericNode::followLink()
+ const
+{
+ return isLink()
+ ? dynamic_cast<LinkNode const *>(this)->follow()
+ : *this;
+}
+
+prefix_ senf::console::GenericNode & senf::console::GenericNode::followLink()
+{
+ return isLink()
+ ? dynamic_cast<LinkNode *>(this)->follow()
+ : *this;
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::console::LinkNode
senf::console::DirectoryNode::get(std::string const & name)
const
{
- GenericNode & node (getLink(name));
- return node.isLink()
- ? dynamic_cast<LinkNode&>(node).follow()
- : node;
+ return getLink(name).followLink();
}
prefix_ senf::console::DirectoryNode &
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();
///< \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;
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.
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.
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
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
.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");
.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");
--- /dev/null
+// $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 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_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $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 ScopeExit public header */
+
+#ifndef HH_SENF_Utils_ScopeExit_
+#define HH_SENF_Utils_ScopeExit_ 1
+
+// Custom includes
+#include <boost/function.hpp>
+#include <boost/utility.hpp>
+
+//#include "ScopeExit.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+
+ class ScopeExit : boost::noncopyable
+ {
+ public:
+ typedef boost::function<void ()> Function;
+
+ explicit ScopeExit(Function const & fn);
+ ~ScopeExit();
+
+ private:
+ Function fn_;
+ };
+
+}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "ScopeExit.cci"
+//#include "ScopeExit.ct"
+//#include "ScopeExit.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
///////////////////////////////////////////////////////////////////////////
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);
if (!BaseEditor::cb_init())
return false;
prompt(prompt_);
- forceRedisplay();
+ show();
return true;
}