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 */ |