--- /dev/null
+// Copyright (C) 2006-2014 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef __AUTOREFCNT_HXX__
+#define __AUTOREFCNT_HXX__
+
+#include "Exception.hxx"
+
+namespace YACS
+{
+ namespace BASES
+ {
+ template<class T>
+ class AutoRefCnt
+ {
+ public:
+ AutoRefCnt(const AutoRefCnt& other):_ptr(0) { referPtr(other._ptr); }
+ AutoRefCnt(T *ptr=0):_ptr(ptr) { }
+ ~AutoRefCnt() { destroyPtr(); }
+ bool operator==(const AutoRefCnt& other) const { return _ptr==other._ptr; }
+ bool operator==(const T *other) const { return _ptr==other; }
+ AutoRefCnt &operator=(const AutoRefCnt& other) { if(_ptr!=other._ptr) { destroyPtr(); referPtr(other._ptr); } return *this; }
+ AutoRefCnt &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; }
+ T *operator->() { return _ptr ; }
+ const T *operator->() const { return _ptr; }
+ T& operator*() { return *_ptr; }
+ const T& operator*() const { return *_ptr; }
+ operator T *() { return _ptr; }
+ operator const T *() const { return _ptr; }
+ T *retn() { if(_ptr) _ptr->incrRef(); return _ptr; }
+ private:
+ void referPtr(T *ptr) { _ptr=ptr; if(_ptr) _ptr->incrRef(); }
+ void destroyPtr() { if(_ptr) _ptr->decrRef(); }
+ private:
+ T *_ptr;
+ };
+
+ template<class T, class U>
+ typename YACS::BASES::AutoRefCnt<U> DynamicCast(typename YACS::BASES::AutoRefCnt<T>& autoSubPtr) throw()
+ {
+ T *subPtr(autoSubPtr);
+ U *ptr(dynamic_cast<U *>(subPtr));
+ typename YACS::BASES::AutoRefCnt<U> ret(ptr);
+ if(ptr)
+ ptr->incrRef();
+ return ret;
+ }
+
+ template<class T, class U>
+ typename YACS::BASES::AutoRefCnt<U> DynamicCastSafe(typename YACS::BASES::AutoRefCnt<T>& autoSubPtr)
+ {
+ T *subPtr(autoSubPtr);
+ U *ptr(dynamic_cast<U *>(subPtr));
+ if(subPtr && !ptr)
+ throw Exception("DynamicCastSafe : U is not a subtype of T !");
+ typename YACS::BASES::AutoRefCnt<U> ret(ptr);
+ if(ptr)
+ ptr->incrRef();
+ return ret;
+ }
+
+ template<class T>
+ class AutoCppPtr
+ {
+ public:
+ AutoCppPtr(T *ptr=0):_ptr(ptr) { }
+ ~AutoCppPtr() { destroyPtr(); }
+ AutoCppPtr &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; }
+ T *operator->() { return _ptr ; }
+ const T *operator->() const { return _ptr; }
+ T& operator*() { return *_ptr; }
+ const T& operator*() const { return *_ptr; }
+ operator T *() { return _ptr; }
+ operator const T *() const { return _ptr; }
+ private:
+ void destroyPtr() { delete _ptr; }
+ private:
+ T *_ptr;
+ };
+ }
+}
+
+#endif
#include "Executor.hxx"
#include "Task.hxx"
+#include "AutoLocker.hxx"
#include "Scheduler.hxx"
#include "Dispatcher.hxx"
#include "Container.hxx"
if(debug>2)_displayDot(graph);
{//Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
tasks=graph->getNextTasks(isMore);
graph->selectRunnableTasks(tasks);
- _mutexForSchedulerUpdate.unlock();
}//End of critical section
if(debug>2)_displayDot(graph);
if(debug>1)_displayDot(graph);
{//Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_toContinue=!graph->isFinished();
- _mutexForSchedulerUpdate.unlock();
}//End of critical section
DEBTRACE("_toContinue: " << _toContinue);
DEBTRACE("Executor::RunB debug: "<< graph->getName() <<" "<< debug<<" fromScratch: "<<fromScratch);
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_mainSched = graph;
_root = dynamic_cast<ComposedNode *>(_mainSched);
if (!_root) throw Exception("Executor::Run, Internal Error!");
gettimeofday(&_start, NULL);
#endif
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
if (debug > 1) _displayDot(graph);
DEBTRACE("--- events...");
if (debug > 2) _displayDot(graph);
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_tasks=graph->getNextTasks(isMore);
numberAllTasks=_numberOfRunningTasks+_tasks.size();
graph->selectRunnableTasks(_tasks);
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
if (debug > 2) _displayDot(graph);
if (_executorState == YACS::RUNNING)
if (debug > 1) _displayDot(graph);
{ // --- Critical section
DEBTRACE("---");
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
//It is possible that the graph is finished but it remains running tasks (it's an error but we must take it into account)
if(_numberOfRunningTasks == 0)
_toContinue = !graph->isFinished();
sendEvent("executor");
_condForPilot.notify_all();
}
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
if (debug > 0) _displayDot(graph);
DEBTRACE("_toContinue: " << _toContinue);
DEBTRACE("End of main Loop");
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
if ( _toContinue) // --- break while(): request to stop detected on checkBreakPoints()
{
DEBTRACE("stop requested: End soon");
_toContinue = false;
sendEvent("executor");
}
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
if ( _dumpOnErrorRequested && _errorDetected)
{
void Executor::setStopOnError(bool dumpRequested, std::string xmlFile)
{
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_dumpErrorFile=xmlFile;
_stopOnErrorRequested=true;
_dumpOnErrorRequested = dumpRequested;
if (dumpRequested && xmlFile.empty())
throw YACS::Exception("dump on error requested and no filename given for dump");
- _mutexForSchedulerUpdate.unlock();
DEBTRACE("_dumpErrorFile " << _dumpErrorFile << " " << _dumpOnErrorRequested);
} // --- End of critical section
}
void Executor::unsetStopOnError()
{
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_stopOnErrorRequested=false;
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
}
{
DEBTRACE("Executor::setExecMode(YACS::ExecutionMode mode) " << mode);
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_isRunningunderExternalControl=true;
_execMode = mode;
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
}
bool ret = false;
//bool doDump = false;
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_isRunningunderExternalControl=true;
DEBTRACE("_executorState: " << _executorState);
switch (_executorState)
// debug: no easy way to verify if main loop is acutally waiting on condition
}
}
- _mutexForSchedulerUpdate.unlock();
DEBTRACE("---");
//if (doDump) saveState(_dumpErrorFile);
} // --- End of critical section
{
DEBTRACE("Executor::setListOfBreakPoints(std::list<std::string> listOfBreakPoints)");
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_isRunningunderExternalControl=true;
_listOfBreakPoints = listOfBreakPoints;
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
}
list<string> listOfNodesToLoad;
listOfNodesToLoad.clear();
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_isRunningunderExternalControl=true;
switch (_executorState)
{
break;
}
}
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
return listOfNodesToLoad;
}
vector<Task *>::iterator iter;
vector<Task *> restrictedTasks;
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_isRunningunderExternalControl=true;
switch (_executorState)
{
break;
}
}
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
_tasks.clear();
{
DEBTRACE("Executor::waitPause()" << _executorState);
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_isRunningunderExternalControl=true;
switch (_executorState)
{
break;
}
}
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
DEBTRACE("---");
}
{
bool stop = false;
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_tasksSave = _tasks;
for (iter=_tasks.begin(); iter!=_tasks.end(); iter++)
{
sendEvent("executor");
_condForPilot.notify_all();
}
- //_mutexForSchedulerUpdate.unlock();
- //} // --- End of critical section
if (stop && !_isOKToEnd) waitResume(); // wait until pilot calls resumeCurrentBreakPoint(), mutex released during wait
if (_isOKToEnd) endRequested = true;
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
if (stop) DEBTRACE("wake up from waitResume");
break;
case YACS::STEPBYSTEP:
{
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_tasksSave = _tasks;
_listOfTasksToLoad.clear();
for (iter=_tasks.begin(); iter!=_tasks.end(); iter++)
waitResume(); // wait until pilot calls resumeCurrentBreakPoint(), mutex released during wait
// or, if no pilot, wait until no more running tasks (stop on error)
if (_isOKToEnd) endRequested = true;
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
DEBTRACE("wake up from waitResume");
break;
if(task->getState() != YACS::TOLOAD)return;
traceExec(task, "state:TOLOAD");
{//Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_mainSched->notifyFrom(task,YACS::START);
- _mutexForSchedulerUpdate.unlock();
}//End of critical section
try
{
{
std::cerr << ex.what() << std::endl;
{//Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
task->aborted();
_mainSched->notifyFrom(task,YACS::ABORT);
traceExec(task, "state:"+Node::getStateName(task->getState()));
- _mutexForSchedulerUpdate.unlock();
}//End of critical section
}
catch(...)
{
std::cerr << "Load failed" << std::endl;
{//Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
task->aborted();
_mainSched->notifyFrom(task,YACS::ABORT);
traceExec(task, "state:"+Node::getStateName(task->getState()));
- _mutexForSchedulerUpdate.unlock();
}//End of critical section
}
}
(*iter)->connectService();
traceExec(*iter, "connectService");
{//Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
(*iter)->connected();
- _mutexForSchedulerUpdate.unlock();
}//End of critical section
}
catch(Exception& ex)
traceExec(*iter, "disconnectService failed, ABORT");
}
{//Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
(*iter)->aborted();
_mainSched->notifyFrom(*iter,YACS::ABORT);
- _mutexForSchedulerUpdate.unlock();
}//End of critical section
}
catch(...)
traceExec(*iter, "disconnectService failed, ABORT");
}
{//Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
(*iter)->aborted();
_mainSched->notifyFrom(*iter,YACS::ABORT);
- _mutexForSchedulerUpdate.unlock();
}//End of critical section
}
if((*iter)->getState() == YACS::ERROR)
traceExec(t, "disconnectService failed, ABORT");
}
{//Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
t->aborted();
_mainSched->notifyFrom(t,YACS::ABORT);
- _mutexForSchedulerUpdate.unlock();
}//End of critical section
traceExec(t, "state:"+Node::getStateName(t->getState()));
}
traceExec(task, "launch");
{ // --- Critical section
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
_numberOfRunningTasks++;
_runningTasks.insert(task);
task->begin(); //change state to ACTIVATED
- _mutexForSchedulerUpdate.unlock();
} // --- End of critical section
Thread(functionForTaskExecution, args, _threadStackSize);
}
{
DEBTRACE("Executor::sleepWhileNoEventsFromAnyRunningTask()");
// _semForNewTasksToPerform.wait(); //----utiliser pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
- _mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate);
if (_numberOfRunningTasks > 0 && _numberOfEndedTasks==0)
{
_isWaitingEventsFromRunningTasks = true;
_condForNewTasksToPerform.wait(_mutexForSchedulerUpdate); // mutex released during wait
}
_numberOfEndedTasks=0;
- _mutexForSchedulerUpdate.unlock();
DEBTRACE("---");
}
int Executor::getNbOfThreads()
{
int ret;
- _mutexForNbOfConcurrentThreads.lock();
+ YACS::BASES::AutoLocker alck(&_mutexForNbOfConcurrentThreads);
_isRunningunderExternalControl=true;
ret = _groupOfAllThreadsCreated.size();
- _mutexForNbOfConcurrentThreads.unlock();
return ret;
}
DEBTRACE("End task->execute()");
{ // --- Critical section
- execInst->_mutexForSchedulerUpdate.lock();
+ YACS::BASES::AutoLocker alck(&execInst->_mutexForSchedulerUpdate);
try
{
if (ev == YACS::FINISH) task->finished();
DEBTRACE("after _semForMaxThreads.post " << execInst->_semThreadCnt);
if (execInst->_executorState != YACS::PAUSED) execInst->wakeUp();
- execInst->_mutexForSchedulerUpdate.unlock();
} // --- End of critical section (change state)
//execInst->notifyEndOfThread(0);
gettimeofday(&now, NULL);
double elapse = (now.tv_sec - _start.tv_sec) + double(now.tv_usec - _start.tv_usec)/1000000.0;
#endif
- _mutexForTrace.lock();
- _trace << elapse << " " << containerName << " " << placement << " " << nodeName << " " << message << endl;
- _trace << flush;
- _mutexForTrace.unlock();
+ {
+ YACS::BASES::AutoLocker alck(&_mutexForTrace);
+ _trace << elapse << " " << containerName << " " << placement << " " << nodeName << " " << message << endl;
+ _trace << flush;
+ }
}
//! emit notification to all observers registered with the dispatcher