From ffe2d7da964403fe2edd542d509a31e65b82e7b5 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Mon, 4 Aug 2014 15:28:37 +0200 Subject: [PATCH] First test qui HPsalome container is running. --- src/bases/AutoLocker.hxx | 8 +- src/bases/Mutex.hxx | 6 - src/bases/MutexPT.cxx | 2 +- src/bases/MutexPT.hxx | 2 +- src/bases/Test/basesTest.cxx | 8 +- src/engine/AnyInputPort.cxx | 10 +- src/engine/AnyOutputPort.cxx | 7 +- src/engine/Executor.cxx | 196 ++++++++++++++++-------- src/engine/Executor.hxx | 4 +- src/engine/HomogeneousPoolContainer.hxx | 6 +- src/engine/RefCounter.cxx | 8 +- src/engine/RefCounter.hxx | 1 + src/engine_swig/engtypemaps.i | 12 ++ src/engine_swig/pilot.i | 10 ++ src/engine_swig/pypilot.i | 1 + src/runtime/CORBANode.cxx | 3 +- src/runtime/CORBAPorts.cxx | 9 +- src/runtime/CppContainer.cxx | 10 +- src/runtime/SalomeComponent.cxx | 30 +++- src/runtime/SalomeContainer.cxx | 16 +- src/runtime/SalomeContainer.hxx | 3 + src/runtime/SalomeContainerHelper.hxx | 7 +- src/runtime/SalomeHPContainer.cxx | 6 +- src/runtime/SalomeHPContainer.hxx | 9 +- src/runtime/SalomeHPContainerTools.cxx | 2 +- src/runtime/SalomeHPContainerTools.hxx | 2 +- src/runtime/XMLNode.cxx | 26 ++-- src/yacsloader_swig/loader.i | 1 + 28 files changed, 279 insertions(+), 126 deletions(-) diff --git a/src/bases/AutoLocker.hxx b/src/bases/AutoLocker.hxx index fe7862ad2..8960361ea 100644 --- a/src/bases/AutoLocker.hxx +++ b/src/bases/AutoLocker.hxx @@ -21,19 +21,19 @@ #define __AUTOLOCKER_HXX__ #include "Exception.hxx" -#include "Mutex.hxx" namespace YACS { namespace BASES { + template class AutoLocker { public: - AutoLocker(Mutex *m):_ptr(m) { _ptr->lock(); } - ~AutoLocker() { _ptr->unlock(); } + AutoLocker(T *m):_ptr(m) { _ptr->lock(); } + ~AutoLocker() { _ptr->unLock(); } private: - Mutex *_ptr; + T *_ptr; }; } } diff --git a/src/bases/Mutex.hxx b/src/bases/Mutex.hxx index 0dcf0a1fc..997d02b9b 100644 --- a/src/bases/Mutex.hxx +++ b/src/bases/Mutex.hxx @@ -49,12 +49,6 @@ namespace YACS { typedef MutexPT Mutex; typedef ConditionPT Condition; - struct Lock - { - YACS::BASES::Mutex * _mutex; - Lock(YACS::BASES::Mutex * mutex) : _mutex(mutex) {_mutex->lock();}; - ~Lock() {_mutex->unlock();}; - }; } } #else diff --git a/src/bases/MutexPT.cxx b/src/bases/MutexPT.cxx index 5d94acc9e..97aecb0a5 100644 --- a/src/bases/MutexPT.cxx +++ b/src/bases/MutexPT.cxx @@ -38,7 +38,7 @@ void MutexPT::lock() pthread_mutex_lock(&_mutexDesc); } -void MutexPT::unlock() +void MutexPT::unLock() { pthread_mutex_unlock(&_mutexDesc); } diff --git a/src/bases/MutexPT.hxx b/src/bases/MutexPT.hxx index cbe22aa4d..af9a73e19 100644 --- a/src/bases/MutexPT.hxx +++ b/src/bases/MutexPT.hxx @@ -36,7 +36,7 @@ namespace YACS MutexPT(); ~MutexPT(); void lock(); - void unlock(); + void unLock(); friend class ConditionPT; private: pthread_mutex_t _mutexDesc; diff --git a/src/bases/Test/basesTest.cxx b/src/bases/Test/basesTest.cxx index 544ff6e03..056cf2d1e 100644 --- a/src/bases/Test/basesTest.cxx +++ b/src/bases/Test/basesTest.cxx @@ -86,7 +86,7 @@ void *BasesTest::th2_1(void *) tmp = tmp+1; Thread::sleep(1000); _value = tmp; - _m.unlock(); + _m.unLock(); Thread::sleep(100000); } return 0; @@ -120,7 +120,7 @@ void BasesTest::get_resources(int id, int amount) } _resources -= amount; _ownedResources[id] = amount; - _m.unlock(); + _m.unLock(); } void BasesTest::free_resources(int id, int amount) @@ -133,7 +133,7 @@ void BasesTest::free_resources(int id, int amount) _waiting = 0; _cond.notify_all(); } - _m.unlock(); + _m.unLock(); } int BasesTest::count_resources() @@ -147,7 +147,7 @@ int BasesTest::count_resources() { totOwned += _ownedResources[i]; } - _m.unlock(); + _m.unLock(); } int total = resources + totOwned; DEBTRACE("resources:: owned by threads: " << totOwned << " remaining: " << resources << " total: " << total); diff --git a/src/engine/AnyInputPort.cxx b/src/engine/AnyInputPort.cxx index dceb3b476..f204b5cb8 100644 --- a/src/engine/AnyInputPort.cxx +++ b/src/engine/AnyInputPort.cxx @@ -19,13 +19,15 @@ #include "AnyInputPort.hxx" #include "TypeCode.hxx" -#include -#include #include "Mutex.hxx" +#include "AutoLocker.hxx" //#define _DEVDEBUG_ #include "YacsTrace.hxx" +#include +#include + using namespace YACS::ENGINE; using namespace std; @@ -83,7 +85,7 @@ void AnyInputPort::exRestoreInit() void AnyInputPort::put(Any *data) { - YACS::BASES::Lock lock(&_mutex); + YACS::BASES::AutoLocker lock(&_mutex); if(_value) _value->decrRef(); _value=data; @@ -105,7 +107,7 @@ void *AnyInputPort::get() const std::string AnyInputPort::getAsString() { - YACS::BASES::Lock lock(&_mutex); + YACS::BASES::AutoLocker lock(&_mutex); return getRuntime()->convertNeutralAsString(edGetType(),_value); } diff --git a/src/engine/AnyOutputPort.cxx b/src/engine/AnyOutputPort.cxx index 792b487b5..cdd7ccac1 100644 --- a/src/engine/AnyOutputPort.cxx +++ b/src/engine/AnyOutputPort.cxx @@ -18,8 +18,9 @@ // #include "AnyOutputPort.hxx" -#include "Any.hxx" +#include "AutoLocker.hxx" #include "Runtime.hxx" +#include "Any.hxx" //#define _DEVDEBUG_ #include "YacsTrace.hxx" @@ -47,7 +48,7 @@ AnyOutputPort::~AnyOutputPort() //! store the current dispatched value void AnyOutputPort::setValue(Any *data) { - YACS::BASES::Lock lock(&_mutex); + YACS::BASES::AutoLocker lock(&_mutex); if(_data) _data->decrRef(); _data = data; @@ -73,6 +74,6 @@ void AnyOutputPort::put(YACS::ENGINE::Any *data) throw(ConversionException) std::string AnyOutputPort::getAsString() { - YACS::BASES::Lock lock(&_mutex); + YACS::BASES::AutoLocker lock(&_mutex); return getRuntime()->convertNeutralAsString(edGetType(),_data); } diff --git a/src/engine/Executor.cxx b/src/engine/Executor.cxx index 0e3830c8d..799fe96e7 100644 --- a/src/engine/Executor.cxx +++ b/src/engine/Executor.cxx @@ -23,6 +23,7 @@ #include "Scheduler.hxx" #include "Dispatcher.hxx" #include "Container.hxx" +#include "HomogeneousPoolContainer.hxx" #include "ComponentInstance.hxx" #include "VisitorSaveState.hxx" @@ -138,7 +139,7 @@ void Executor::RunA(Scheduler *graph,int debug, bool fromScratch) if(debug>2)_displayDot(graph); {//Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); tasks=graph->getNextTasks(isMore); graph->selectRunnableTasks(tasks); }//End of critical section @@ -155,7 +156,7 @@ void Executor::RunA(Scheduler *graph,int debug, bool fromScratch) if(debug>1)_displayDot(graph); {//Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _toContinue=!graph->isFinished(); }//End of critical section DEBTRACE("_toContinue: " << _toContinue); @@ -232,7 +233,7 @@ void Executor::RunB(Scheduler *graph,int debug, bool fromScratch) DEBTRACE("Executor::RunB debug: "<< graph->getName() <<" "<< debug<<" fromScratch: "< alck(&_mutexForSchedulerUpdate); _mainSched = graph; _root = dynamic_cast(_mainSched); if (!_root) throw Exception("Executor::Run, Internal Error!"); @@ -292,10 +293,11 @@ void Executor::RunB(Scheduler *graph,int debug, bool fromScratch) DEBTRACE("--- events..."); if (debug > 2) _displayDot(graph); { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _tasks=graph->getNextTasks(isMore); numberAllTasks=_numberOfRunningTasks+_tasks.size(); graph->selectRunnableTasks(_tasks); + FilterTasksConsideringContainers(_tasks); } // --- End of critical section if (debug > 2) _displayDot(graph); if (_executorState == YACS::RUNNING) @@ -313,7 +315,7 @@ void Executor::RunB(Scheduler *graph,int debug, bool fromScratch) if (debug > 1) _displayDot(graph); { // --- Critical section DEBTRACE("---"); - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + 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(); @@ -349,7 +351,7 @@ void Executor::RunB(Scheduler *graph,int debug, bool fromScratch) DEBTRACE("End of main Loop"); { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); if ( _toContinue) // --- break while(): request to stop detected on checkBreakPoints() { DEBTRACE("stop requested: End soon"); @@ -395,7 +397,7 @@ bool Executor::isNotFinished() void Executor::setStopOnError(bool dumpRequested, std::string xmlFile) { { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _dumpErrorFile=xmlFile; _stopOnErrorRequested=true; _dumpOnErrorRequested = dumpRequested; @@ -412,7 +414,7 @@ void Executor::setStopOnError(bool dumpRequested, std::string xmlFile) void Executor::unsetStopOnError() { { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _stopOnErrorRequested=false; } // --- End of critical section } @@ -427,7 +429,7 @@ void Executor::setExecMode(YACS::ExecutionMode mode) { DEBTRACE("Executor::setExecMode(YACS::ExecutionMode mode) " << mode); { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _isRunningunderExternalControl=true; _execMode = mode; } // --- End of critical section @@ -447,7 +449,7 @@ bool Executor::resumeCurrentBreakPoint() bool ret = false; //bool doDump = false; { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _isRunningunderExternalControl=true; DEBTRACE("_executorState: " << _executorState); switch (_executorState) @@ -488,7 +490,7 @@ void Executor::setListOfBreakPoints(std::list listOfBreakPoints) { DEBTRACE("Executor::setListOfBreakPoints(std::list listOfBreakPoints)"); { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _isRunningunderExternalControl=true; _listOfBreakPoints = listOfBreakPoints; } // --- End of critical section @@ -506,7 +508,7 @@ std::list Executor::getTasksToLoad() list listOfNodesToLoad; listOfNodesToLoad.clear(); { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _isRunningunderExternalControl=true; switch (_executorState) { @@ -545,7 +547,7 @@ bool Executor::setStepsToExecute(std::list listToExecute) vector::iterator iter; vector restrictedTasks; { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _isRunningunderExternalControl=true; switch (_executorState) { @@ -605,7 +607,7 @@ void Executor::waitPause() { DEBTRACE("Executor::waitPause()" << _executorState); { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _isRunningunderExternalControl=true; switch (_executorState) { @@ -723,7 +725,7 @@ bool Executor::checkBreakPoints() { bool stop = false; { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _tasksSave = _tasks; for (iter=_tasks.begin(); iter!=_tasks.end(); iter++) { @@ -760,7 +762,7 @@ bool Executor::checkBreakPoints() case YACS::STEPBYSTEP: { { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _tasksSave = _tasks; _listOfTasksToLoad.clear(); for (iter=_tasks.begin(); iter!=_tasks.end(); iter++) @@ -812,36 +814,36 @@ void Executor::loadTask(Task *task) { DEBTRACE("Executor::loadTask(Task *task)"); if(task->getState() != YACS::TOLOAD)return; - traceExec(task, "state:TOLOAD"); + traceExec(task, "state:TOLOAD", ComputePlacement(task)); {//Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _mainSched->notifyFrom(task,YACS::START); }//End of critical section try { - traceExec(task, "load"); + traceExec(task, "load", ComputePlacement(task)); task->load(); - traceExec(task, "initService"); + traceExec(task, "initService", ComputePlacement(task)); task->initService(); } catch(Exception& ex) { std::cerr << ex.what() << std::endl; {//Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); task->aborted(); _mainSched->notifyFrom(task,YACS::ABORT); - traceExec(task, "state:"+Node::getStateName(task->getState())); + traceExec(task, "state:"+Node::getStateName(task->getState()), ComputePlacement(task)); }//End of critical section } catch(...) { std::cerr << "Load failed" << std::endl; {//Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); task->aborted(); _mainSched->notifyFrom(task,YACS::ABORT); - traceExec(task, "state:"+Node::getStateName(task->getState())); + traceExec(task, "state:"+Node::getStateName(task->getState()), ComputePlacement(task)); }//End of critical section } } @@ -863,9 +865,9 @@ void Executor::launchTasks(std::vector& tasks) try { (*iter)->connectService(); - traceExec(*iter, "connectService"); + traceExec(*iter, "connectService",ComputePlacement(*iter)); {//Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); (*iter)->connected(); }//End of critical section } @@ -875,15 +877,15 @@ void Executor::launchTasks(std::vector& tasks) try { (*iter)->disconnectService(); - traceExec(*iter, "disconnectService"); + traceExec(*iter, "disconnectService",ComputePlacement(*iter)); } catch(...) { // Disconnect has failed - traceExec(*iter, "disconnectService failed, ABORT"); + traceExec(*iter, "disconnectService failed, ABORT",ComputePlacement(*iter)); } {//Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); (*iter)->aborted(); _mainSched->notifyFrom(*iter,YACS::ABORT); }//End of critical section @@ -894,15 +896,15 @@ void Executor::launchTasks(std::vector& tasks) try { (*iter)->disconnectService(); - traceExec(*iter, "disconnectService"); + traceExec(*iter, "disconnectService",ComputePlacement(*iter)); } catch(...) { // Disconnect has failed - traceExec(*iter, "disconnectService failed, ABORT"); + traceExec(*iter, "disconnectService failed, ABORT",ComputePlacement(*iter)); } {//Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); (*iter)->aborted(); _mainSched->notifyFrom(*iter,YACS::ABORT); }//End of critical section @@ -920,22 +922,22 @@ void Executor::launchTasks(std::vector& tasks) try { t->disconnectService(); - traceExec(t, "disconnectService"); + traceExec(t, "disconnectService",ComputePlacement(*iter)); } catch(...) { // Disconnect has failed - traceExec(t, "disconnectService failed, ABORT"); + traceExec(t, "disconnectService failed, ABORT",ComputePlacement(*iter)); } {//Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); t->aborted(); _mainSched->notifyFrom(t,YACS::ABORT); }//End of critical section - traceExec(t, "state:"+Node::getStateName(t->getState())); + traceExec(t, "state:"+Node::getStateName(t->getState()),ComputePlacement(*iter)); } } - traceExec(*iter, "state:"+Node::getStateName((*iter)->getState())); + traceExec(*iter, "state:"+Node::getStateName((*iter)->getState()),ComputePlacement(*iter)); } //Second phase, execute each task in a thread @@ -1004,10 +1006,10 @@ void Executor::launchTask(Task *task) args->sched = _mainSched; args->execInst = this; - traceExec(task, "launch"); + traceExec(task, "launch",ComputePlacement(task)); { // --- Critical section - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); _numberOfRunningTasks++; _runningTasks.insert(task); task->begin(); //change state to ACTIVATED @@ -1021,7 +1023,7 @@ void Executor::sleepWhileNoEventsFromAnyRunningTask() { DEBTRACE("Executor::sleepWhileNoEventsFromAnyRunningTask()"); // _semForNewTasksToPerform.wait(); //----utiliser pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); - YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&_mutexForSchedulerUpdate); if (_numberOfRunningTasks > 0 && _numberOfEndedTasks==0) { _isWaitingEventsFromRunningTasks = true; @@ -1061,7 +1063,7 @@ void Executor::wakeUp() int Executor::getNbOfThreads() { int ret; - YACS::BASES::AutoLocker alck(&_mutexForNbOfConcurrentThreads); + YACS::BASES::AutoLocker alck(&_mutexForNbOfConcurrentThreads); _isRunningunderExternalControl=true; ret = _groupOfAllThreadsCreated.size(); return ret; @@ -1090,7 +1092,7 @@ void *Executor::functionForTaskExecution(void *arg) Scheduler *sched=args->sched; Executor *execInst=args->execInst; delete args; - execInst->traceExec(task, "state:"+Node::getStateName(task->getState())); + execInst->traceExec(task, "state:"+Node::getStateName(task->getState()),ComputePlacement(task)); Thread::detach(); @@ -1099,9 +1101,9 @@ void *Executor::functionForTaskExecution(void *arg) YACS::Event ev=YACS::FINISH; try { - execInst->traceExec(task, "start execution"); + execInst->traceExec(task, "start execution",ComputePlacement(task)); task->execute(); - execInst->traceExec(task, "end execution OK"); + execInst->traceExec(task, "end execution OK",ComputePlacement(task)); } catch(Exception& ex) { @@ -1110,14 +1112,14 @@ void *Executor::functionForTaskExecution(void *arg) ev=YACS::ABORT; string message = "end execution ABORT, "; message += ex.what(); - execInst->traceExec(task, message); + execInst->traceExec(task, message,ComputePlacement(task)); } catch(...) { // Execution has failed std::cerr << "Execution has failed: unknown reason" << std::endl; ev=YACS::ABORT; - execInst->traceExec(task, "end execution ABORT, unknown reason"); + execInst->traceExec(task, "end execution ABORT, unknown reason",ComputePlacement(task)); } // Disconnect task @@ -1125,19 +1127,31 @@ void *Executor::functionForTaskExecution(void *arg) { DEBTRACE("task->disconnectService()"); task->disconnectService(); - execInst->traceExec(task, "disconnectService"); + execInst->traceExec(task, "disconnectService",ComputePlacement(task)); } catch(...) { // Disconnect has failed std::cerr << "disconnect has failed" << std::endl; ev=YACS::ABORT; - execInst->traceExec(task, "disconnectService failed, ABORT"); + execInst->traceExec(task, "disconnectService failed, ABORT",ComputePlacement(task)); + } + // + + std::string placement(ComputePlacement(task)); + + // container management for HomogeneousPoolOfContainer + + HomogeneousPoolContainer *contC(dynamic_cast(task->getContainer())); + if(contC) + { + YACS::BASES::AutoLocker alckCont(contC); + contC->release(task); } DEBTRACE("End task->execute()"); { // --- Critical section - YACS::BASES::AutoLocker alck(&execInst->_mutexForSchedulerUpdate); + YACS::BASES::AutoLocker alck(&execInst->_mutexForSchedulerUpdate); try { if (ev == YACS::FINISH) task->finished(); @@ -1151,7 +1165,7 @@ void *Executor::functionForTaskExecution(void *arg) } task->aborted(); } - execInst->traceExec(task, "state:"+Node::getStateName(task->getState())); + execInst->traceExec(task, "state:"+Node::getStateName(task->getState()),placement); sched->notifyFrom(task,ev); } catch(Exception& ex) @@ -1198,20 +1212,14 @@ void *Executor::functionForTaskExecution(void *arg) return 0; } -void Executor::traceExec(Task *task, const std::string& message) +void Executor::traceExec(Task *task, const std::string& message, const std::string& placement) { string nodeName = _mainSched->getTaskName(task); Container *cont = task->getContainer(); string containerName = "---"; - string placement = "---"; if (cont) - { - containerName = cont->getName(); - ComponentInstance *compo = task->getComponent(); - ServiceNode *taskCast(dynamic_cast(task)); - if(taskCast) - placement = cont->getFullPlacementId(taskCast); - } + containerName = cont->getName(); + #ifdef WIN32 DWORD now = timeGetTime(); double elapse = (now - _start)/1000.0; @@ -1221,7 +1229,7 @@ void Executor::traceExec(Task *task, const std::string& message) double elapse = (now.tv_sec - _start.tv_sec) + double(now.tv_usec - _start.tv_usec)/1000000.0; #endif { - YACS::BASES::AutoLocker alck(&_mutexForTrace); + YACS::BASES::AutoLocker alck(&_mutexForTrace); _trace << elapse << " " << containerName << " " << placement << " " << nodeName << " " << message << endl; _trace << flush; } @@ -1238,3 +1246,71 @@ void Executor::sendEvent(const std::string& event) YASSERT(_root); disp->dispatch(_root,event); } + +/*! + * This method takes in input a list of tasks and selects from that lists a part of it considering only the containers. + * If tasks have no container instance subclass of HomogeneousPoolContainer this method will let the \a tsks untouched. + * + * \param [in,out] tsks - list of tasks to be + */ +void Executor::FilterTasksConsideringContainers(std::vector& tsks) +{ + std::map > m; + for(std::vector::const_iterator it=tsks.begin();it!=tsks.end();it++) + { + Task *cur(*it); + if(!cur) + continue; + Container *cont(cur->getContainer()); + if(!cont) + { + m[(HomogeneousPoolContainer *)NULL].push_back(cur); + continue; + } + HomogeneousPoolContainer *contC(dynamic_cast(cont)); + if(!contC) + { + m[(HomogeneousPoolContainer *)NULL].push_back(cur); + continue; + } + m[contC].push_back(cur); + } + // + std::vector ret; + for(std::map >::const_iterator it=m.begin();it!=m.end();it++) + { + HomogeneousPoolContainer *curhpc((*it).first); + const std::vector& curtsks((*it).second); + if(!curhpc) + { + ret.insert(ret.end(),curtsks.begin(),curtsks.end()); + } + else + { + // start of critical section for container curhpc + YACS::BASES::AutoLocker alckForCont(curhpc); + std::vector vecOfTaskSharingSameHPContToBeRunSimutaneously; + std::size_t sz(curhpc->getNumberOfFreePlace()); + std::vector::const_iterator it2(curtsks.begin()); + for(std::size_t i=0;iallocateFor(vecOfTaskSharingSameHPContToBeRunSimutaneously); + //end of critical section + } + } + // + tsks=ret; +} + +std::string Executor::ComputePlacement(Task *zeTask) +{ + std::string placement("---"); + if(!zeTask) + return placement; + if(zeTask->getContainer()) + placement=zeTask->getContainer()->getFullPlacementId(zeTask); + return placement; +} diff --git a/src/engine/Executor.hxx b/src/engine/Executor.hxx index 90c25499d..3bac84b9f 100644 --- a/src/engine/Executor.hxx +++ b/src/engine/Executor.hxx @@ -123,9 +123,11 @@ namespace YACS void wakeUp(); void sleepWhileNoEventsFromAnyRunningTask(); void notifyEndOfThread(YACS::BASES::Thread *thread); - void traceExec(Task *task, const std::string& message); + void traceExec(Task *task, const std::string& message, const std::string& placement); void _displayDot(Scheduler *graph); virtual void sendEvent(const std::string& event); + static void FilterTasksConsideringContainers(std::vector& tsks); + static std::string ComputePlacement(Task *zeTask); protected: static void *functionForTaskExecution(void *); }; diff --git a/src/engine/HomogeneousPoolContainer.hxx b/src/engine/HomogeneousPoolContainer.hxx index 7ca663a7a..6ef5ce897 100644 --- a/src/engine/HomogeneousPoolContainer.hxx +++ b/src/engine/HomogeneousPoolContainer.hxx @@ -24,8 +24,7 @@ #include "Exception.hxx" #include "Container.hxx" -#include -#include +#include namespace YACS { @@ -39,6 +38,9 @@ namespace YACS { public: virtual void setSizeOfPool(int sz) = 0; + virtual std::size_t getNumberOfFreePlace() const = 0; + virtual void allocateFor(const std::vector& nodes) = 0; + virtual void release(const Task *node) = 0; protected: HomogeneousPoolContainer(); #ifndef SWIG diff --git a/src/engine/RefCounter.cxx b/src/engine/RefCounter.cxx index 93ce8dff0..f3b25dc5c 100644 --- a/src/engine/RefCounter.cxx +++ b/src/engine/RefCounter.cxx @@ -42,7 +42,7 @@ void RefCounter::incrRef() const RefCounter::_totalCnt++; #endif _cnt++; - _globalMutexForTS.unlock(); + _globalMutexForTS.unLock(); } bool RefCounter::decrRef() @@ -52,7 +52,7 @@ bool RefCounter::decrRef() RefCounter::_totalCnt--; #endif bool ret=(--_cnt==0); - _globalMutexForTS.unlock(); + _globalMutexForTS.unLock(); if(ret) delete this; return ret; @@ -65,6 +65,10 @@ RefCounter::RefCounter():_cnt(1) #endif } +RefCounter::RefCounter(const RefCounter& other):_cnt(1) +{ +} + RefCounter::~RefCounter() { #ifdef REFCNT diff --git a/src/engine/RefCounter.hxx b/src/engine/RefCounter.hxx index c2bb3236e..b02f59cbb 100644 --- a/src/engine/RefCounter.hxx +++ b/src/engine/RefCounter.hxx @@ -35,6 +35,7 @@ namespace YACS static unsigned int _totalCnt; protected: RefCounter(); + RefCounter(const RefCounter& other); virtual ~RefCounter(); protected: mutable unsigned int _cnt; diff --git a/src/engine_swig/engtypemaps.i b/src/engine_swig/engtypemaps.i index bad933f9c..d1a494ddd 100644 --- a/src/engine_swig/engtypemaps.i +++ b/src/engine_swig/engtypemaps.i @@ -80,6 +80,7 @@ catch (const CORBA::SystemException& ex) { \ #include "InputDataStreamPort.hxx" #include "OutputDataStreamPort.hxx" #include "OptimizerLoop.hxx" +#include "HomogeneousPoolContainer.hxx" class InterpreterUnlocker { @@ -205,6 +206,17 @@ static PyObject* convertPort(YACS::ENGINE::Port* port,int owner=0) return ob; } +static PyObject *convertContainer(YACS::ENGINE::Container *cont, int owner=0) +{ + if(!cont) + return SWIG_NewPointerObj((void*)cont,SWIGTYPE_p_YACS__ENGINE__Container, owner); + if(dynamic_cast(cont)) + { + return SWIG_NewPointerObj((void*)dynamic_cast(cont),SWIGTYPE_p_YACS__ENGINE__HomogeneousPoolContainer, owner); + } + return SWIG_NewPointerObj((void*)cont,SWIGTYPE_p_YACS__ENGINE__Container, owner); +} + %} #if SWIG_VERSION >= 0x010329 diff --git a/src/engine_swig/pilot.i b/src/engine_swig/pilot.i index 01bc22dc1..a9b18013c 100644 --- a/src/engine_swig/pilot.i +++ b/src/engine_swig/pilot.i @@ -127,10 +127,20 @@ REFCOUNT_TEMPLATE(CONTAINmap,YACS::ENGINE::Container) %template(propmap) std::map; REFCOUNT_TEMPLATE(CompoInstmap,YACS::ENGINE::ComponentInstance) + /* * End of Template section */ +%typemap(out) Container * +{ + $result=convertContainer($1,$owner); +} + +%typemap(out) YACS::ENGINE::Container * +{ + $result=convertContainer($1,$owner); +} /* * Ownership section diff --git a/src/engine_swig/pypilot.i b/src/engine_swig/pypilot.i index 52398d4c1..3a5da9fbb 100644 --- a/src/engine_swig/pypilot.i +++ b/src/engine_swig/pypilot.i @@ -121,6 +121,7 @@ namespace YACS %types(YACS::ENGINE::WhileLoop *,YACS::ENGINE::ForEachLoop *,YACS::ENGINE::ComposedNode *,YACS::ENGINE::InlineNode *); %types(YACS::ENGINE::InlineFuncNode *,YACS::ENGINE::ServiceInlineNode *,YACS::ENGINE::ServiceNode *); %types(YACS::ENGINE::ElementaryNode *); +%types(YACS::ENGINE::Container *, YACS::ENGINE::HomogeneousPoolContainer *); %types(YACS::ENGINE::InputPort *,YACS::ENGINE::OutputPort *,YACS::ENGINE::InPropertyPort *); %types(YACS::ENGINE::InputDataStreamPort *,YACS::ENGINE::OutputDataStreamPort *); diff --git a/src/runtime/CORBANode.cxx b/src/runtime/CORBANode.cxx index f38696f23..dc4f66528 100644 --- a/src/runtime/CORBANode.cxx +++ b/src/runtime/CORBANode.cxx @@ -35,6 +35,7 @@ #include "CalStreamPort.hxx" #include "InPort.hxx" #include "TypeCode.hxx" +#include "AutoLocker.hxx" #ifdef SALOME_KERNEL #include "SALOME_NamingService.hxx" @@ -467,7 +468,7 @@ void SalomeNode::disconnectService() { DEBTRACE( "SalomeNode::disconnectService: "< lock(&_mutex); if(ids.size() == 0) return; diff --git a/src/runtime/CORBAPorts.cxx b/src/runtime/CORBAPorts.cxx index ee14bd161..a45207757 100644 --- a/src/runtime/CORBAPorts.cxx +++ b/src/runtime/CORBAPorts.cxx @@ -29,6 +29,7 @@ #include "RuntimeSALOME.hxx" #include "TypeConversions.hxx" #include "TypeCode.hxx" +#include "AutoLocker.hxx" #include "CORBAPorts.hxx" #include "PythonPorts.hxx" #include "ServiceNode.hxx" @@ -165,7 +166,7 @@ void InputCorbaPort::put(CORBA::Any *data) throw (ConversionException) #ifdef REFCNT DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count); #endif - YACS::BASES::Lock lock(&_mutex); + YACS::BASES::AutoLocker lock(&_mutex); #ifdef _DEVDEBUG_ display(data); #endif @@ -207,7 +208,7 @@ CORBA::Any * InputCorbaPort::getAny() PyObject * InputCorbaPort::getPyObj() { - YACS::BASES::Lock lock(&_mutex); + YACS::BASES::AutoLocker lock(&_mutex); CORBA::TypeCode_var tc=getAny()->type(); if (!tc->equivalent(CORBA::_tc_null)) return convertCorbaPyObject(edGetType(),getAny()); @@ -318,7 +319,7 @@ void OutputCorbaPort::put(CORBA::Any *data) throw (ConversionException) InputPort *p; { - YACS::BASES::Lock lock(&_mutex); + YACS::BASES::AutoLocker lock(&_mutex); #ifdef REFCNT DEBTRACE("refcount CORBA : " << ((omni::TypeCode_base*)data->pd_tc.in())->pd_ref_count); #endif @@ -422,7 +423,7 @@ CORBA::Any * OutputCorbaPort::getAnyOut() PyObject * OutputCorbaPort::getPyObj() { - YACS::BASES::Lock lock(&_mutex); + YACS::BASES::AutoLocker lock(&_mutex); CORBA::TypeCode_var tc=getAny()->type(); if (!tc->equivalent(CORBA::_tc_null)) return convertCorbaPyObject(edGetType(),getAny()); diff --git a/src/runtime/CppContainer.cxx b/src/runtime/CppContainer.cxx index 54bcc1d51..18a330d9b 100644 --- a/src/runtime/CppContainer.cxx +++ b/src/runtime/CppContainer.cxx @@ -70,7 +70,7 @@ void CppContainer::lock() void CppContainer::unLock() { - _mutex.unlock(); + _mutex.unLock(); } bool CppContainer::isAlreadyStarted(const Task *askingNode) const @@ -205,7 +205,7 @@ void LocalContainer::destroy() delete iI->second; } _instance_map.clear(); - _instance_mapMutex.unlock(); // unlock + _instance_mapMutex.unLock(); // unlock // unload all dynamic libraries _library_mapMutex.lock(); @@ -213,7 +213,7 @@ void LocalContainer::destroy() for (iL=_library_map.begin(); iL != _library_map.end(); iL++) dlclose(iL->second.handle); _library_map.clear(); - _library_mapMutex.unlock(); + _library_mapMutex.unLock(); delete _singleton; _singleton = NULL; @@ -245,7 +245,7 @@ CppComponent * LocalContainer::createComponentInstance(const char * name) C = new CppComponent(o, r, t, name); _instance_mapMutex.lock(); // lock to be alone _instance_map.insert(std::pair(name, C)); - _instance_mapMutex.unlock(); // unlock + _instance_mapMutex.unLock(); // unlock return C; } @@ -275,7 +275,7 @@ void LocalContainer::unregisterComponentInstance(CppComponent * C) { _instance_mapMutex.lock(); // lock to be alone _instance_map.erase(C->getCompoName()); - _instance_mapMutex.unlock(); // unlock + _instance_mapMutex.unLock(); // unlock } inline void toupper (std::string & s) diff --git a/src/runtime/SalomeComponent.cxx b/src/runtime/SalomeComponent.cxx index b991f3846..ea1fbf053 100644 --- a/src/runtime/SalomeComponent.cxx +++ b/src/runtime/SalomeComponent.cxx @@ -20,7 +20,9 @@ #include "RuntimeSALOME.hxx" #include "SalomeComponent.hxx" #include "SalomeContainer.hxx" +#include "SalomeHPContainer.hxx" #include "CORBANode.hxx" +#include "AutoLocker.hxx" #ifdef SALOME_KERNEL #include "SALOME_NamingService.hxx" @@ -76,14 +78,32 @@ bool SalomeComponent::isLoaded(Task *askingNode) const return true; } -#ifdef SALOME_KERNEL +//#ifdef SALOME_KERNEL //! Load the component void SalomeComponent::load(Task *askingNode) { if(_container) { - _objComponent=((SalomeContainer*)_container)->loadComponent(askingNode); - return; + SalomeContainer *salomeContainer(dynamic_cast(_container)); + if(salomeContainer) + { + _objComponent=salomeContainer->loadComponent(askingNode); + return ; + } + SalomeHPContainer *salomeContainer2(dynamic_cast(_container)); + if(salomeContainer2) + { + SalomeContainerHelper *lmt(0); + { + YACS::BASES::AutoLocker altck(salomeContainer2); + lmt=salomeContainer2->getHelperOfTask(askingNode); + } + SalomeContainer tmpCont(*salomeContainer2,salomeContainer2->getContainerInfo(),lmt, + salomeContainer2->getComponentNames(),salomeContainer2->getShutdownLev()); + _objComponent=tmpCont.loadComponent(askingNode); + return ; + } + throw Exception("Unrecognized type of Container ! Only Salome and HPSalome container are supported by the Salome components !"); } //throw Exception("SalomeComponent::load : no container specified !!! To be implemented in executor to allocate default a Container in case of presenceOfDefaultContainer."); //This component has no specified container : use default container policy @@ -95,12 +115,12 @@ void SalomeComponent::load(Task *askingNode) params.container_name ="FactoryServer"; _objComponent=LCC.LoadComponent(params,_compoName.c_str()); } -#else +/*#else void SalomeComponent::load(Task *askingNode) { throw Exception("YACS has been built without SALOME support"); } -#endif +#endif*/ //! Create a ServiceNode with this component instance and no input or output port /*! diff --git a/src/runtime/SalomeContainer.cxx b/src/runtime/SalomeContainer.cxx index 38ec23235..849e7e5af 100644 --- a/src/runtime/SalomeContainer.cxx +++ b/src/runtime/SalomeContainer.cxx @@ -64,9 +64,17 @@ SalomeContainer::SalomeContainer(const SalomeContainer& other) { } +SalomeContainer::SalomeContainer(const Container& other, const SalomeContainerTools& sct, SalomeContainerHelper *lmt, + const std::vector& componentNames, int shutdownLev):Container(other),_componentNames(componentNames), + _launchModeType(lmt),_shutdownLevel(shutdownLev),_sct(sct) +{ + if(lmt) + lmt->incrRef(); +} + SalomeContainer::~SalomeContainer() { - delete _launchModeType; + _launchModeType->decrRef(); } void SalomeContainer::lock() @@ -76,7 +84,7 @@ void SalomeContainer::lock() void SalomeContainer::unLock() { - _mutex.unlock(); + _mutex.unLock(); } Container *SalomeContainer::clone() const @@ -107,12 +115,12 @@ void SalomeContainer::setProperty(const std::string& name, const std::string& va { if (value == SalomeContainerMonoHelper::TYPE_NAME) { - delete _launchModeType; + _launchModeType->decrRef(); _launchModeType=new SalomeContainerMonoHelper; } else if (value == SalomeContainerMultiHelper::TYPE_NAME) { - delete _launchModeType; + _launchModeType->decrRef(); _launchModeType=new SalomeContainerMultiHelper; } else diff --git a/src/runtime/SalomeContainer.hxx b/src/runtime/SalomeContainer.hxx index 5553e946e..2d07b7819 100644 --- a/src/runtime/SalomeContainer.hxx +++ b/src/runtime/SalomeContainer.hxx @@ -41,6 +41,9 @@ namespace YACS public: SalomeContainer(); SalomeContainer(const SalomeContainer& other); +#ifndef SWIG + SalomeContainer(const Container& other, const SalomeContainerTools& sct, SalomeContainerHelper *lmt, const std::vector& componentNames, int shutdownLev); +#endif //! For thread safety for concurrent load operation on same Container. void lock(); //! For thread safety for concurrent load operation on same Container. diff --git a/src/runtime/SalomeContainerHelper.hxx b/src/runtime/SalomeContainerHelper.hxx index aa301a90b..b14a78215 100644 --- a/src/runtime/SalomeContainerHelper.hxx +++ b/src/runtime/SalomeContainerHelper.hxx @@ -25,6 +25,8 @@ #include "SALOMEconfig.h" #include CORBA_CLIENT_HEADER(SALOME_Component) +#include "RefCounter.hxx" + #include #include @@ -35,7 +37,7 @@ namespace YACS class Task; class ComponentInstance; - class SalomeContainerHelper + class SalomeContainerHelper : public RefCounter { public: virtual std::string getType() const = 0; @@ -44,6 +46,7 @@ namespace YACS virtual bool isAlreadyStarted(const Task *askingNode) const = 0; virtual void setContainer(const Task *askingNode, Engines::Container_var cont) = 0; virtual void shutdown() = 0; + protected: virtual ~SalomeContainerHelper(); }; @@ -57,6 +60,7 @@ namespace YACS bool isAlreadyStarted(const Task *askingNode) const; void setContainer(const Task *askingNode, Engines::Container_var cont); void shutdown(); + private: ~SalomeContainerMonoHelper(); public: static const char TYPE_NAME[]; @@ -74,6 +78,7 @@ namespace YACS bool isAlreadyStarted(const Task *askingNode) const; void setContainer(const Task *askingNode, Engines::Container_var cont); void shutdown(); + private: ~SalomeContainerMultiHelper(); public: static const char TYPE_NAME[]; diff --git a/src/runtime/SalomeHPContainer.cxx b/src/runtime/SalomeHPContainer.cxx index cdc45e695..79a482ade 100644 --- a/src/runtime/SalomeHPContainer.cxx +++ b/src/runtime/SalomeHPContainer.cxx @@ -49,7 +49,7 @@ void SalomeHPContainer::allocateFor(const std::vector& nodes) _launchModeType.allocateFor(nodes); } -void SalomeHPContainer::release(Task *node) +void SalomeHPContainer::release(const Task *node) { _launchModeType.release(node); } @@ -65,7 +65,7 @@ void SalomeHPContainer::lock() void SalomeHPContainer::unLock() { - _mutex.unlock(); + _mutex.unLock(); } bool SalomeHPContainer::isAlreadyStarted(const Task *askingNode) const @@ -85,7 +85,7 @@ void SalomeHPContainer::shutdown(int level) if(level < _shutdownLevel) return; _shutdownLevel=999; - for(std::size_t i=0;_launchModeType.size();i++) + for(std::size_t i=0;i<_launchModeType.size();i++) { SalomeContainerMonoHelper *helper(_launchModeType.at(i)); helper->shutdown(); diff --git a/src/runtime/SalomeHPContainer.hxx b/src/runtime/SalomeHPContainer.hxx index 04457e08c..e3e536e26 100644 --- a/src/runtime/SalomeHPContainer.hxx +++ b/src/runtime/SalomeHPContainer.hxx @@ -49,7 +49,7 @@ namespace YACS void setSizeOfPool(int sz); std::size_t getNumberOfFreePlace() const; void allocateFor(const std::vector& nodes); - void release(Task *node); + void release(const Task *node); //! For thread safety for concurrent load operation on same Container. void lock(); //! For thread safety for concurrent load operation on same Container. @@ -70,7 +70,14 @@ namespace YACS std::map getResourceProperties(const std::string& name) const; void checkCapabilityToDealWith(const ComponentInstance *inst) const throw(YACS::Exception); // +#ifndef SWIG + const SalomeContainerTools &getContainerInfo() const { return _sct; } + std::vector getComponentNames() const { return _componentNames; } + int getShutdownLev() const { return _shutdownLevel; } + SalomeContainerMonoHelper *getHelperOfTask(const Task *node) { return _launchModeType.getHelperOfTask(node); } + // YACS::BASES::Mutex& getLocker() { return _mutex; } +#endif public: static const char KIND[]; protected: diff --git a/src/runtime/SalomeHPContainerTools.cxx b/src/runtime/SalomeHPContainerTools.cxx index 552aa1368..92d83d59a 100644 --- a/src/runtime/SalomeHPContainerTools.cxx +++ b/src/runtime/SalomeHPContainerTools.cxx @@ -94,7 +94,7 @@ void SalomeHPContainerVectOfHelper::checkNoCurrentWork() const for(std::map::const_iterator it=_currentlyWorking.begin();it!=_currentlyWorking.end();it++) if((*it).first) throw Exception("Something wrong a node is still declared to be using the ressource !"); - for(std::vector< YACS::BASES::AutoCppPtr >::const_iterator it=_launchModeType.begin();it!=_launchModeType.end();it++) + for(std::vector< YACS::BASES::AutoRefCnt >::const_iterator it=_launchModeType.begin();it!=_launchModeType.end();it++) if((*it)->isAlreadyStarted(0)) throw Exception("Some of the containers have be started ! Please shutdown them before !"); } diff --git a/src/runtime/SalomeHPContainerTools.hxx b/src/runtime/SalomeHPContainerTools.hxx index 1a1565cb0..d3beec092 100644 --- a/src/runtime/SalomeHPContainerTools.hxx +++ b/src/runtime/SalomeHPContainerTools.hxx @@ -53,7 +53,7 @@ namespace YACS void checkPosInVec(std::size_t pos) const; private: std::vector _whichOccupied; - std::vector< BASES::AutoCppPtr > _launchModeType; + std::vector< BASES::AutoRefCnt > _launchModeType; std::map _currentlyWorking; }; } diff --git a/src/runtime/XMLNode.cxx b/src/runtime/XMLNode.cxx index e25633875..e44a60a32 100644 --- a/src/runtime/XMLNode.cxx +++ b/src/runtime/XMLNode.cxx @@ -21,6 +21,7 @@ #include "XMLPorts.hxx" #include "Mutex.hxx" #include "TypeCode.hxx" +#include "AutoLocker.hxx" #include #include @@ -91,21 +92,22 @@ void XmlNode::execute() DEBTRACE("execute"); char dir[]="yacsXXXXXX"; // add a lock around mkdtemp (seems not thread safe) - MUTEX.lock(); + { + YACS::BASES::AutoLocker alck(&MUTEX); #ifdef WIN32 - char mdir [512+1]; - GetTempPath(MAX_PATH+1, mdir); - CreateDirectory(mdir, NULL); + char mdir [512+1]; + GetTempPath(MAX_PATH+1, mdir); + CreateDirectory(mdir, NULL); #else - char* mdir=mkdtemp(dir); + char* mdir=mkdtemp(dir); #endif - MUTEX.unlock(); - if(mdir==NULL) - { - perror("mkdtemp failed"); - std::cerr << "Problem in mkdtemp " << dir << " " << mdir << std::endl; - throw Exception("Execution problem in mkdtemp"); - } + if(mdir==NULL) + { + perror("mkdtemp failed"); + std::cerr << "Problem in mkdtemp " << dir << " " << mdir << std::endl; + throw Exception("Execution problem in mkdtemp"); + } + } std::string sdir(dir); std::string input=sdir+"/input"; std::ofstream f(input.c_str()); diff --git a/src/yacsloader_swig/loader.i b/src/yacsloader_swig/loader.i index d591c3eb5..ff844ef44 100644 --- a/src/yacsloader_swig/loader.i +++ b/src/yacsloader_swig/loader.i @@ -51,6 +51,7 @@ %types(YACS::ENGINE::Node *); %types(YACS::ENGINE::InputPort *,YACS::ENGINE::OutputPort *,YACS::ENGINE::InputDataStreamPort *,YACS::ENGINE::OutputDataStreamPort *); %types(YACS::ENGINE::InGate *,YACS::ENGINE::OutGate *,YACS::ENGINE::InPort *,YACS::ENGINE::OutPort *,YACS::ENGINE::Port *); +%types(YACS::ENGINE::Container *, YACS::ENGINE::HomogeneousPoolContainer *); %import "pilot.i" -- 2.30.2