Statistics
| Branch: | Tag: | Revision:

root / mblock / src / include / mblock / mblock.h @ c48f42b5

History | View | Annotate | Download (10.2 kB)

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
  //! \implementation
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 */