Libbarrett
1.2.4
|
00001 /* 00002 * system-inl.h 00003 * 00004 * Created on: Feb 28, 2011 00005 * Author: dc 00006 */ 00007 00008 #include <barrett/systems/abstract/execution_manager.h> 00009 #include <barrett/thread/null_mutex.h> 00010 00011 00012 namespace barrett { 00013 namespace systems { 00014 00015 00016 inline thread::Mutex& System::getEmMutex() const 00017 { 00018 if (hasExecutionManager()) { 00019 return getExecutionManager()->getMutex(); 00020 } else { 00021 return thread::NullMutex::aNullMutex; 00022 } 00023 } 00024 00025 00026 inline thread::Mutex& System::AbstractInput::getEmMutex() const 00027 { 00028 if (parentSys != NULL) { 00029 return parentSys->getEmMutex(); 00030 } else { 00031 return thread::NullMutex::aNullMutex; 00032 } 00033 } 00034 00035 00036 inline thread::Mutex& System::AbstractOutput::getEmMutex() const 00037 { 00038 if (parentSys != NULL) { 00039 return parentSys->getEmMutex(); 00040 } else { 00041 return thread::NullMutex::aNullMutex; 00042 } 00043 } 00044 00045 00046 template<typename T> 00047 System::Input<T>::~Input() { 00048 if (parentSys == NULL) { 00049 assert( !isConnected() ); 00050 } else { 00051 mandatoryCleanUp(); 00052 } 00053 } 00054 00055 template<typename T> 00056 void System::Input<T>::mandatoryCleanUp() 00057 { 00058 assert(parentSys != NULL); 00059 00060 BARRETT_SCOPED_LOCK(getEmMutex()); 00061 00062 disconnect(*this); 00063 AbstractInput::mandatoryCleanUp(); 00064 } 00065 00066 template<typename T> 00067 void System::Input<T>::pushExecutionManager() 00068 { 00069 if (isConnected()) { 00070 output->parentSys->setExecutionManager(parentSys->em); 00071 } 00072 } 00073 00074 template<typename T> 00075 void System::Input<T>::unsetExecutionManager() 00076 { 00077 if (isConnected()) { 00078 output->parentSys->unsetExecutionManager(); 00079 } 00080 } 00081 00082 00083 template<typename T> 00084 System::Output<T>::~Output() { 00085 if (parentSys == NULL) { 00086 assert( !isConnected() ); 00087 } else { 00088 mandatoryCleanUp(); 00089 } 00090 } 00091 00092 template<typename T> 00093 void System::Output<T>::mandatoryCleanUp() 00094 { 00095 assert(parentSys != NULL); 00096 00097 BARRETT_SCOPED_LOCK(getEmMutex()); 00098 00099 disconnect(*this); 00100 value.undelegate(); 00101 value.delegators.clear_and_dispose(typename Value::UndelegateDisposer()); 00102 AbstractOutput::mandatoryCleanUp(); 00103 } 00104 00105 template<typename T> 00106 ExecutionManager* System::Output<T>::collectExecutionManager() const 00107 { 00108 typename connected_input_list_type::const_iterator i(inputs.begin()), iEnd(inputs.end()); 00109 for (; i != iEnd; ++i) { 00110 if (i->parentSys->hasExecutionManager()) { 00111 return i->parentSys->getExecutionManager(); 00112 } 00113 } 00114 00115 typename Value::delegate_output_list_type::const_iterator o(value.delegators.begin()), oEnd(value.delegators.end()); 00116 for (; o != oEnd; ++o) { 00117 if (o->parentSys->hasExecutionManager()) { 00118 return o->parentSys->getExecutionManager(); 00119 } 00120 } 00121 00122 return NULL; 00123 } 00124 00125 template<typename T> 00126 void System::Output<T>::pushExecutionManager() 00127 { 00128 if (value.delegate != NULL) { 00129 value.delegate->parentOutput.parentSys->setExecutionManager(parentSys->em); 00130 } 00131 } 00132 00133 template<typename T> 00134 void System::Output<T>::unsetExecutionManager() 00135 { 00136 if (value.delegate != NULL) { 00137 value.delegate->parentOutput.parentSys->unsetExecutionManager(); 00138 } 00139 } 00140 00141 template<typename T> 00142 void System::Output<T>::Value::delegateTo(Output<T>& delegateOutput) 00143 { 00144 BARRETT_SCOPED_LOCK(parentOutput.getEmMutex()); 00145 00146 undelegate(); 00147 delegate = &(delegateOutput.value); 00148 delegate->delegators.push_back(parentOutput); 00149 00150 parentOutput.pushExecutionManager(); 00151 } 00152 00153 template<typename T> 00154 void System::Output<T>::Value::undelegate() 00155 { 00156 BARRETT_SCOPED_LOCK(parentOutput.getEmMutex()); 00157 00158 if (delegate != NULL) { 00159 delegate->delegators.erase(delegate_output_list_type::s_iterator_to(parentOutput)); 00160 parentOutput.unsetExecutionManager(); 00161 delegate = NULL; 00162 } 00163 } 00164 00165 00166 namespace detail { 00167 template<typename T> inline typename IntrusiveDelegateFunctor<T>::hook_ptr IntrusiveDelegateFunctor<T>::to_hook_ptr(IntrusiveDelegateFunctor<T>::value_type &value) 00168 { 00169 return &value.delegateHook; 00170 } 00171 template<typename T> inline typename IntrusiveDelegateFunctor<T>::const_hook_ptr IntrusiveDelegateFunctor<T>::to_hook_ptr(const IntrusiveDelegateFunctor<T>::value_type &value) 00172 { 00173 return &value.delegateHook; 00174 } 00175 template<typename T> inline typename IntrusiveDelegateFunctor<T>::pointer IntrusiveDelegateFunctor<T>::to_value_ptr(IntrusiveDelegateFunctor<T>::hook_ptr n) 00176 { 00177 return boost::intrusive::get_parent_from_member<System::Output<T> >(n, &System::Output<T>::delegateHook); 00178 } 00179 template<typename T> inline typename IntrusiveDelegateFunctor<T>::const_pointer IntrusiveDelegateFunctor<T>::to_value_ptr(IntrusiveDelegateFunctor<T>::const_hook_ptr n) 00180 { 00181 return boost::intrusive::get_parent_from_member<System::Output<T> >(n, &System::Output<T>::delegateHook); 00182 } 00183 } 00184 00185 00186 } 00187 }