From 6a818e9acc870a5fe80a9c1ebdf3ea636d099134 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Fri, 16 Jan 2015 18:10:25 +0100 Subject: [PATCH] Retrieve state of ForEachLoop node even in case of failure. --- src/engine/Any.cxx | 32 +++++++++++++++++++++++++++++++- src/engine/Any.hxx | 4 ++++ src/engine/Executor.hxx | 1 + src/engine/ForEachLoop.cxx | 35 +++++++++++++++++++++++++++++++++++ src/engine/ForEachLoop.hxx | 5 +++++ src/engine_swig/pilot.i | 37 +++++++++++++++++++++++++++++++++++++ 6 files changed, 113 insertions(+), 1 deletion(-) diff --git a/src/engine/Any.cxx b/src/engine/Any.cxx index 0ca4b843a..e062e0111 100644 --- a/src/engine/Any.cxx +++ b/src/engine/Any.cxx @@ -28,6 +28,9 @@ using namespace YACS::ENGINE; using namespace std; +// forbidden value int=-269488145 double=-1.54947e+231 bool=239 +const char SeqAlloc::DFT_CHAR_VAR=-17;//0xEF + StringOnHeap::StringOnHeap(const char *val):_dealloc(0),_str(strdup(val)) { } @@ -382,7 +385,7 @@ void SeqAlloc::initCoarseMemory(char *mem, unsigned int size, Deallocator deallo memcpy(_start,mem,sizeInByte); else { - for(unsigned int i=0;i SeqAlloc::getSetItems() const +{ + std::vector ret; + unsigned int sz(size()); + for(unsigned int i=0;i its(getSetItems()); + std::size_t sz(its.size()); + SequenceAny *ret(SequenceAny::New(getType()->contentType(),sz)); + for(std::size_t i=0;isetEltAtRank(i,obj); + } + return ret; +} + SequenceAny *SequenceAny::New(const TypeCode *typeOfContent) { if(typeOfContent->kind() == Objref) diff --git a/src/engine/Any.hxx b/src/engine/Any.hxx index cc9a51c9d..3f4560f1b 100644 --- a/src/engine/Any.hxx +++ b/src/engine/Any.hxx @@ -162,6 +162,8 @@ namespace YACS void destroy(char *pt, const TypeCode *tc); void deallocate(char *pt); unsigned int size() const; + std::vector getSetItems() const; + static const char DFT_CHAR_VAR; }; class YACSLIBENGINE_EXPORT ComposedAny : public Any @@ -201,6 +203,8 @@ namespace YACS static SequenceAny *New(const TypeCode *typeOfContent, unsigned lgth); template static SequenceAny *New(T *val, unsigned int lgth, Deallocator deAlloc); + std::vector getSetItems() const { return _alloc.getSetItems(); } + SequenceAny *removeUnsetItemsFromThis() const; protected: void putMyReprAtPlace(char *data) const; static void putReprAtPlace(char *data, const char *src, const TypeCode *type, bool deepCpy); diff --git a/src/engine/Executor.hxx b/src/engine/Executor.hxx index bf606ea6e..fedd17196 100644 --- a/src/engine/Executor.hxx +++ b/src/engine/Executor.hxx @@ -114,6 +114,7 @@ namespace YACS void waitPause(); static int _maxThreads; static size_t _threadStackSize; + YACS::BASES::Mutex& getTheMutexForSchedulerUpdate() { return _mutexForSchedulerUpdate; } protected: bool checkBreakPoints(); void waitResume(); diff --git a/src/engine/ForEachLoop.cxx b/src/engine/ForEachLoop.cxx index 1dc70d97e..325d05801 100644 --- a/src/engine/ForEachLoop.cxx +++ b/src/engine/ForEachLoop.cxx @@ -21,6 +21,9 @@ #include "TypeCode.hxx" #include "Visitor.hxx" #include "ComposedNode.hxx" +#include "Executor.hxx" +#include "AutoLocker.hxx" + #include #include @@ -852,3 +855,35 @@ std::string ForEachLoop::getProgress() const aProgress << "0"; return aProgress.str(); } + +/*! + * This method allows to retrieve the state of \a this during execution or after. This method works even if this is \b NOT complete, or during execution or after a failure in \a this. + * The typical usage of this method is to retrieve the results of items that passed successfully to avoid to lose all of them if only one fails. + * This method has one input \a execut and 3 outputs. + * + * \param [in] execut - The single input is for threadsafety reasons because this method can be called safely during the execution of \a this. + * \param [out] outputs - For each output ports in \a this linked with nodes sharing the same father than \a this the passed results are stored. + * All of the items in \a outputs have the same size. + * \param [out] nameOfOutputs - The array with same size than \a outputs, that tells for each item in outputs the output port it refers to. + * \return the list of ids among \c this->edGetSeqOfSamplesPort() that run successfully. The length of this returned array will be the length of all + * SequenceAny objects contained in \a outputs. + * + * \sa edGetSeqOfSamplesPort + */ +std::vector ForEachLoop::getPassedResults(Executor *execut, std::vector& outputs, std::vector& nameOfOutputs) const +{ + YACS::BASES::AutoLocker alck(&(execut->getTheMutexForSchedulerUpdate())); + if(_execVals.empty()) + return std::vector(); + if(_execOutGoingPorts.empty()) + return std::vector(); + std::size_t sz(_execVals.size()); outputs.resize(sz); nameOfOutputs.resize(sz); + const std::vector& ports(_execOutGoingPorts[0]); + for(std::size_t i=0;iremoveUnsetItemsFromThis(); + nameOfOutputs[i]=ports[i]->getName(); + } + return _execVals[0]->getSetItems(); +} + diff --git a/src/engine/ForEachLoop.hxx b/src/engine/ForEachLoop.hxx index 8181cd8aa..f390dcd36 100644 --- a/src/engine/ForEachLoop.hxx +++ b/src/engine/ForEachLoop.hxx @@ -123,6 +123,8 @@ namespace YACS static const char NAME[]; }; + class Executor; + class YACSLIBENGINE_EXPORT ForEachLoop : public DynParaLoop { friend class SplitterNode; @@ -169,6 +171,9 @@ namespace YACS virtual std::string typeName() {return "YACS__ENGINE__ForEachLoop";} virtual void resetState(int level); std::string getProgress() const; +#ifndef SWIG + std::vector getPassedResults(Executor *execut, std::vector& outputs, std::vector& nameOfOutputs) const; +#endif protected: Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; void checkLinkPossibility(OutPort *start, const std::list& pointsOfViewStart, diff --git a/src/engine_swig/pilot.i b/src/engine_swig/pilot.i index 6262f4773..4b58f258e 100644 --- a/src/engine_swig/pilot.i +++ b/src/engine_swig/pilot.i @@ -189,6 +189,8 @@ REFCOUNT_TEMPLATE(CompoInstmap,YACS::ENGINE::ComponentInstance) %newobject *::createStructTc; %newobject *::createType; +%newobject YACS::ENGINE::SequenceAny::removeUnsetItemsFromThis; + %newobject YACS::ENGINE::TypeCode::interfaceTc; %newobject YACS::ENGINE::TypeCode::sequenceTc; %newobject YACS::ENGINE::TypeCode::structTc; @@ -371,6 +373,14 @@ EXCEPTION(YACS::ENGINE::ExecutorSwig::waitPause) } } +%extend YACS::ENGINE::Any +{ + PyObject *getPyObj() + { + return (PyObject *)getRuntime()->convertNeutral(const_cast(self->getType()),self); + } +} + %newobject YACS::ENGINE::SequenceAny::__getitem__; %extend YACS::ENGINE::SequenceAny { @@ -397,3 +407,30 @@ EXCEPTION(YACS::ENGINE::ExecutorSwig::waitPause) return a; } } + +%extend YACS::ENGINE::ForEachLoop +{ + PyObject *getPassedResults(Executor *execut) const + { + std::vector ret1; + std::vector ret2; + std::vector ret0(self->getPassedResults(execut,ret1,ret2)); + PyObject *ret(PyTuple_New(3)); + // param 0 + PyObject *ret0Py(PyList_New(ret0.size())); + for(std::size_t i=0;i