Click
Loading...
Searching...
No Matches
router.hh
Go to the documentation of this file.
1// -*- c-basic-offset: 4; related-file-name: "../../lib/router.cc" -*-
2#ifndef CLICK_ROUTER_HH
3#define CLICK_ROUTER_HH
4#include <click/element.hh>
5#include <click/timer.hh>
6#include <click/sync.hh>
7#include <click/task.hh>
8#include <click/vector.hh>
9#include <click/pair.hh>
10#include <click/standard/threadsched.hh>
11#if CLICK_NS
12# include <click/simclick.h>
13#endif
14#if CLICK_USERLEVEL
15#include <functional>
16#endif
17CLICK_DECLS
18class Master;
19class ElementFilter;
20class RouterVisitor;
21class RouterThread;
22class HashMap_ArenaFactory;
23class NotifierSignal;
24class ThreadSched;
25class Handler;
26class NameInfo;
27
28class Router { public:
29
32 // MASTER
33 inline Master* master() const;
34
35 // STATUS
36 inline bool initialized() const;
37 inline bool handlers_ready() const;
38 inline bool running() const;
39 inline bool dying() const;
40
41 // RUNCOUNT AND RUNCLASS
42 enum { STOP_RUNCOUNT = -2147483647 - 1 };
43 inline int32_t runcount() const;
44 void adjust_runcount(int32_t delta);
45 void set_runcount(int32_t rc);
46 inline void please_stop_driver();
47
48 // ELEMENTS
49 inline const Vector<Element*>& elements() const;
50 inline int nelements() const;
51 inline Element* element(int i) const;
52 inline Element* root_element() const;
53 static Element* element(const Router *router, int i);
54
55 const String& ename(int i) const;
56 String ename_context(int i) const;
57 String elandmark(int i) const;
58 const String& econfiguration(int i) const;
59 void set_econfiguration(int i, const String& conf);
60
61 Element* find(const String& name, ErrorHandler* errh = 0) const;
62 Element* find(const String& name, String context, ErrorHandler* errh = 0) const;
63 Element* find(const String& name, const Element* context, ErrorHandler* errh = 0) const;
64
65 bool element_can_reach(Element* a, Element* b);
66 int visit(Element *e, bool isoutput, int port, RouterVisitor *visitor, bool all_paths = false) const;
67 int visit_ports(Element *e, bool isoutput, int port, RouterVisitor *visitor) const;
68 int visit_paths(Element *e, bool isoutput, int port, RouterVisitor *visitor) const {
69 return visit(e, isoutput, port, visitor, true);
70 }
71 int visit_downstream(Element *e, int port, RouterVisitor *visitor) const;
72 int visit_upstream(Element *e, int port, RouterVisitor *visitor) const;
73
74 int downstream_elements(Element *e, int port, ElementFilter *filter, Vector<Element*> &result) CLICK_DEPRECATED;
75 int upstream_elements(Element *e, int port, ElementFilter *filter, Vector<Element*> &result) CLICK_DEPRECATED;
76
77 inline const char *flow_code_override(int eindex) const;
78 void set_flow_code_override(int eindex, const String &flow_code);
79
80 // HANDLERS
81 // 'const Handler *' results last until that element/handlername modified
82 static const Handler *handler(const Element *e, const String &hname);
83 static void add_read_handler(const Element *e, const String &hname, ReadHandlerCallback callback, void *user_data, uint32_t flags = 0);
84 static void add_write_handler(const Element *e, const String &hname, WriteHandlerCallback callback, void *user_data, uint32_t flags = 0);
85 static void set_handler(const Element *e, const String &hname, uint32_t flags, HandlerCallback callback, void *read_user_data = 0, void *write_user_data = 0);
86 static int set_handler_flags(const Element *e, const String &hname, uint32_t set_flags, uint32_t clear_flags = 0);
87 static int router_handler(int operation, String &data, Element *e, const Handler *handler, ErrorHandler *errh);
88
89 enum { FIRST_GLOBAL_HANDLER = 0x40000000 };
90 static int hindex(const Element *e, const String &hname);
91 static const Handler *handler(const Router *router, int hindex);
92 static void element_hindexes(const Element *e, Vector<int> &result);
93
94 // ATTACHMENTS AND REQUIREMENTS
95 void* attachment(const String& aname) const;
96 void*& force_attachment(const String& aname);
97 void* set_attachment(const String& aname, void* value);
98
99 ErrorHandler* chatter_channel(const String& channel_name) const;
100 HashMap_ArenaFactory* arena_factory() const;
101
102 inline ThreadSched* thread_sched() const;
103 inline void set_thread_sched(ThreadSched* scheduler);
104 inline int home_thread_id(const Element* e) const;
105 inline void set_home_thread_id(const Element* e, int home_thread);
106 inline bool is_fullpush() const;
107 inline void non_fullpush();
108
110 // Needs to be public for NameInfo, but not useful outside
111 inline NameInfo* name_info() const;
112 NameInfo* force_name_info();
115 // UNPARSING
117 void unparse(StringAccum& sa, const String& indent = String()) const;
118 void unparse_requirements(StringAccum& sa, const String& indent = String()) const;
119 void unparse_declarations(StringAccum& sa, const String& indent = String()) const;
120 void unparse_connections(StringAccum& sa, const String& indent = String()) const;
121
122 String element_ports_string(const Element *e) const;
124
125 // INITIALIZATION
128 Router(const String& configuration, Master* master);
129 ~Router();
130
131 static void static_initialize();
132 static void static_cleanup();
133
134 inline void use();
135 void unuse();
136
137 void add_requirement(const String &type, const String &value);
138 int add_element(Element *e, const String &name, const String &conf, const String &filename, unsigned lineno);
139 int add_connection(int from_idx, int from_port, int to_idx, int to_port, bool is_context, String context);
140#if CLICK_LINUXMODULE
141 int add_module_ref(struct module* module);
142#endif
143
144 inline Router* hotswap_router() const;
145 void set_hotswap_router(Router* router);
146
147#if CLICK_USERLEVEL
160 class InitFuture { public:
161 InitFuture(Element* owner = 0);
162 ~InitFuture();
163
164 virtual void notifyParent(InitFuture* future);
165
166 virtual int solve_initialize(ErrorHandler* errh);
167
168 virtual int completed(ErrorHandler* errh);
169 protected:
170 bool _completed;
171 Element* _owner;
172 };
173
174 class ChildrenFuture : public InitFuture { public:
175 ChildrenFuture(Element* owner = 0);
176 ~ChildrenFuture();
177 virtual int solve_initialize(ErrorHandler* errh);
178 void postOnce(InitFuture* future);
179 virtual void post(InitFuture* future);
180 void post(std::function<int(ErrorHandler*)>, Element* owner = 0);
181 void post(std::function<int(void)>, Element* owner = 0);
182 virtual int completed(ErrorHandler* errh);
183 private:
184 Vector<InitFuture*> _children;
185 };
186
187 class FctFuture : public InitFuture { public:
188 FctFuture(std::function<int(void)> f, Element* owner = 0);
189 FctFuture(std::function<int(ErrorHandler*)> f, Element* owner = 0);
190 ~FctFuture();
191
192 virtual int solve_initialize(ErrorHandler* errh) override;
193 std::function<int(ErrorHandler*)> _f;
194 };
195
196 class FctChildFuture : public FctFuture { public:
197 FctChildFuture(std::function<int(ErrorHandler*)> f, Element* owner, InitFuture* future);
198 ~FctChildFuture();
199
200 virtual int solve_initialize(ErrorHandler* errh) override;
201 private:
202 InitFuture* _child;
203 };
204
205 ChildrenFuture* get_root_init_future() {
206 return &_root_init_future;
207 }
208
209#endif
210 int initialize(ErrorHandler* errh);
211 void activate(bool foreground, ErrorHandler* errh);
212 inline void activate(ErrorHandler* errh);
213 inline void set_foreground(bool foreground);
214
215 int new_notifier_signal(const char *name, NotifierSignal &signal);
216 String notifier_signal_name(const atomic_uint32_t *signal) const;
218
220 // Needs to be public for Lexer, etc., but not useful outside
221 struct Port {
222 int idx;
223 int port;
224
225 Port() {
226 }
227 Port(int i, int p)
228 : idx(i), port(p) {
229 }
230
231 bool operator==(const Port &x) const {
232 return idx == x.idx && port == x.port;
233 }
234 bool operator!=(const Port &x) const {
235 return idx != x.idx || port != x.port;
236 }
237 bool operator<(const Port &x) const {
238 return idx < x.idx || (idx == x.idx && port < x.port);
239 }
240 bool operator<=(const Port &x) const {
241 return idx < x.idx || (idx == x.idx && port <= x.port);
242 }
243 };
244
245 struct Connection {
246 Port p[2];
247 bool _is_context;
248 String _context;
249
250
251 Connection() : _is_context(false), _context("") {
252 }
253 Connection(int from_idx, int from_port, int to_idx, int to_port) : _is_context(false), _context("") {
254 p[0] = Port(to_idx, to_port);
255 p[1] = Port(from_idx, from_port);
256 }
257 Connection(int from_idx, int from_port, int to_idx, int to_port, bool is_context, String context) {
258 p[0] = Port(to_idx, to_port);
259 p[1] = Port(from_idx, from_port);
260 _is_context = is_context;
261 _context = context;
262 }
263
264 const Port &operator[](int i) const {
265 assert(i >= 0 && i < 2);
266 return p[i];
267 }
268 Port &operator[](int i) {
269 assert(i >= 0 && i < 2);
270 return p[i];
271 }
272
273 bool operator==(const Connection &x) const {
274 return p[0] == x.p[0] && p[1] == x.p[1];
275 }
276 bool operator<(const Connection &x) const {
277 return p[0] < x.p[0] || (p[0] == x.p[0] && p[1] < x.p[1]);
278 }
279 };
282#if CLICK_NS
283 simclick_node_t *simnode() const;
284 int sim_get_ifid(const char* ifname);
285 int sim_listen(int ifid, int element);
286 int sim_if_ready(int ifid);
287 int sim_write(int ifid, int ptype, const unsigned char *, int len,
288 simclick_simpacketinfo *pinfo);
289 int sim_incoming_packet(int ifid, int ptype, const unsigned char *,
290 int len, simclick_simpacketinfo* pinfo);
291 void sim_trace(const char* event);
292 int sim_get_node_id();
293 int sim_get_next_pkt_id();
294 int sim_if_promisc(int ifid);
295
296 protected:
297 Vector<Vector<int> *> _listenvecs;
298 Vector<int>* sim_listenvec(int ifid);
299#endif
300
301 private:
302
303 class RouterContextErrh;
304
305 enum {
306 ROUTER_NEW, ROUTER_PRECONFIGURE, ROUTER_PREINITIALIZE,
307 ROUTER_LIVE, ROUTER_DEAD // order is important
308 };
309 enum {
310 RUNNING_DEAD = -2, RUNNING_INACTIVE = -1, RUNNING_PREPARING = 0,
311 RUNNING_BACKGROUND = 1, RUNNING_ACTIVE = 2
312 };
313
314 Master* _master;
315 ChildrenFuture _root_init_future;
316
317 atomic_uint32_t _runcount;
318
319 volatile int _state;
320 bool _have_connections : 1;
321 mutable bool _conn_sorted : 1;
322 bool _have_configuration : 1;
323 volatile int _running;
324
325 atomic_uint32_t _refcount;
326
327 Vector<Element *> _elements;
328 Vector<String> _element_names;
329 Vector<String> _element_configurations;
330 Vector<uint32_t> _element_landmarkids;
331 mutable Vector<int> _element_home_thread_ids;
332
333 struct element_landmark_t {
334 uint32_t first_landmarkid;
335 String filename;
336 };
337 Vector<element_landmark_t> _element_landmarks;
338 uint32_t _last_landmarkid;
339
340 mutable Vector<int> _element_name_sorter;
341 Vector<int> _element_gport_offset[2];
342 Vector<int> _element_configure_order;
343
344 mutable Vector<Connection> _conn;
345 mutable Vector<int> _conn_output_sorter;
346
347 Vector<String> _requirements;
348
349 Vector<int> _ehandler_first_by_element;
350 Vector<int> _ehandler_to_handler;
351 Vector<int> _ehandler_next;
352
353 Vector<int> _handler_first_by_name;
354
355 enum { HANDLER_BUFSIZ = 256 };
356 Handler** _handler_bufs;
357 int _nhandlers_bufs;
358 int _free_handler;
359
360 Vector<String> _attachment_names;
361 Vector<void*> _attachments;
362
363 Element* _root_element;
364 String _configuration;
365
366 struct notifier_signals_t {
367 enum { capacity = 4096 };
368 String name;
369 int nsig;
370 atomic_uint32_t sig[capacity / 32];
371 notifier_signals_t *next;
372 notifier_signals_t(const String &n, notifier_signals_t *nx)
373 : name(n), nsig(0), next(nx) {
374 memset(&sig[0], 0, sizeof(sig));
375 }
376 };
377 notifier_signals_t *_notifier_signals;
378 HashMap_ArenaFactory* _arena_factory;
379 Router* _hotswap_router;
380 ThreadSched* _thread_sched;
381 bool _is_fullpush;
382 mutable NameInfo* _name_info;
383 Vector<int> _flow_code_override_eindex;
384 Vector<String> _flow_code_override;
385
386 Router* _next_router;
387
388#if CLICK_LINUXMODULE
389 Vector<struct module*> _modules;
390#endif
391
392 Router(const Router&);
393 Router& operator=(const Router&);
394
395 Connection *remove_connection(Connection *cp);
396 void hookup_error(const Port &p, bool isoutput, const char *message,
397 ErrorHandler *errh, bool active = false);
398 int check_hookup_elements(ErrorHandler*);
399 int check_hookup_range(ErrorHandler*);
400 int check_hookup_completeness(ErrorHandler*);
401
402 const char *hard_flow_code_override(int e) const;
403 int processing_error(const Connection &conn, bool, int, ErrorHandler*);
404 int check_push_and_pull(ErrorHandler*);
405
406 void set_connections();
407 void sort_connections() const;
408 int connindex_lower_bound(bool isoutput, const Port &port) const;
409
410 void make_gports();
411 inline int ngports(bool isout) const {
412 return _element_gport_offset[isout].back();
413 }
414 inline int gport(bool isoutput, const Port &port) const;
415
416 int hard_home_thread_id(const Element *e) const;
417
418 int element_lerror(ErrorHandler*, Element*, const char*, ...) const;
419
420 // private handler methods
421 void initialize_handlers(bool, bool);
422 inline Handler* xhandler(int) const;
423 int find_ehandler(int, const String&, bool allow_star) const;
424 static inline Handler fetch_handler(const Element*, const String&);
425 void store_local_handler(int eindex, Handler &h);
426 static void store_global_handler(Handler &h);
427 static inline void store_handler(const Element *element, Handler &h);
428
429 // global handlers
430 static String router_read_handler(Element *e, void *user_data);
431 static int router_write_handler(const String &str, Element *e, void *user_data, ErrorHandler *errh);
432
434 friend class Master;
435 friend class Task;
436 friend class Lexer;
437 friend int Element::set_nports(int, int);
440};
441
442
449inline void
451{
452 _refcount++;
453}
454
459inline bool
461{
462 return _running > 0;
463}
464
466inline bool
468{
469 return _running == RUNNING_DEAD;
470}
471
473inline bool
475{
476 return _state == ROUTER_LIVE;
477}
478
484inline bool
486{
487 return _state > ROUTER_PRECONFIGURE;
488}
489
492inline const Vector<Element*>&
494{
495 return _elements;
496}
497
499inline int
501{
502 return _elements.size();
503}
504
512inline Element*
513Router::element(int i) const
514{
515 return element(this, i);
516}
517
525inline Element*
527{
528 return _root_element;
529}
530
531inline ThreadSched*
532Router::thread_sched() const
533{
534 return _thread_sched;
535}
536
537inline void
538Router::set_thread_sched(ThreadSched* ts)
539{
540 _thread_sched = ts;
541}
542
543inline int
544Router::home_thread_id(const Element* e) const
545{
546 if (initialized())
547 return _element_home_thread_ids[e->eindex() + 1];
548 else
549 return hard_home_thread_id(e);
550}
551
552inline void
553Router::set_home_thread_id(const Element* e, int home_thread_id)
554{
555 _element_home_thread_ids[e->eindex() + 1] = home_thread_id;
556}
557
558
568inline bool
570 return _is_fullpush;
571}
572
573inline void
574Router::non_fullpush() {
575 _is_fullpush = false;
576}
577
582inline NameInfo*
583Router::name_info() const
584{
585 return _name_info;
586}
590inline Master*
592{
593 return _master;
594}
595
605inline int32_t
607{
608 return _runcount.value();
609}
610
613inline void
618
622inline const char *
624{
625 if (_flow_code_override.size())
626 return hard_flow_code_override(eindex);
627 else
628 return 0;
629}
630
631inline void
632Router::activate(ErrorHandler* errh)
633{
634 activate(true, errh);
635}
636
637inline void
638Router::set_foreground(bool foreground)
639{
640 assert(_running >= RUNNING_BACKGROUND);
641 _running = foreground ? RUNNING_ACTIVE : RUNNING_BACKGROUND;
642}
643
655inline Element *
656Router::find(const String& name, ErrorHandler *errh) const
657{
658 return find(name, "", errh);
659}
660
675inline int
676Router::visit_downstream(Element *e, int port, RouterVisitor *visitor) const
677{
678 return visit(e, true, port, visitor);
679}
680
695inline int
696Router::visit_upstream(Element *e, int port, RouterVisitor *visitor) const
697{
698 return visit(e, false, port, visitor);
699}
700
701inline HashMap_ArenaFactory*
702Router::arena_factory() const
703{
704 return _arena_factory;
705}
706
716inline Router*
718{
719 return _hotswap_router;
720}
721
722inline
723Handler::Handler(const String &name)
724 : _name(name), _read_user_data(0), _write_user_data(0), _flags(0),
725 _use_count(0), _next_by_name(-1)
726{
727 _read_hook.r = 0;
728 _write_hook.w = 0;
729}
730
731CLICK_ENDDECLS
732#endif
Base class for filter predicates for elements and ports.
Definition elemfilter.hh:7
Base class for Click elements.
Definition element.hh:42
int eindex() const
Return the element's index within its router.
Definition element.hh:524
Error reporting class.
Definition error.hh:90
Represents a router's handlers.
Definition handler.hh:19
Manages Click name databases.
Definition nameinfo.hh:11
An activity signal.
Definition notifier.hh:12
Definition router.hh:160
A router configuration.
Definition router.hh:28
bool handlers_ready() const
Return true iff the router's handlers have been initialized.
Definition router.hh:485
static const Handler * handler(const Element *e, const String &hname)
Return element e's handler named hname.
Definition router.cc:1982
String elandmark(int i) const
Returns element index eindex's landmark.
Definition router.cc:353
~Router()
Destroy the router.
Definition router.cc:110
int nelements() const
Returns the number of elements in the router.
Definition router.hh:500
int visit_upstream(Element *e, int port, RouterVisitor *visitor) const
Traverse the router configuration upstream of [port]e.
Definition router.hh:696
int32_t runcount() const
Return the router's runcount.
Definition router.hh:606
void adjust_runcount(int32_t delta)
Adjust the runcount by delta.
Definition router.cc:844
const String & ename(int i) const
Returns element index eindex's name.
Definition router.cc:292
void set_runcount(int32_t rc)
Set the runcount.
Definition router.cc:822
void set_econfiguration(int i, const String &conf)
Sets element index eindex's configuration string.
Definition router.cc:339
void unuse()
Decrement the router's reference count.
Definition router.cc:174
String configuration_string() const
Returns the router's initial configuration string.
Definition router.cc:2537
void please_stop_driver()
Request a driver stop by adjusting the runcount by -1.
Definition router.hh:614
static int hindex(const Element *e, const String &hname)
Return the handler index for element e's handler named hname.
Definition router.cc:2011
bool is_fullpush() const
Tell if the whole router is in full push mode.
Definition router.hh:569
void unparse_declarations(StringAccum &sa, const String &indent=String()) const
Unparse declarations of the router's elements into sa.
Definition router.cc:2350
const Vector< Element * > & elements() const
Returns a vector containing all the router's elements.
Definition router.hh:493
const char * flow_code_override(int eindex) const
Returns the overriding flow code for element e, if any.
Definition router.hh:623
static void add_read_handler(const Element *e, const String &hname, ReadHandlerCallback callback, void *user_data, uint32_t flags=0)
Add an e.hname read handler.
Definition router.cc:2079
Master * master() const
Return the Master object for this router.
Definition router.hh:591
String element_ports_string(const Element *e) const
Return a string representing e's ports.
Definition router.cc:2459
int visit_ports(Element *e, bool isoutput, int port, RouterVisitor *visitor) const
Traverse the router configuration from one of e's ports, passing per each ports.
Definition router.cc:1016
void unparse_requirements(StringAccum &sa, const String &indent=String()) const
Unparse the router's requirements into sa.
Definition router.cc:2329
bool running() const
Return true iff the router is currently running.
Definition router.hh:460
static int set_handler_flags(const Element *e, const String &hname, uint32_t set_flags, uint32_t clear_flags=0)
Change the e.hname handler's flags.
Definition router.cc:2190
void unparse(StringAccum &sa, const String &indent=String()) const
Unparse this router into sa.
Definition router.cc:2433
Router * hotswap_router() const
Returns the currently-installed router this router will eventually replace.
Definition router.hh:717
static void add_write_handler(const Element *e, const String &hname, WriteHandlerCallback callback, void *user_data, uint32_t flags=0)
Add an e.hname write handler.
Definition router.cc:2112
int visit_downstream(Element *e, int port, RouterVisitor *visitor) const
Traverse the router configuration downstream of e[port].
Definition router.hh:676
const String & econfiguration(int i) const
Returns element index eindex's configuration string.
Definition router.cc:325
void use()
Increment the router's reference count.
Definition router.hh:450
static void set_handler(const Element *e, const String &hname, uint32_t flags, HandlerCallback callback, void *read_user_data=0, void *write_user_data=0)
Add a comprehensive e.hname handler.
Definition router.cc:2153
int visit(Element *e, bool isoutput, int port, RouterVisitor *visitor, bool all_paths=false) const
Traverse the router configuration from one of e's ports, maximum once per port.
Definition router.cc:907
void unparse_connections(StringAccum &sa, const String &indent=String()) const
Unparse the router's connections into sa.
Definition router.cc:2370
String ename_context(int i) const
Returns element index eindex's name context.
Definition router.cc:307
static void element_hindexes(const Element *e, Vector< int > &result)
Return the handler indexes for element e's handlers.
Definition router.cc:2038
Element * find(const String &name, ErrorHandler *errh=0) const
Finds an element named name.
Definition router.hh:656
int new_notifier_signal(const char *name, NotifierSignal &signal)
Create a new basic signal.
Definition router.cc:2266
int upstream_elements(Element *e, int port, ElementFilter *filter, Vector< Element * > &result)
Search for elements upstream from e.
Definition router.cc:1143
bool initialized() const
Return true iff the router has been successfully initialized.
Definition router.hh:474
bool dying() const
Return true iff the router is in the process of being killed.
Definition router.hh:467
int downstream_elements(Element *e, int port, ElementFilter *filter, Vector< Element * > &result)
Search for elements downstream from e.
Definition router.cc:1114
Element * root_element() const
Returns this router's root element.
Definition router.hh:526
Element * element(int i) const
Returns the element with index i.
Definition router.hh:513
A set of Tasks scheduled on the same CPU.
Definition routerthread.hh:32
Base class for router configuration visitors.
Definition routervisitor.hh:17
Efficiently build up Strings from pieces.
Definition straccum.hh:28
A string of characters.
Definition string.hh:22
Represents a frequently-scheduled computational task.
Definition task.hh:49
Vector template.
Definition vector.hh:111
T & back()
Return a reference to the last element (number size()-1).
Definition vector.hh:334
size_type size() const
Return the number of elements.
Definition vector.hh:231
A 32-bit integer with support for atomic operations.
Definition atomic.hh:71
uint32_t value() const
Return the value.
Definition atomic.hh:179
Click's Element class.
Classes for synchronizing among multiple CPUs, particularly in the Linux kernel.
Support for Task, which triggers execution frequently.
Support for Timer, which triggers execution at a given time.
Click's vector container template.