00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2006,2008 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio 00006 * 00007 * GNU Radio is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 3, or (at your option) 00010 * any later version. 00011 * 00012 * GNU Radio is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License along 00018 * with this program; if not, write to the Free Software Foundation, Inc., 00019 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00020 */ 00021 #ifndef INCLUDED_MB_MBLOCK_H 00022 #define INCLUDED_MB_MBLOCK_H 00023 00024 #include <mblock/common.h> 00025 #include <mblock/message.h> 00026 #include <mblock/port.h> 00027 #include <mblock/time.h> 00028 00029 00030 /*! 00031 * Abstract class implementing visitor pattern 00032 * \ingroup internal 00033 */ 00034 class mb_visitor 00035 { 00036 public: 00037 virtual ~mb_visitor(); 00038 virtual bool operator()(mb_mblock *mblock) = 0; 00039 }; 00040 00041 // ---------------------------------------------------------------------- 00042 00043 /*! 00044 * \brief Parent class for all message passing blocks 00045 * 00046 * Subclass this to define your mblocks. 00047 */ 00048 class mb_mblock : boost::noncopyable, 00049 public boost::enable_shared_from_this<mb_mblock> 00050 { 00051 private: 00052 mb_mblock_impl_sptr d_impl; // implementation details 00053 00054 friend class mb_runtime; 00055 friend class mb_mblock_impl; 00056 friend class mb_worker; 00057 00058 protected: 00059 /*! 00060 * \brief mblock constructor. 00061 * 00062 * Initializing all mblocks in the system is a 3 step procedure. 00063 * 00064 * The top level mblock's constructor is run. That constructor 00065 * (a) registers all of its ports using define_port, (b) registers any 00066 * subcomponents it may have via the define_component method, and 00067 * then (c) issues connect calls to wire its subcomponents together. 00068 * 00069 * \param runtime the runtime associated with this mblock 00070 * \param instance_name specify the name of this instance 00071 * (for debugging, NUMA mapping, etc) 00072 * \param user_arg argument passed by user to constructor 00073 * (ignored by the mb_mblock base class) 00074 */ 00075 mb_mblock(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); 00076 00077 public: 00078 /*! 00079 * \brief Called by the runtime system to execute the initial 00080 * transition of the finite state machine. 00081 * 00082 * This method is called by the runtime after all blocks are 00083 * constructed and before the first message is delivered. Override 00084 * this to initialize your finite state machine. 00085 */ 00086 virtual void initial_transition(); 00087 00088 protected: 00089 /*! 00090 * \brief Called by the runtime system when there's a message to handle. 00091 * 00092 * Override this to define your behavior. 00093 * 00094 * Do not issue any potentially blocking calls in this method. This 00095 * includes things such reads or writes on sockets, pipes or slow 00096 * i/o devices. 00097 */ 00098 virtual void handle_message(mb_message_sptr msg); 00099 00100 /*! 00101 * \brief Define a port. 00102 * 00103 * EXTERNAL and RELAY ports are part of our peer interface. 00104 * INTERNAL ports are used to talk to sub-components. 00105 * 00106 * \param port_name The name of the port (must be unique within this mblock). 00107 * \param protocol_class_name The name of the protocol class associated with 00108 * this port. It must already be defined. 00109 * \param conjugated Are the incoming and outgoing message sets swapped? 00110 * \param port_type INTERNAL, EXTERNAL or RELAY. 00111 */ 00112 mb_port_sptr 00113 define_port(const std::string &port_name, 00114 const std::string &protocol_class_name, 00115 bool conjugated, 00116 mb_port::port_type_t port_type); 00117 00118 /*! 00119 * \brief Define a subcomponent by name. 00120 * 00121 * Called within the constructor to tell the system the 00122 * names and identities of our sub-component mblocks. 00123 * 00124 * \param component_name The name of the sub-component (must be unique with this mblock). 00125 * \param class_name The class of the instance that is to be created. 00126 * \param user_arg The argument to pass to the constructor of the component. 00127 */ 00128 void 00129 define_component(const std::string &component_name, 00130 const std::string &class_name, 00131 pmt_t user_arg = PMT_NIL); 00132 00133 /*! 00134 * \brief connect endpoint_1 to endpoint_2 00135 * 00136 * \param comp_name1 component on one end of the connection 00137 * \param port_name1 the name of the port on comp1 00138 * \param comp_name2 component on the other end of the connection 00139 * \param port_name2 the name of the port on comp2 00140 * 00141 * An endpoint is specified by the component's local name (given as 00142 * component_name in the call to register_component) and the name of 00143 * the port on that component. 00144 * 00145 * To connect an internal or relay port, use "self" as the component name. 00146 */ 00147 void 00148 connect(const std::string &comp_name1, const std::string &port_name1, 00149 const std::string &comp_name2, const std::string &port_name2); 00150 00151 /*! 00152 * \brief disconnect endpoint_1 from endpoint_2 00153 * 00154 * \param comp_name1 component on one end of the connection 00155 * \param port_name1 the name of the port on comp1 00156 * \param comp_name2 component on the other end of the connection 00157 * \param port_name2 the name of the port on comp2 00158 * 00159 * An endpoint is specified by the component's local name (given as 00160 * component_name in the call to register_component) and the name of 00161 * the port on that component. 00162 * 00163 * To disconnect an internal or relay port, use "self" as the component name. 00164 */ 00165 void 00166 disconnect(const std::string &comp_name1, const std::string &port_name1, 00167 const std::string &comp_name2, const std::string &port_name2); 00168 00169 /*! 00170 * \brief disconnect all connections to specified component 00171 * \param component_name component to disconnect 00172 */ 00173 void 00174 disconnect_component(const std::string &component_name); 00175 00176 /*! 00177 * \brief disconnect all connections to all components 00178 */ 00179 void 00180 disconnect_all(); 00181 00182 /*! 00183 * \brief Return number of connections (QA mostly) 00184 */ 00185 int 00186 nconnections() const; 00187 00188 //! Set the class name 00189 void set_class_name(const std::string &name); 00190 00191 /*! 00192 * \brief Tell runtime that we are done. 00193 * 00194 * This method does not return. 00195 */ 00196 void exit(); 00197 00198 /*! 00199 * \brief Ask runtime to execute the shutdown procedure for all blocks. 00200 * 00201 * \param result sets value of \p result output argument of runtime->run(...) 00202 * 00203 * The runtime first sends a maximum priority %shutdown message to 00204 * all blocks. All blocks should handle the %shutdown message, 00205 * perform whatever clean up is required, and call this->exit(); 00206 * 00207 * After a period of time (~100ms), any blocks which haven't yet 00208 * called this->exit() are sent a maximum priority %halt message. 00209 * %halt is detected in main_loop, and this->exit() is called. 00210 * 00211 * After an additional period of time (~100ms), any blocks which 00212 * still haven't yet called this->exit() are sent a SIG<FOO> (TBD) 00213 * signal, which will blow them out of any blocking system calls and 00214 * raise an mbe_terminate exception. The default top-level 00215 * runtime-provided exception handler will call this->exit() to 00216 * finish the process. 00217 * 00218 * runtime->run(...) returns when all blocks have called exit. 00219 */ 00220 void shutdown_all(pmt_t result); 00221 00222 /*! 00223 * \brief main event dispatching loop 00224 * 00225 * Although it is possible to override this, the default implementation 00226 * should work for virtually all cases. 00227 */ 00228 virtual void main_loop(); 00229 00230 public: 00231 virtual ~mb_mblock(); 00232 00233 //! Return instance name of this block 00234 std::string instance_name() const; 00235 00236 //! Return the class name of this block 00237 std::string class_name() const; 00238 00239 //! Set the instance name of this block. 00240 void set_instance_name(const std::string &name); 00241 00242 //! Return the parent of this mblock, or 0 if we're the top-level block. 00243 mb_mblock *parent() const; 00244 00245 /*! 00246 * \brief Schedule a "one shot" timeout. 00247 * 00248 * \param abs_time the absolute time at which the timeout should fire 00249 * \param user_data the data passed in the %timeout message. 00250 * 00251 * When the timeout fires, a message will be sent to the mblock. 00252 * 00253 * The message will have port_id = %sys-port, signal = %timeout, 00254 * data = user_data, metadata = the handle returned from 00255 * schedule_one_shot_timeout, pri = MB_PRI_BEST. 00256 * 00257 * \returns a handle that can be used in cancel_timeout, and is passed 00258 * as the metadata field of the generated %timeout message. 00259 * 00260 * To cancel a pending timeout, call cancel_timeout. 00261 */ 00262 pmt_t 00263 schedule_one_shot_timeout(const mb_time &abs_time, pmt_t user_data); 00264 00265 /*! 00266 * \brief Schedule a periodic timeout. 00267 * 00268 * \param first_abs_time The absolute time at which the first timeout should fire. 00269 * \param delta_time The relative delay between the first and successive timeouts. 00270 * \param user_data the data passed in the %timeout message. 00271 * 00272 * When the timeout fires, a message will be sent to the mblock, and a 00273 * new timeout will be scheduled for previous absolute time + delta_time. 00274 * 00275 * The message will have port_id = %sys-port, signal = %timeout, 00276 * data = user_data, metadata = the handle returned from 00277 * schedule_one_shot_timeout, pri = MB_PRI_BEST. 00278 * 00279 * \returns a handle that can be used in cancel_timeout, and is passed 00280 * as the metadata field of the generated %timeout message. 00281 * 00282 * To cancel a pending timeout, call cancel_timeout. 00283 */ 00284 pmt_t 00285 schedule_periodic_timeout(const mb_time &first_abs_time, 00286 const mb_time &delta_time, 00287 pmt_t user_data); 00288 00289 /*! 00290 * \brief Attempt to cancel a pending timeout. 00291 * 00292 * Note that this only stops a future timeout from firing. It is 00293 * possible that a timeout may have already fired and enqueued a 00294 * %timeout message, but that that message has not yet been seen by 00295 * handle_message. 00296 * 00297 * \param handle returned from schedule_one_shot_timeout or schedule_periodic_timeout. 00298 */ 00299 void cancel_timeout(pmt_t handle); 00300 00301 /*! 00302 * \brief Perform a pre-order depth-first traversal of the hierarchy. 00303 * 00304 * The traversal stops and returns false if any call to visitor returns false. 00305 */ 00306 bool 00307 walk_tree(mb_visitor *visitor); 00308 00309 00310 //! \internal 00311 // internal use only 00312 mb_mblock_impl_sptr 00313 impl() const { return d_impl; } 00314 00315 }; 00316 00317 00318 #endif /* INCLUDED_MB_MBLOCK_H */