ModuleManager.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #include "ModuleManager.hh"
18 //#include "ModuleManager.ih"
19 
20 // Custom includes
22 #include <senf/Utils/membind.hh>
25 #include "Module.hh"
26 
27 //#include "ModuleManager.mpp"
28 #define prefix_
29 //-/////////////////////////////////////////////////////////////////////////////////////////////////
30 
31 //-/////////////////////////////////////////////////////////////////////////////////////////////////
32 // senf::ppi::ModuleManager
33 
35 {
36  while (! initQueue_.empty()) {
37  initQueue_.front()->v_init();
38  initQueue_.pop_front();
39  }
40  initRunner_.disable();
41 }
42 
43 #ifndef DOXYGEN
44 
45 struct senf::ppi::ModuleManager::RunGuard
46 {
47  RunGuard(ModuleManager & m) : manager(m) { manager.running_ = true; }
48  ~RunGuard() { manager.running_ = false; }
49  ModuleManager & manager;
50 };
51 
52 #endif
53 
55 {
56  init();
57  RunGuard guard (*this);
58  scheduler::process();
59 }
60 
61 //-/////////////////////////////////////////////////////////////////////////////////////////////////
62 // private members
63 
64 prefix_ void senf::ppi::ModuleManager::registerModule(module::Module & module)
65 {
66  if (not alive_)
67  return;
68  moduleRegistry_.push_back(&module);
69 }
70 
71 prefix_ void senf::ppi::ModuleManager::unregisterModule(module::Module & module)
72 {
73  if (not alive_)
74  return;
75  moduleRegistry_.erase(
76  std::remove(moduleRegistry_.begin(), moduleRegistry_.end(), & module),
77  moduleRegistry_.end());
78 }
79 
80 prefix_ void senf::ppi::ModuleManager::registerInitializable(Initializable & i)
81 {
82  if (not alive_)
83  return;
84  initQueue_.push_back(&i);
85  initRunner_.enable();
86  // This call ensures, that the senf::ppi::init() handler is called as next handler
87  // after this handler returns (this works since the senf::ppi::init() handler is registered as
88  // PRE hook and thus has very high priority)
89  scheduler::yield();
90 }
91 
92 prefix_ void senf::ppi::ModuleManager::unregisterInitializable(Initializable & i)
93 {
94  if (not alive_)
95  return;
96  initQueue_.erase(
97  std::remove(initQueue_.begin(), initQueue_.end(), &i),
98  initQueue_.end());
99  if (initQueue_.empty())
100  initRunner_.disable();
101 }
102 
103 prefix_ senf::ppi::ModuleManager::ModuleManager()
104  : running_(false),
105  alive_(true),
106  initRunner_("senf::ppi::init", membind(&ModuleManager::init, this), scheduler::EventHook::PRE, false)
107 {
108  console::sysdir().add("ppi", consoleDir_);
109 
110  consoleDir_
111  .add("dump", console::factory::Command(
112  senf::membind(&ModuleManager::dumpModules, this))
113  .doc("Dump complete PPI structure\n"
114  "The dump will contain one paragraph for each module. The first line gives module\n"
115  "information, additional lines list all connectors and their peers (if connected).\n"
116  "\n"
117  "This information can be processed by 'tools/drawmodules.py' and 'dot' (from the\n"
118  "graphviz package) to generate a graphic representation of the module structure:\n"
119  "\n"
120  " $ echo /sys/ppi/dump | nc -q1 <host> <port> \\\n"
121  " | python tools/drawmodules.py | dot -Tpng /dev/fd/0 >modules.png\n")
122  );
123  consoleDir_.add("modules", console::factory::Directory());
124 }
125 
126 prefix_ senf::ppi::ModuleManager::~ModuleManager()
127 {
128  alive_ = false;
129 }
130 
131 prefix_ void senf::ppi::ModuleManager::dumpModules(std::ostream & os)
132  const
133 {
134  for (ModuleRegistry::const_iterator i (moduleRegistry_.begin()), i_end (moduleRegistry_.end());
135  i != i_end; ++i) {
136  auto const & _tmp_to_make_clang_happy_ (**i);
137  os << *i << " " << prettyName(typeid(_tmp_to_make_clang_happy_)) << "\n";
138  for (module::Module::ConnectorRegistry::iterator j ((*i)->connectorRegistry_.begin()),
139  j_end ((*i)->connectorRegistry_.end()); j != j_end; ++j) {
140  auto const & _tmp_to_make_clang_happy2_ (**j);
141  os << " " << *j << " " << prettyName(typeid(_tmp_to_make_clang_happy2_));
142  if ((**j).connected()) {
143  os << " " << & (*j)->peer();
144  connector::PassiveConnector * pc (dynamic_cast<connector::PassiveConnector *>(*j));
145  if (pc && pc->throttled())
146  os << " throttled";
147  }
148  os << "\n";
149  }
150  os << "\n";
151  }
152 }
153 
154 //-/////////////////////////////////////////////////////////////////////////////////////////////////
155 #undef prefix_
156 //#include "ModuleManager.mpp"
157 
158 
159 // Local Variables:
160 // mode: c++
161 // fill-column: 100
162 // comment-column: 40
163 // c-file-style: "senf"
164 // indent-tabs-mode: nil
165 // ispell-local-dictionary: "american"
166 // compile-command: "scons -u test"
167 // End:
void run()
Called by senf::ppi::run()
Module base-class.
Definition: Module.hh:169
Module public header.
#define prefix_
Passive connector base-class.
Definition: Connectors.hh:231
boost::function< R(Args)> membind(R(T::*fn)(Args), T *ob)
ModuleManager public header.
std::string prettyName(std::type_info const &type)
bool throttled() const
Get accumulative throttling state.
static Priority const PRE
void init()
Called by senf::ppi::init()
Internal: Module management.