00001 /*************************************************************************** 00002 tag: Peter Soetens Thu Oct 22 11:59:08 CEST 2009 SequentialActivity.cpp 00003 00004 SequentialActivity.cpp - 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 #include "SequentialActivity.hpp" 00040 #include "../os/MainThread.hpp" 00041 #include "../os/MutexLock.hpp" 00042 00043 namespace RTT { 00044 using namespace extras; 00045 using namespace base; 00046 00047 SequentialActivity::SequentialActivity( RunnableInterface* run /*= 0*/ ) 00048 : ActivityInterface(run), running(false), active(false) 00049 { 00050 } 00051 00052 SequentialActivity::~SequentialActivity() 00053 { 00054 stop(); 00055 } 00056 00057 Seconds SequentialActivity::getPeriod() const 00058 { 00059 return 0.0; 00060 } 00061 00062 bool SequentialActivity::setPeriod(Seconds s) { 00063 if ( s == 0.0) 00064 return true; 00065 return false; 00066 } 00067 00068 unsigned SequentialActivity::getCpuAffinity() const 00069 { 00070 return ~0; 00071 } 00072 00073 bool SequentialActivity::setCpuAffinity(unsigned cpu) 00074 { 00075 return false; 00076 } 00077 00078 os::ThreadInterface* SequentialActivity::thread() 00079 { 00080 return os::MainThread::Instance(); 00081 } 00082 00083 bool SequentialActivity::initialize() 00084 { 00085 return true; 00086 } 00087 00088 void SequentialActivity::step() 00089 { 00090 } 00091 00092 bool SequentialActivity::breakLoop() 00093 { 00094 return false; 00095 } 00096 00097 00098 void SequentialActivity::finalize() 00099 { 00100 } 00101 00102 bool SequentialActivity::start() 00103 { 00104 if (active == true ) 00105 return false; 00106 00107 active = true; 00108 00109 if ( runner ? runner->initialize() : this->initialize() ) { 00110 } else { 00111 active = false; 00112 } 00113 return active; 00114 } 00115 00116 00117 bool SequentialActivity::stop() 00118 { 00119 if ( !active ) 00120 return false; 00121 00122 if (runner) 00123 runner->finalize(); 00124 else 00125 this->finalize(); 00126 active = false; 00127 return true; 00128 } 00129 00130 bool SequentialActivity::isRunning() const 00131 { 00132 return running; 00133 } 00134 00135 bool SequentialActivity::isPeriodic() const 00136 { 00137 return false; 00138 } 00139 00140 bool SequentialActivity::isActive() const 00141 { 00142 return active; 00143 } 00144 00145 bool SequentialActivity::trigger() 00146 { 00147 // This function may recurse, in which case it returns true. 00148 // We could also rely on the MutexTryLock to fail, but in 00149 // case an OS only has recursive mutexes, we'd need to 00150 // check running anyway before calling runner->step(). So 00151 // we moved that piece of code up front. 00152 // The other thread will complete the work. (hasWork). 00153 if (running) 00154 return true; 00155 if ( active ) { 00156 bool did_step = false; 00157 do { 00158 os::MutexTryLock lock(execution_lock); 00159 if ( lock.isSuccessful() ) { 00160 running = true; 00161 if (runner) runner->step(); else this->step(); 00162 running = false; 00163 did_step = true; 00164 } else { 00165 // nop: step() is already being executed and 00166 // should notice that new data is there. 00167 // race: step() returns and trigger is called-> 00168 // trigger is ignored. 00169 return true; 00170 } 00171 // mutex unlocked here. 00172 } // if the runner signals work again (ie a race occured), 00173 // rety to lock. 00174 while ( did_step && runner->hasWork() ); 00175 return true; 00176 } 00177 return false; 00178 } 00179 00180 bool SequentialActivity::execute() 00181 { 00182 return false; 00183 } 00184 00185 00186 }