Imported Upstream version 3.2.2
[debian/gnuradio] / mblock / src / include / mblock / mblock.h
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006,2008 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 #ifndef INCLUDED_MB_MBLOCK_H
22 #define INCLUDED_MB_MBLOCK_H
23
24 #include <mblock/common.h>
25 #include <mblock/message.h>
26 #include <mblock/port.h>
27 #include <mblock/time.h>
28
29
30 /*!
31  * Abstract class implementing visitor pattern
32  * \ingroup internal
33  */
34 class mb_visitor
35 {
36 public:
37   virtual ~mb_visitor();
38   virtual bool operator()(mb_mblock *mblock) = 0;
39 };
40
41 // ----------------------------------------------------------------------
42
43 /*!
44  * \brief Parent class for all message passing blocks
45  *
46  * Subclass this to define your mblocks.
47  */
48 class mb_mblock : boost::noncopyable,
49                   public boost::enable_shared_from_this<mb_mblock>
50 {
51 private:
52   mb_mblock_impl_sptr           d_impl;         // implementation details
53
54   friend class mb_runtime;
55   friend class mb_mblock_impl;
56   friend class mb_worker;
57
58 protected:
59   /*!
60    * \brief mblock constructor.
61    *
62    * Initializing all mblocks in the system is a 3 step procedure.
63    *
64    * The top level mblock's constructor is run.  That constructor 
65    * (a) registers all of its ports using define_port, (b) registers any
66    * subcomponents it may have via the define_component method, and
67    * then (c) issues connect calls to wire its subcomponents together.
68    *
69    * \param runtime the runtime associated with this mblock
70    * \param instance_name specify the name of this instance
71    *        (for debugging, NUMA mapping, etc)
72    * \param user_arg argument passed by user to constructor
73    *        (ignored by the mb_mblock base class)
74    */
75   mb_mblock(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
76
77 public:
78   /*!
79    * \brief Called by the runtime system to execute the initial
80    * transition of the finite state machine.
81    *
82    * This method is called by the runtime after all blocks are
83    * constructed and before the first message is delivered.  Override
84    * this to initialize your finite state machine.
85    */
86   virtual void initial_transition();
87
88 protected:
89   /*!
90    * \brief Called by the runtime system when there's a message to handle.
91    *
92    * Override this to define your behavior.
93    *
94    * Do not issue any potentially blocking calls in this method.  This
95    * includes things such reads or writes on sockets, pipes or slow
96    * i/o devices.
97    */
98   virtual void handle_message(mb_message_sptr msg);
99
100   /*!
101    * \brief Define a port.
102    *
103    * EXTERNAL and RELAY ports are part of our peer interface.
104    * INTERNAL ports are used to talk to sub-components.
105    *
106    * \param port_name    The name of the port (must be unique within this mblock).
107    * \param protocol_class_name The name of the protocol class associated with
108    *                            this port.  It must already be defined.
109    * \param conjugated   Are the incoming and outgoing message sets swapped?
110    * \param port_type    INTERNAL, EXTERNAL or RELAY.
111    */
112   mb_port_sptr
113   define_port(const std::string &port_name,
114               const std::string &protocol_class_name,
115               bool conjugated,
116               mb_port::port_type_t port_type);
117
118   /*!
119    * \brief Define a subcomponent by name.
120    *
121    * Called within the constructor to tell the system the
122    * names and identities of our sub-component mblocks.
123    *
124    * \param component_name  The name of the sub-component (must be unique with this mblock).
125    * \param class_name      The class of the instance that is to be created.
126    * \param user_arg The argument to pass to the constructor of the component.
127    */
128   void
129   define_component(const std::string &component_name,
130                    const std::string &class_name,
131                    pmt_t user_arg = PMT_NIL);
132
133   /*!
134    * \brief connect endpoint_1 to endpoint_2
135    *
136    * \param comp_name1  component on one end of the connection
137    * \param port_name1  the name of the port on comp1
138    * \param comp_name2  component on the other end of the connection
139    * \param port_name2  the name of the port on comp2
140    *
141    * An endpoint is specified by the component's local name (given as
142    * component_name in the call to register_component) and the name of
143    * the port on that component.
144    *
145    * To connect an internal or relay port, use "self" as the component name.
146    */
147   void
148   connect(const std::string &comp_name1, const std::string &port_name1,
149           const std::string &comp_name2, const std::string &port_name2);
150
151   /*!
152    * \brief disconnect endpoint_1 from endpoint_2
153    *
154    * \param comp_name1  component on one end of the connection
155    * \param port_name1  the name of the port on comp1
156    * \param comp_name2  component on the other end of the connection
157    * \param port_name2  the name of the port on comp2
158    *
159    * An endpoint is specified by the component's local name (given as
160    * component_name in the call to register_component) and the name of
161    * the port on that component.
162    *
163    * To disconnect an internal or relay port, use "self" as the component name.
164    */
165   void
166   disconnect(const std::string &comp_name1, const std::string &port_name1,
167              const std::string &comp_name2, const std::string &port_name2);
168
169   /*!
170    * \brief disconnect all connections to specified component
171    * \param component_name component to disconnect
172    */
173   void
174   disconnect_component(const std::string &component_name);
175
176   /*!
177    * \brief disconnect all connections to all components
178    */
179   void
180   disconnect_all();
181
182   /*!
183    * \brief Return number of connections (QA mostly)
184    */
185   int
186   nconnections() const;
187
188   //! Set the class name
189   void set_class_name(const std::string &name);
190
191   /*!
192    * \brief Tell runtime that we are done.
193    *
194    * This method does not return.
195    */
196   void exit();
197
198   /*!
199    * \brief Ask runtime to execute the shutdown procedure for all blocks.
200    * 
201    * \param result sets value of \p result output argument of runtime->run(...)
202    *
203    * The runtime first sends a maximum priority %shutdown message to
204    * all blocks.  All blocks should handle the %shutdown message,
205    * perform whatever clean up is required, and call this->exit();
206    *
207    * After a period of time (~100ms), any blocks which haven't yet
208    * called this->exit() are sent a maximum priority %halt message.
209    * %halt is detected in main_loop, and this->exit() is called.
210    *
211    * After an additional period of time (~100ms), any blocks which
212    * still haven't yet called this->exit() are sent a SIG<FOO> (TBD)
213    * signal, which will blow them out of any blocking system calls and
214    * raise an mbe_terminate exception.  The default top-level
215    * runtime-provided exception handler will call this->exit() to
216    * finish the process.
217    *
218    * runtime->run(...) returns when all blocks have called exit.
219    */
220   void shutdown_all(pmt_t result);
221
222   /*!
223    * \brief main event dispatching loop
224    *
225    * Although it is possible to override this, the default implementation
226    * should work for virtually all cases.
227    */
228   virtual void main_loop();
229   
230 public:
231   virtual ~mb_mblock();
232
233   //! Return instance name of this block
234   std::string instance_name() const;
235
236   //! Return the class name of this block
237   std::string class_name() const;
238
239   //! Set the instance name of this block.
240   void set_instance_name(const std::string &name);
241   
242   //! Return the parent of this mblock, or 0 if we're the top-level block.
243   mb_mblock *parent() const;
244
245   /*!
246    * \brief Schedule a "one shot" timeout.
247    *
248    * \param abs_time the absolute time at which the timeout should fire
249    * \param user_data the data passed in the %timeout message.
250    *
251    * When the timeout fires, a message will be sent to the mblock.
252    *
253    * The message will have port_id = %sys-port, signal = %timeout,
254    * data = user_data, metadata = the handle returned from
255    * schedule_one_shot_timeout, pri = MB_PRI_BEST.
256    *
257    * \returns a handle that can be used in cancel_timeout, and is passed
258    * as the metadata field of the generated %timeout message.
259    *
260    * To cancel a pending timeout, call cancel_timeout.
261    */
262   pmt_t
263   schedule_one_shot_timeout(const mb_time &abs_time, pmt_t user_data);
264
265   /*!
266    * \brief Schedule a periodic timeout.
267    *
268    * \param first_abs_time The absolute time at which the first timeout should fire.
269    * \param delta_time The relative delay between the first and successive timeouts.
270    * \param user_data the data passed in the %timeout message.
271    *
272    * When the timeout fires, a message will be sent to the mblock, and a
273    * new timeout will be scheduled for previous absolute time + delta_time.
274    *
275    * The message will have port_id = %sys-port, signal = %timeout,
276    * data = user_data, metadata = the handle returned from
277    * schedule_one_shot_timeout, pri = MB_PRI_BEST.
278    *
279    * \returns a handle that can be used in cancel_timeout, and is passed
280    * as the metadata field of the generated %timeout message.
281    *
282    * To cancel a pending timeout, call cancel_timeout.
283    */
284   pmt_t
285   schedule_periodic_timeout(const mb_time &first_abs_time,
286                             const mb_time &delta_time,
287                             pmt_t user_data);
288
289   /*!
290    * \brief Attempt to cancel a pending timeout.
291    *
292    * Note that this only stops a future timeout from firing.  It is
293    * possible that a timeout may have already fired and enqueued a
294    * %timeout message, but that that message has not yet been seen by
295    * handle_message.
296    *
297    * \param handle returned from schedule_one_shot_timeout or schedule_periodic_timeout.
298    */
299   void cancel_timeout(pmt_t handle);
300
301   /*!
302    * \brief Perform a pre-order depth-first traversal of the hierarchy.
303    *
304    * The traversal stops and returns false if any call to visitor returns false.
305    */
306   bool
307   walk_tree(mb_visitor *visitor);
308
309
310   //! \internal
311   // internal use only
312   mb_mblock_impl_sptr
313   impl() const { return d_impl; }
314
315 };
316
317
318 #endif /* INCLUDED_MB_MBLOCK_H */