00001 /*************************************************************************** 00002 tag: Peter Soetens Wed Jan 18 14:11:38 CET 2006 SignalBase.hpp 00003 00004 SignalBase.hpp - description 00005 ------------------- 00006 begin : Wed January 18 2006 00007 copyright : (C) 2006 Peter Soetens 00008 email : peter.soetens@mech.kuleuven.be 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU General Public * 00013 * License as published by the Free Software Foundation; * 00014 * version 2 of the License. * 00015 * * 00016 * As a special exception, you may use this file as part of a free * 00017 * software library without restriction. Specifically, if other files * 00018 * instantiate templates or use macros or inline functions from this * 00019 * file, or you compile this file and link it with other files to * 00020 * produce an executable, this file does not by itself cause the * 00021 * resulting executable to be covered by the GNU General Public * 00022 * License. This exception does not however invalidate any other * 00023 * reasons why the executable file might be covered by the GNU General * 00024 * Public License. * 00025 * * 00026 * This library is distributed in the hope that it will be useful, * 00027 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00029 * Lesser General Public License for more details. * 00030 * * 00031 * You should have received a copy of the GNU General Public * 00032 * License along with this library; if not, write to the Free Software * 00033 * Foundation, Inc., 59 Temple Place, * 00034 * Suite 330, Boston, MA 02111-1307 USA * 00035 * * 00036 ***************************************************************************/ 00037 00038 00039 #ifndef ORO_SIGNAL_BASE_HPP 00040 #define ORO_SIGNAL_BASE_HPP 00041 00042 #include <boost/intrusive_ptr.hpp> 00043 #include <boost/function.hpp> 00044 00045 #include "../rtt-config.h" 00046 00047 #if defined(OROBLD_OS_NO_ASM) 00048 #define ORO_SIGNAL_USE_RT_LIST 00049 #else 00050 #define ORO_SIGNAL_USE_LIST_LOCK_FREE 00051 #endif 00052 00053 #include "../os/Atomic.hpp" 00054 #ifdef ORO_SIGNAL_USE_LIST_LOCK_FREE 00055 #include "ListLockFree.hpp" 00056 #include <boost/shared_ptr.hpp> 00057 #else 00058 #ifdef ORO_SIGNAL_USE_RT_LIST 00059 #include "../os/Mutex.hpp" 00060 #include "../os/rt_list.hpp" 00061 #else 00062 #include "../os/Mutex.hpp" 00063 #include <list> 00064 #endif 00065 #endif 00066 00067 namespace RTT 00068 { 00069 namespace internal { 00070 00071 class SignalBase; 00072 00080 class RTT_API ConnectionBase 00081 { 00082 protected: 00083 RTT_API friend void intrusive_ptr_add_ref(ConnectionBase*); 00084 RTT_API friend void intrusive_ptr_release(ConnectionBase*); 00085 bool mconnected; 00086 SignalBase* m_sig; 00087 00092 os::AtomicInt refcount; 00093 00097 void ref(); 00101 void deref(); 00102 00103 protected: 00104 virtual ~ConnectionBase(); 00105 public: 00106 ConnectionBase(SignalBase* sig); 00107 00108 typedef boost::intrusive_ptr<ConnectionBase> shared_ptr; 00109 00110 inline bool connected() { return mconnected && m_sig; } 00111 bool connect(); 00112 bool disconnect(); 00113 void destroy(); 00114 private: 00115 ConnectionBase(const ConnectionBase& ); 00116 const ConnectionBase& operator=( const ConnectionBase& ); 00117 }; 00118 00119 RTT_API void intrusive_ptr_add_ref( ConnectionBase* p ); 00120 RTT_API void intrusive_ptr_release( ConnectionBase* p ); 00121 00128 class RTT_API SignalBase 00129 { 00130 public: 00131 typedef ConnectionBase::shared_ptr connection_t; 00132 #ifdef ORO_SIGNAL_USE_LIST_LOCK_FREE 00133 typedef ListLockFree<connection_t> connections_list; 00134 #else 00135 #ifdef ORO_SIGNAL_USE_RT_LIST 00136 typedef RTT::os::rt_list< connection_t > connections_list; 00137 #else 00138 typedef std::list< connection_t > connections_list; 00139 #endif 00140 typedef connections_list::iterator iterator; 00141 typedef connections_list::iterator const_iterator; 00142 #endif 00143 protected: 00144 friend class ConnectionBase; 00145 00146 void conn_setup( connection_t conn ); 00147 00148 void conn_connect( connection_t conn ); 00149 00150 void conn_disconnect( connection_t conn ); 00151 00152 void conn_destroy( connection_t conn ); 00153 protected: 00154 connections_list mconnections; 00155 #ifdef ORO_SIGNAL_USE_LIST_LOCK_FREE 00156 // no mutexes involved 00157 #else 00158 00161 void cleanup(); 00162 00163 RTT::os::MutexRecursive m; 00164 iterator itend; 00165 #ifdef ORO_SIGNAL_USE_RT_LIST 00166 int disconcount; 00167 #else 00168 int concount; 00169 #endif 00170 #endif 00171 bool emitting; 00172 SignalBase(); 00173 public: 00180 virtual ~SignalBase(); 00181 00186 void disconnect(); 00187 00193 void destroy(); 00194 00204 void reserve(size_t conns); 00208 virtual int arity() const = 0; 00209 private: 00210 SignalBase(const SignalBase& ); 00211 const SignalBase& operator=( const SignalBase& ); 00212 00213 }; 00214 }// namespace detail 00215 00216 } 00217 #endif