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

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
parent fcde783d
No related branches found
No related tags found
No related merge requests found
......@@ -29,8 +29,10 @@
// 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_
......@@ -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
......
......@@ -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()
......
......@@ -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<DirectoryNode>(i->second))
if (i->second->isDirectory())
output << "/";
else if (i->second->isLink())
output << "@";
output << "\n";
}
}
......
......@@ -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<DirectoryNode*>(node);
dir = static_cast<DirectoryNode*>(&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////////////////////////////////////////
......
......@@ -114,6 +114,21 @@ prefix_ bool senf::console::GenericNode::isCommand()
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
......@@ -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<LinkNode&>(node).follow()
: node;
return getLink(name).followLink();
}
prefix_ senf::console::DirectoryNode &
......
......@@ -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
......
......@@ -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");
......
// $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_
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
// $Id$
//
// Copyright (C) 2009
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief 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
// 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:
......@@ -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;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment