Orocos Real-Time Toolkit
2.6.0
|
00001 /*************************************************************************** 00002 tag: Peter Soetens Thu Oct 22 11:59:07 CEST 2009 CorbaDispatcher.hpp 00003 00004 CorbaDispatcher.hpp - description 00005 ------------------- 00006 begin : Thu October 22 2009 00007 copyright : (C) 2009 Peter Soetens 00008 email : peter@thesourcworks.com 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_CORBA_DISPATCHER_HPP 00040 #define ORO_CORBA_DISPATCHER_HPP 00041 00042 #include "../../os/MutexLock.hpp" 00043 #include "../../Activity.hpp" 00044 #include "../../base/ChannelElementBase.hpp" 00045 #include "../../Logger.hpp" 00046 #include "../../internal/List.hpp" 00047 #include "DataFlowI.h" 00048 #include "../../DataFlowInterface.hpp" 00049 #include "../../TaskContext.hpp" 00050 00051 namespace RTT { 00052 namespace corba { 00057 class CorbaDispatcher : public Activity 00058 { 00059 typedef std::map<DataFlowInterface*,CorbaDispatcher*> DispatchMap; 00060 RTT_CORBA_API static DispatchMap DispatchI; 00061 00062 typedef internal::List<base::ChannelElementBase::shared_ptr> RCList; 00063 RCList RClist; 00064 00065 bool do_exit; 00066 00067 RTT_CORBA_API static os::Mutex* mlock; 00068 00069 RTT_CORBA_API static int defaultScheduler; 00070 RTT_CORBA_API static int defaultPriority; 00071 00072 CorbaDispatcher( const std::string& name) 00073 : Activity(defaultScheduler, defaultPriority, 0.0, 0, name), 00074 RClist(20,2), 00075 do_exit(false) 00076 {} 00077 00078 CorbaDispatcher( const std::string& name, int scheduler, int priority) 00079 : Activity(scheduler, priority, 0.0, 0, name), 00080 RClist(20,2), 00081 do_exit(false) 00082 {} 00083 00084 ~CorbaDispatcher() { 00085 this->stop(); 00086 } 00087 00088 public: 00097 static CorbaDispatcher* Instance(DataFlowInterface* iface, int scheduler = defaultScheduler, int priority = defaultPriority) { 00098 if (!mlock) 00099 mlock = new os::Mutex(); 00100 DispatchMap::iterator result = DispatchI.find(iface); 00101 if ( result == DispatchI.end() ) { 00102 os::MutexLock lock(*mlock); 00103 // re-try to find (avoid race): 00104 result = DispatchI.find(iface); 00105 if ( result != DispatchI.end() ) 00106 return result->second; 00107 // *really* not found, let's create it. 00108 std::string name; 00109 if ( iface == 0 || iface->getOwner() == 0) 00110 name = "Global"; 00111 else 00112 name = iface->getOwner()->getName(); 00113 name += ".CorbaDispatch"; 00114 DispatchI[iface] = new CorbaDispatcher( name, scheduler, priority ); 00115 DispatchI[iface]->start(); 00116 return DispatchI[iface]; 00117 } 00118 return result->second; 00119 } 00120 00125 static void Release(DataFlowInterface* iface) { 00126 DispatchMap::iterator result = DispatchI.find(iface); 00127 if ( result != DispatchI.end() ) { 00128 os::MutexLock lock(*mlock); 00129 delete result->second; 00130 DispatchI.erase(result); 00131 } 00132 if ( DispatchI.empty() ) 00133 delete mlock; 00134 mlock = 0; 00135 } 00136 00140 static void ReleaseAll() { 00141 DispatchMap::iterator result = DispatchI.begin(); 00142 while ( result != DispatchI.end() ) { 00143 delete result->second; 00144 DispatchI.erase(result); 00145 result = DispatchI.begin(); 00146 } 00147 delete mlock; 00148 mlock = 0; 00149 } 00150 00151 static void hasElement(base::ChannelElementBase::shared_ptr c0, base::ChannelElementBase::shared_ptr c1, bool& result) 00152 { 00153 result = result || (c0 == c1); 00154 } 00155 00156 void dispatchChannel( base::ChannelElementBase::shared_ptr chan ) { 00157 bool has_element = false; 00158 RClist.apply(boost::bind(&CorbaDispatcher::hasElement, _1, chan, boost::ref(has_element))); 00159 if (!has_element) 00160 RClist.append( chan ); 00161 this->trigger(); 00162 } 00163 00164 void cancelChannel( base::ChannelElementBase::shared_ptr chan ) { 00165 RClist.erase( chan ); 00166 } 00167 00168 bool initialize() { 00169 log(Info) <<"Started " << this->getName() << "." <<endlog(); 00170 do_exit = false; 00171 return true; 00172 } 00173 00174 void loop() { 00175 while ( !RClist.empty() && !do_exit) { 00176 base::ChannelElementBase::shared_ptr chan = RClist.front(); 00177 CRemoteChannelElement_i* rbase = dynamic_cast<CRemoteChannelElement_i*>(chan.get()); 00178 if (rbase) 00179 rbase->transferSamples(); 00180 RClist.erase( chan ); 00181 } 00182 } 00183 00184 bool breakLoop() { 00185 do_exit = true; 00186 return true; 00187 } 00188 }; 00189 } 00190 } 00191 #endif