Index: /trunk/SophyaLib/SysTools/Makefile
===================================================================
--- /trunk/SophyaLib/SysTools/Makefile	(revision 3717)
+++ /trunk/SophyaLib/SysTools/Makefile	(revision 3718)
@@ -4,80 +4,111 @@
  
 clean:
-	 rm -f $(SOPHYAOBJP)cexpre.o $(SOPHYAOBJP)commander.o $(SOPHYAOBJP)ctimer.o $(SOPHYAOBJP)cxxcmplnk.o $(SOPHYAOBJP)pdlmgr.o $(SOPHYAOBJP)periodic.o $(SOPHYAOBJP)psighand.o $(SOPHYAOBJP)resusage.o $(SOPHYAOBJP)rpneval.o $(SOPHYAOBJP)zthread.o $(SOPHYAOBJP)timing.o
+	 rm -f $(SOPHYAOBJP)cexpre.o $(SOPHYAOBJP)commander.o $(SOPHYAOBJP)ctimer.o $(SOPHYAOBJP)cxxcmplnk.o $(SOPHYAOBJP)parlex.o $(SOPHYAOBJP)pdlmgr.o $(SOPHYAOBJP)periodic.o $(SOPHYAOBJP)psighand.o $(SOPHYAOBJP)resusage.o $(SOPHYAOBJP)rpneval.o $(SOPHYAOBJP)zthread.o $(SOPHYAOBJP)timing.o
 	rm -f $(SOPHYALIBP)libSysTools.a
  
-$(SOPHYALIBP)libSysTools.a : $(SOPHYAOBJP)cexpre.o $(SOPHYAOBJP)commander.o $(SOPHYAOBJP)ctimer.o $(SOPHYAOBJP)cxxcmplnk.o $(SOPHYAOBJP)pdlmgr.o $(SOPHYAOBJP)periodic.o $(SOPHYAOBJP)psighand.o $(SOPHYAOBJP)resusage.o $(SOPHYAOBJP)rpneval.o $(SOPHYAOBJP)timing.o $(SOPHYAOBJP)zthread.o
+$(SOPHYALIBP)libSysTools.a : $(SOPHYAOBJP)cexpre.o $(SOPHYAOBJP)commander.o $(SOPHYAOBJP)ctimer.o $(SOPHYAOBJP)cxxcmplnk.o $(SOPHYAOBJP)parlex.o $(SOPHYAOBJP)pdlmgr.o $(SOPHYAOBJP)periodic.o $(SOPHYAOBJP)psighand.o $(SOPHYAOBJP)resusage.o $(SOPHYAOBJP)rpneval.o $(SOPHYAOBJP)timing.o $(SOPHYAOBJP)zthread.o
 	$(AR) $(ARFLAGS) $@ $? 
 	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
  
-$(SOPHYAOBJP)cexpre.o: cexpre.cc $(SOPHYAINCP)sopnamsp.h \
-  cexpre.h $(SOPHYAINCP)machdefs.h \
+$(SOPHYAOBJP)cexpre.o: cexpre.cc $(SOPHYAINCP)sopnamsp.h cexpre.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
   $(SOPHYAINCP)pexceptions.h \
   $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)randinterf.h \
-  $(SOPHYAINCP)anydataobj.h
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cexpre.cc
  
 $(SOPHYAOBJP)commander.o: commander.cc $(SOPHYAINCP)sopnamsp.h \
-  commander.h $(SOPHYAINCP)machdefs.h pdlmgr.h \
-  $(SOPHYAINCP)dvlist.h \
-  $(SOPHYAINCP)objfio.h \
+  commander.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h $(SOPHYAINCP)objfio.h \
   $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)pexceptions.h \
-  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)machdefs.h $(SOPHYAINCP)gnumd5.h \
   $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)ppfnametag.h \
-  $(SOPHYAINCP)mutyv.h \
-  $(SOPHYAINCP)timestamp.h ctimer.h \
-  $(SOPHYAINCP)strutil.h \
-  $(SOPHYAINCP)strutilxx.h cexpre.h \
-  $(SOPHYAINCP)pexceptions.h rpneval.h \
+  $(SOPHYAINCP)ppersist.h $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)machdefs.h $(SOPHYAINCP)objfio.h \
+  ctimer.h $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)machdefs.h cexpre.h rpneval.h \
   $(SOPHYAINCP)srandgen.h \
-  $(SOPHYAINCP)randinterf.h zthread.h
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)randinterf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h zthread.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  commander.cc
  
 $(SOPHYAOBJP)ctimer.o: ctimer.cc $(SOPHYAINCP)machdefs.h \
-  $(SOPHYAINCP)sopnamsp.h ctimer.h
+  $(SOPHYAINCP)osx_values.h ctimer.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ctimer.cc
  
 $(SOPHYAOBJP)cxxcmplnk.o: cxxcmplnk.cc $(SOPHYAINCP)sopnamsp.h \
   cxxcmplnk.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
   $(SOPHYAINCP)sspvflags.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cxxcmplnk.cc
  
+$(SOPHYAOBJP)parlex.o: parlex.cc parlex.h zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  parlex.cc
+ 
 $(SOPHYAOBJP)pdlmgr.o: pdlmgr.cc $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
   $(SOPHYAINCP)sopnamsp.h pdlmgr.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pdlmgr.cc
  
 $(SOPHYAOBJP)periodic.o: periodic.cc $(SOPHYAINCP)sopnamsp.h \
-  $(SOPHYAINCP)machdefs.h periodic.h
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h periodic.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  periodic.cc
  
-$(SOPHYAOBJP)psighand.o: psighand.cc $(SOPHYAINCP)sopnamsp.h \
-  psighand.h $(SOPHYAINCP)machdefs.h \
+$(SOPHYAOBJP)psighand.o: psighand.cc $(SOPHYAINCP)sopnamsp.h psighand.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
   $(SOPHYAINCP)pexceptions.h \
   $(SOPHYAINCP)machdefs.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  psighand.cc
  
-$(SOPHYAOBJP)resusage.o: resusage.cc $(SOPHYAINCP)sopnamsp.h \
-  resusage.h $(SOPHYAINCP)machdefs.h
+$(SOPHYAOBJP)resusage.o: resusage.cc $(SOPHYAINCP)sopnamsp.h resusage.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  resusage.cc
  
-$(SOPHYAOBJP)rpneval.o: rpneval.cc $(SOPHYAINCP)sopnamsp.h \
-  rpneval.h $(SOPHYAINCP)machdefs.h \
+$(SOPHYAOBJP)rpneval.o: rpneval.cc $(SOPHYAINCP)sopnamsp.h rpneval.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
   $(SOPHYAINCP)pexceptions.h \
   $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)randinterf.h \
-  $(SOPHYAINCP)anydataobj.h
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  rpneval.cc
  
-$(SOPHYAOBJP)zthread.o: zthread.cc $(SOPHYAINCP)sopnamsp.h \
-  zthread.h $(SOPHYAINCP)machdefs.h \
+$(SOPHYAOBJP)zthread.o: zthread.cc $(SOPHYAINCP)sopnamsp.h zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
   $(SOPHYAINCP)pexceptions.h \
   $(SOPHYAINCP)machdefs.h
Index: /trunk/SophyaLib/SysTools/objlist.list
===================================================================
--- /trunk/SophyaLib/SysTools/objlist.list	(revision 3717)
+++ /trunk/SophyaLib/SysTools/objlist.list	(revision 3718)
@@ -3,4 +3,5 @@
 ctimer.o
 cxxcmplnk.o
+parlex.o
 pdlmgr.o
 periodic.o
Index: /trunk/SophyaLib/SysTools/parlex.cc
===================================================================
--- /trunk/SophyaLib/SysTools/parlex.cc	(revision 3718)
+++ /trunk/SophyaLib/SysTools/parlex.cc	(revision 3718)
@@ -0,0 +1,264 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+
+#include "parlex.h"
+
+using namespace std; 
+
+namespace SOPHYA {
+
+/*!
+  \class ParallelTaskFunction 
+  \ingroup SysTools
+  \brief ParallelTaskInterface implementation for functions 
+*/  
+//! Constructor with the specification of the function to be executed 
+ParallelTaskFunction::ParallelTaskFunction(ParalExFunction f)
+  : parfunc_(f)
+{
+}
+int ParallelTaskFunction::execute(int tid)
+{
+  return parfunc_(tid);
+}
+
+/*!
+  \class ParalExThread
+  \ingroup SysTools
+  \brief Thread objects that provide methods to control their execution.   
+*/
+/* --Methode-- */
+/*! 
+  \brief Constructor with the specification of the ParallelTask object and the 
+  tread-id or rank in a context of parallel execution 
+*/
+ParalExThread::ParalExThread(ParallelTaskInterface& ptask, int tid)
+  : ptask_(ptask), tid_(tid), mtx_(false), state_(0)
+{
+}
+
+/* --Methode-- */
+//! specific implementation of the ZThread::run() method
+void ParalExThread::run()
+{
+  bool fgencore=true;
+  while(fgencore) {
+    mtx_.lock();
+    while ((state_!=1)&&(state_!=6))  mtx_.wait();
+    if (state_==6)  {  // Signal de fin d'execution du thread  
+      setRC(0);
+      state_=7;
+      //DEL cout << " *DBG*FF* ParalExThread::run(tid=" << tid_ << ") state->7 " << endl; 
+      mtx_.unlock();
+      mtx_.signal();
+      fgencore=false;
+      return;
+    }
+    state_=2;
+    int rcex = 0;
+    try {
+      rcex = ptask_.execute(tid_);
+    }
+    catch (std::exception exc) {
+      fgexcept_ = true;
+      msg_exc_ = "std::exception in ParalExThread::run(): ";
+      msg_exc_ += exc.what();
+      cerr << "ParalExThread::run(): catched std::exception " << exc.what() << endl;
+      rcex = 77;
+    }  
+    catch (...) {
+      fgexcept_ = true;
+      msg_exc_ = "Unknown exception (...) in ParalExThread::run(): ";
+      cerr << "ParalExThread::run(): catched unknown (...) exception " << endl; 
+      rcex = 78; 
+    } 
+    setRC(rcex);
+    state_=3;
+    mtx_.unlock();
+    mtx_.signal();
+  }
+  return;
+}
+
+/*!
+  \brief Launches the task execution (call ptask.execute() )
+  The thread should have been previously started using the start() method. 
+*/
+/* --Methode-- */
+int ParalExThread::go()
+{
+  //  if (!IfStarted())  start();
+  mtx_.lock();
+  if (state_>5)  {  // condition d'erreur - thread termine 
+    mtx_.unlock();
+    return 99;
+  }
+  // Attente conditions pour lancer l'execution 
+  while (state_!=0)   mtx_.wait();
+  
+  // On modifie l'etat pour lancer l'execution 
+  state_ = 1;
+  fgexcept_ = false;
+  msg_exc_ = "";
+  mtx_.unlock();
+  mtx_.signal();
+}
+
+/* --Methode-- */
+//! Waits till the end of execution launched by go()
+int ParalExThread::waitEndOfExecution()
+{
+  int rc = 0;
+  mtx_.lock();
+  if (state_>5)  rc = 99;
+  else if (state_<1)  rc = 97;
+  if (rc !=0) {  // condition d'erreur - thread termine ou execution non lance 
+    mtx_.unlock();
+    return rc;
+  }
+  while (state_!=3)  mtx_.wait();
+  state_ = 0;
+  mtx_.unlock();
+  mtx_.signal();
+  return(getRC());
+}
+
+/* --Methode-- */
+int ParalExThread::setParallelTask(ParallelTaskInterface& ptask)
+{
+  int rc = 0;
+  mtx_.lock();
+  if (state_>5)  {  // condition d'erreur - thread termine 
+    mtx_.unlock();
+    return 99;
+  }
+  while (state_!=0)   mtx_.wait();
+  ptask_ = ptask;
+  mtx_.unlock();
+  return(0);
+}
+
+/* --Methode-- */
+/*!
+  \brief Terminates (stops) the thread execution. 
+  
+  if fgwait==true, function returns only after the effective thread termination.
+*/
+void ParalExThread::terminate(bool fgwait)
+{
+  //DEL  cout << " *DBG* ParalExThread::terminate(tid=" << tid_ << ") " << endl; 
+  mtx_.lock();
+  state_=6;
+  mtx_.unlock();
+  mtx_.signal();
+  if (!fgwait)  return;
+  usleep(200);
+  //DEL  cout << " *DBG*EE* ParalExThread::terminate(tid=" << tid_ << ") after usleep " << endl; 
+  mtx_.lock();
+  while (state_!=7)  mtx_.wait();
+  mtx_.unlock();
+  return;
+}
+
+
+/*!
+  \class ParallelExecutor
+  \ingroup SysTools
+  \brief This class can be used for simultaneous execution of different functions  
+*/
+
+/*! 
+  \brief Contructor with arguments specifying the number of parallel execution threads 
+  and the parallel task object 
+*/
+/* --Methode-- */
+ParallelExecutor::ParallelExecutor(ParallelTaskInterface& ptask, size_t nthr)
+  : vpext_(nthr), vrc_(nthr), fgstarted_(false), fgrunning_(false)
+{
+  if (nthr<1) throw ParmError("ParallelExecutor(ptask,nthr)/Error nthr<1"); 
+  for(size_t i=0; i<vpext_.size(); i++) {
+    vpext_[i] = new ParalExThread(ptask, i);
+    vrc_[i] = 0;
+  }
+}
+
+/*! 
+  \brief Contructor with a vector argument containing the list of parallel task objects 
+  to be executed.
+*/
+/* --Methode-- */
+ParallelExecutor::ParallelExecutor(vector< ParallelTaskInterface * > vptask)
+  : vpext_(vptask.size()), vrc_(vptask.size()), fgstarted_(false), fgrunning_(false)
+{
+  if (vptask.size()<1) throw ParmError("ParallelExecutor(vector<ptask>/Error vptask.size()<1"); 
+  for(size_t i=0; i<vpext_.size(); i++) {
+    vpext_[i] = new ParalExThread( (*vptask[i]), i);
+    vrc_[i] = 0;
+  }
+}
+
+/* --Methode-- */
+ParallelExecutor::~ParallelExecutor()
+{
+  //DEL  cout << " **DBG*B**~ParallelExecutor() " << endl;
+  for(size_t i=0; i<vpext_.size(); i++) {
+    //DEL cout << " *DBG*C* vpext_[ " << i << " ]->terminate(true) " << endl;
+    vpext_[i]->terminate(true);
+    delete vpext_[i];
+  }
+}
+
+/* --Methode-- */
+void ParallelExecutor::SetParallelTask( ParallelTaskInterface& ptask )
+{
+  if (fgrunning_) 
+    throw ZThreadExc("ParallelExecutor::SetParallelTask(ptask)/Error parallel thread are running");
+  for(size_t i=0; i<vpext_.size(); i++)
+    vpext_[i]->setParallelTask(ptask);
+  return;
+}
+
+/* --Methode-- */
+void ParallelExecutor::SetParallelTask( vector< ParallelTaskInterface * > vptask )
+{
+  if (fgrunning_) 
+    throw ZThreadExc("ParallelExecutor::SetParallelTask(vector<ptask>)/Error parallel thread are running");
+  if (vptask.size()!=vpext_.size()) 
+    throw SzMismatchError("ParallelExecutor::SetParallelTask(vector<ptask>) - vptask.size()!=vpext.size()");
+  for(size_t i=0; i<vpext_.size(); i++)
+    vpext_[i]->setParallelTask(*vptask[i]);
+  return;
+}
+
+
+/* --Methode-- */
+void ParallelExecutor::start()
+{
+  if (fgstarted_)  return;
+  for(size_t i=0; i<vpext_.size(); i++)  vpext_[i]->start();
+  return;
+}
+
+/*! 
+  \brief Lauches the ParallelTask::execute() in the parallel threads and waits for their ending
+  
+  The return code is zero if all threads have succesfully executed with ParallelTask::execute() 
+  return code=0. The methods getRC(i) and IfException(i) should be checked in case of errors.
+*/
+/* --Methode-- */
+int ParallelExecutor::execute()
+{
+  fgrunning_ = true;
+  for(size_t i=0; i<vpext_.size(); i++)  vpext_[i]->go();
+  int rc = 0;
+  for(size_t i=0; i<vpext_.size(); i++)  { 
+    vrc_[i] = vpext_[i]->waitEndOfExecution();
+    if (vrc_[i]!=0)  rc++;
+  }
+  fgrunning_ = false;
+  return rc;
+}
+
+}  // End namespace SOPHYA 
+
Index: /trunk/SophyaLib/SysTools/parlex.h
===================================================================
--- /trunk/SophyaLib/SysTools/parlex.h	(revision 3718)
+++ /trunk/SophyaLib/SysTools/parlex.h	(revision 3718)
@@ -0,0 +1,130 @@
+// This may look like C code, but it is really -*- C++ -*-
+// UPS - LAL (Orsay) / IN2P3/CNRS  -  IRFU/SPP (Saclay) / CEA
+#ifndef PARLEX_SEEN
+#define PARLEX_SEEN
+
+// Classes pour execution de taches paralleles en utilisant les threads
+//    R. Ansari       UPS+LAL IN2P3/CNRS  2005
+
+#include "zthread.h"
+#include <vector>
+
+namespace SOPHYA {
+using namespace std; 
+
+//--------------------------------------------------------------------
+//  Interface pour les objets ayant une fonction (Execute()) pouvant 
+//  s'executer en parallele
+//--------------------------------------------------------------------
+/*!
+  \class ParallelTaskInterface
+  \ingroup SysTools
+  \brief Interface definition for parallel task object. 
+
+  The pure virtual method execute() should be redefined by the classes
+  inheriting from ParallelTaskInterface
+*/  
+class ParallelTaskInterface {
+public:
+  explicit       ParallelTaskInterface()  { }
+  virtual        ~ParallelTaskInterface() { }
+  /*! This method should perform the actual computation. The parameter tid 
+    is used by the ParallelExecutor class to identify the thread calling the method
+  */
+  virtual int    execute(int tid) = 0; 
+};
+
+//---- Implementation de ParallelTaskInterface pour l'execution des fonctions 
+typedef int (* ParalExFunction) (int);
+//----
+class ParallelTaskFunction {
+public:
+  explicit       ParallelTaskFunction(ParalExFunction f);
+  virtual int    execute(int tid);
+ 
+  ParalExFunction parfunc_;
+};
+
+//--------------------------------------------------------------------
+//  Classe de thread permettant l'execution controle de la methode 
+//   ParallelTaskInterface::Execute() 
+//--------------------------------------------------------------------
+class ParalExThread : public ZThread {
+public:
+  explicit       ParalExThread(ParallelTaskInterface& ptask, int tid);
+  virtual void   run();
+
+  // demarre l'execution (start() doit etre appele avant)  
+  //! 
+  int    go();
+  // Attend la fin  de l'execution 
+  int    waitEndOfExecution();
+  // Termine (arrete) l'execution du thread . si fgwait==true, attend l'arret effectif du tread.
+  void   terminate(bool fgwait=true);
+  // demarre l'execution et attend sa fin
+  //! Launches the execution of ptask_.execute() and waits for its ending.
+  inline int execute() 
+  { 
+    int rc=go();
+    if(rc!=0) return rc;
+    return waitEndOfExecution();
+  }
+  //! Return the the execution phase, 0: waiting, 1:go called, 2: executing, 3: execution finished 
+  inline int getExecutionState() { return state_; }
+  //! Return true if an exception has been catched when ptask_.execute() called, and correspond message
+  inline bool IfException(string& msg)
+     {  msg=msg_exc_;  return fgexcept_; }
+
+  //! Return reference to the parallel task object  
+  inline ParallelTaskInterface& getParallelTask() { return ptask_; }
+  //! Set (changes) the parallel task object. 
+  int setParallelTask(ParallelTaskInterface& ptask);
+  //! Return the rank or thread-id in a parallel execution context
+  inline int Rank() { return tid_; }
+
+protected: 
+  ParallelTaskInterface& ptask_;
+  int tid_;
+  ZMutex mtx_;
+  int state_;     //  running state  
+// 0:idle, 1: go, 2: executing, 3: executionfinished , 6:terminatethread, 7:threadfinished 
+  bool fgexcept_;  // true -> exception lors de l'execution de ptask_.execute() 
+  string msg_exc_;  // message d'exception le cas echeant 
+};
+
+//--------------------------------------------------------------------
+//  Classe permettant l'execution simultanee de plusieurs fonctions 
+//   ParallelTaskInterface::Execute() 
+//--------------------------------------------------------------------
+class ParallelExecutor {
+public:
+  explicit      ParallelExecutor(ParallelTaskInterface& ptask, size_t nthr); 
+  explicit      ParallelExecutor(vector< ParallelTaskInterface * > vptask); 
+  virtual       ~ParallelExecutor();
+
+  //! Set (changes) the parallel task objects (same object for all threads)
+  void SetParallelTask( ParallelTaskInterface& ptask );
+  //! Set (changes) the parallel task objects 
+  void SetParallelTask( vector< ParallelTaskInterface * > vptask);
+
+  //! Starts all the parallel threads 
+  virtual void  start();
+  // Appel a l'execution parallele
+  virtual int   execute();
+  //! Return the number of parallel threads 
+  inline  size_t  nThreads()  { return vpext_.size(); }
+  //! Return RC for the ParalleTask.execute() of thread i 
+  inline  int     getRC(size_t i) { return vrc_[i]; }
+  //! Return the execption condition for the ParalleTask.execute() of thread i 
+  inline  bool    IfException(size_t i, string& msg)  { return vpext_[i]->IfException(msg); }
+
+protected:
+  vector<ParalExThread *> vpext_; 
+  vector<int> vrc_;
+  bool fgstarted_;   // true -> les threads tournent (thr[i].start() appeles)
+  bool fgrunning_;   // true -> en cours d'execution 
+};
+
+} // namespace SOPHYA
+
+#endif
Index: /trunk/SophyaLib/SysTools/smakefile
===================================================================
--- /trunk/SophyaLib/SysTools/smakefile	(revision 3717)
+++ /trunk/SophyaLib/SysTools/smakefile	(revision 3718)
@@ -4,80 +4,111 @@
  
 clean:
-	 rm -f $(SOPHYAOBJP)cexpre.o $(SOPHYAOBJP)commander.o $(SOPHYAOBJP)ctimer.o $(SOPHYAOBJP)cxxcmplnk.o $(SOPHYAOBJP)pdlmgr.o $(SOPHYAOBJP)periodic.o $(SOPHYAOBJP)psighand.o $(SOPHYAOBJP)resusage.o $(SOPHYAOBJP)rpneval.o $(SOPHYAOBJP)zthread.o $(SOPHYAOBJP)timing.o
+	 rm -f $(SOPHYAOBJP)cexpre.o $(SOPHYAOBJP)commander.o $(SOPHYAOBJP)ctimer.o $(SOPHYAOBJP)cxxcmplnk.o $(SOPHYAOBJP)parlex.o $(SOPHYAOBJP)pdlmgr.o $(SOPHYAOBJP)periodic.o $(SOPHYAOBJP)psighand.o $(SOPHYAOBJP)resusage.o $(SOPHYAOBJP)rpneval.o $(SOPHYAOBJP)zthread.o $(SOPHYAOBJP)timing.o
 	rm -f $(SOPHYALIBP)libSysTools.a
  
-$(SOPHYALIBP)libSysTools.a : $(SOPHYAOBJP)cexpre.o $(SOPHYAOBJP)commander.o $(SOPHYAOBJP)ctimer.o $(SOPHYAOBJP)cxxcmplnk.o $(SOPHYAOBJP)pdlmgr.o $(SOPHYAOBJP)periodic.o $(SOPHYAOBJP)psighand.o $(SOPHYAOBJP)resusage.o $(SOPHYAOBJP)rpneval.o $(SOPHYAOBJP)timing.o $(SOPHYAOBJP)zthread.o
+$(SOPHYALIBP)libSysTools.a : $(SOPHYAOBJP)cexpre.o $(SOPHYAOBJP)commander.o $(SOPHYAOBJP)ctimer.o $(SOPHYAOBJP)cxxcmplnk.o $(SOPHYAOBJP)parlex.o $(SOPHYAOBJP)pdlmgr.o $(SOPHYAOBJP)periodic.o $(SOPHYAOBJP)psighand.o $(SOPHYAOBJP)resusage.o $(SOPHYAOBJP)rpneval.o $(SOPHYAOBJP)timing.o $(SOPHYAOBJP)zthread.o
 	$(AR) $(ARFLAGS) $@ $? 
 	touch $(SOPHYAINCP)/SophyaConfInfo/libsophya.objlist
  
-$(SOPHYAOBJP)cexpre.o: cexpre.cc $(SOPHYAINCP)sopnamsp.h \
-  cexpre.h $(SOPHYAINCP)machdefs.h \
+$(SOPHYAOBJP)cexpre.o: cexpre.cc $(SOPHYAINCP)sopnamsp.h cexpre.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
   $(SOPHYAINCP)pexceptions.h \
   $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)randinterf.h \
-  $(SOPHYAINCP)anydataobj.h
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cexpre.cc
  
 $(SOPHYAOBJP)commander.o: commander.cc $(SOPHYAINCP)sopnamsp.h \
-  commander.h $(SOPHYAINCP)machdefs.h pdlmgr.h \
-  $(SOPHYAINCP)dvlist.h \
-  $(SOPHYAINCP)objfio.h \
+  commander.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h pdlmgr.h \
+  $(SOPHYAINCP)dvlist.h $(SOPHYAINCP)objfio.h \
   $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)ppersist.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)pexceptions.h \
-  $(SOPHYAINCP)gnumd5.h \
+  $(SOPHYAINCP)machdefs.h $(SOPHYAINCP)gnumd5.h \
   $(SOPHYAINCP)ppfbinstream.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)rawstream.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)ppfnametag.h \
-  $(SOPHYAINCP)mutyv.h \
-  $(SOPHYAINCP)timestamp.h ctimer.h \
-  $(SOPHYAINCP)strutil.h \
-  $(SOPHYAINCP)strutilxx.h cexpre.h \
-  $(SOPHYAINCP)pexceptions.h rpneval.h \
+  $(SOPHYAINCP)ppersist.h $(SOPHYAINCP)mutyv.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)timestamp.h \
+  $(SOPHYAINCP)machdefs.h $(SOPHYAINCP)objfio.h \
+  ctimer.h $(SOPHYAINCP)strutil.h \
+  $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)machdefs.h cexpre.h rpneval.h \
   $(SOPHYAINCP)srandgen.h \
-  $(SOPHYAINCP)randinterf.h zthread.h
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)randinterf.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h zthread.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  commander.cc
  
 $(SOPHYAOBJP)ctimer.o: ctimer.cc $(SOPHYAINCP)machdefs.h \
-  $(SOPHYAINCP)sopnamsp.h ctimer.h
+  $(SOPHYAINCP)osx_values.h ctimer.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  ctimer.cc
  
 $(SOPHYAOBJP)cxxcmplnk.o: cxxcmplnk.cc $(SOPHYAINCP)sopnamsp.h \
   cxxcmplnk.h $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
   $(SOPHYAINCP)sspvflags.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  cxxcmplnk.cc
  
+$(SOPHYAOBJP)parlex.o: parlex.cc parlex.h zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
+  $(SOPHYAINCP)pexceptions.h \
+  $(SOPHYAINCP)machdefs.h
+	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  parlex.cc
+ 
 $(SOPHYAOBJP)pdlmgr.o: pdlmgr.cc $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
   $(SOPHYAINCP)sopnamsp.h pdlmgr.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  pdlmgr.cc
  
 $(SOPHYAOBJP)periodic.o: periodic.cc $(SOPHYAINCP)sopnamsp.h \
-  $(SOPHYAINCP)machdefs.h periodic.h
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h periodic.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  periodic.cc
  
-$(SOPHYAOBJP)psighand.o: psighand.cc $(SOPHYAINCP)sopnamsp.h \
-  psighand.h $(SOPHYAINCP)machdefs.h \
+$(SOPHYAOBJP)psighand.o: psighand.cc $(SOPHYAINCP)sopnamsp.h psighand.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
   $(SOPHYAINCP)pexceptions.h \
   $(SOPHYAINCP)machdefs.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  psighand.cc
  
-$(SOPHYAOBJP)resusage.o: resusage.cc $(SOPHYAINCP)sopnamsp.h \
-  resusage.h $(SOPHYAINCP)machdefs.h
+$(SOPHYAOBJP)resusage.o: resusage.cc $(SOPHYAINCP)sopnamsp.h resusage.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  resusage.cc
  
-$(SOPHYAOBJP)rpneval.o: rpneval.cc $(SOPHYAINCP)sopnamsp.h \
-  rpneval.h $(SOPHYAINCP)machdefs.h \
+$(SOPHYAOBJP)rpneval.o: rpneval.cc $(SOPHYAINCP)sopnamsp.h rpneval.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
   $(SOPHYAINCP)pexceptions.h \
   $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)strutilxx.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)srandgen.h \
+  $(SOPHYAINCP)machdefs.h \
   $(SOPHYAINCP)randinterf.h \
-  $(SOPHYAINCP)anydataobj.h
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)anydataobj.h \
+  $(SOPHYAINCP)machdefs.h
 	$(CXXCOMPILE) $(CXXTEMPFLG) -o $@  rpneval.cc
  
-$(SOPHYAOBJP)zthread.o: zthread.cc $(SOPHYAINCP)sopnamsp.h \
-  zthread.h $(SOPHYAINCP)machdefs.h \
+$(SOPHYAOBJP)zthread.o: zthread.cc $(SOPHYAINCP)sopnamsp.h zthread.h \
+  $(SOPHYAINCP)machdefs.h \
+  $(SOPHYAINCP)osx_values.h \
   $(SOPHYAINCP)pexceptions.h \
   $(SOPHYAINCP)machdefs.h
Index: /trunk/SophyaLib/SysTools/zthread.cc
===================================================================
--- /trunk/SophyaLib/SysTools/zthread.cc	(revision 3717)
+++ /trunk/SophyaLib/SysTools/zthread.cc	(revision 3718)
@@ -63,5 +63,5 @@
 {
   ZThread * thr = (ZThread *)xthr;
-  if(thr->_status == 1) thr->_status = 2;
+  if(thr->_status == 2) thr->_status = 3;
   return;
 }
@@ -76,9 +76,11 @@
 /* ------ Classe ZThread  -------  */
 /*!
-  Constructor, with optional specification of the thread stack size.
+  Constructor, with optional specification of the thread stack size in bytes.
+  if not specified or zero, defaut system stack size is used.
 */
 ZThread::ZThread(size_t stacksize)
 {
   _status = 0;
+  _fgstarted = false;
   _ssize = 0;
   _act = NULL;
@@ -93,9 +95,12 @@
 
 /*!
-  Method which starts the thread.
+  Method which starts the thread. 
+  The thread object is created by a call to pthread_create() in this method.
 */
 void ZThread::start()
 {
-  if ( IfStarted() ) throw ZThreadExc("ZThread::Start() - Already started thread !");
+  if ( _fgstarted ) throw ZThreadExc("ZThread::Start() - Already started thread !");
+  _fgstarted = true;
+  _status = 1;
   int rc;
   pthread_attr_t tha;
@@ -154,5 +159,5 @@
 {
   if (_act)  _act(_usp);
-  setRC(0);      
+  exit(0);      
   return;
 }
@@ -165,8 +170,8 @@
 void ZThread::run_p()
 {
-  _status = 1;
+  _status = 2;
   pthread_cleanup_push(zthr_cleanup, (void *)this);
   run();
-  _status = 2;
+  _status = 3;
   pthread_exit(&(_rc));
   pthread_cleanup_pop(0);
@@ -212,5 +217,5 @@
 
 /*!
-  Constructor: Creates a associated pair of POSIX \c pthread_mutex_t 
+  Constructor: Creates an associated pair of POSIX \c pthread_mutex_t 
   and \c pthread_cond_t objects
   \param : if fgd == true , the destructor call pthread_mutex_destroy/pthread_cond_destroy
Index: /trunk/SophyaLib/SysTools/zthread.h
===================================================================
--- /trunk/SophyaLib/SysTools/zthread.h	(revision 3717)
+++ /trunk/SophyaLib/SysTools/zthread.h	(revision 3718)
@@ -31,19 +31,24 @@
   explicit	ZThread(size_t stacksize=0);
   virtual	~ZThread();
+  //! Change the thread stack-size, specified in bytes. Can only be called before the thread is started
+  inline void   setStackSize(size_t ssz) { _ssize=ssz; }
+  //! Change the thread stack-size, specified in kilobytes. Can only be called before the thread is started
+  inline void   setStackSizekb(size_t sszk) { _ssize=sszk*1024; }
+
   void		start();
   void		cancel();
   void          kill(int sig);
+  void          join();
 
-  void          join();
   virtual void  run();
 
   //! Returns true if the thread has been created / started
-  bool IfStarted() { return ((_status > 0) ? true : false); }
+  bool IfStarted() { return (((_fgstarted)||(_status>0)) ? true : false); }
   //! Returns true if the thread is running 
-  bool IfRunning() { return ((_status == 1) ? true : false); }
+  bool IfRunning() { return ((_status == 2) ? true : false); }
   //! Returns true if the thread has ended normally 
-  bool IfEnded() { return ((_status == 2) ? true : false); }
+  bool IfEnded() { return ((_status == 3) ? true : false); }
   //! Returns true if the thread has been stopped (killed/canceled) 
-  bool IfStopped() { return ((_status == 3) ? true : false); }
+  bool IfStopped() { return ((_status == 5) ? true : false); }
 
   //! Sets the return code for the thread object
@@ -77,4 +82,7 @@
   // PTHREAD_CANCEL_DEFERRED  ou  PTHREAD_CANCEL_ASYNCHRONOUS
 
+  /*! 
+    \brief This method is only for internal use by zthread.cc and should not be called by users
+  */ 
   virtual void  run_p();
 
@@ -83,6 +91,6 @@
   size_t _ssize;
   int _rc;
-  int _status; // 0 : not started, 1: running, 2: ended, 3:stopped 
-
+  int _status; // 0 : not started, 1 : started, 2: running, 3: ended, 5:stopped 
+  bool _fgstarted;   // false -> true par appel a start()
   ZThreadAction _act;
   void * _usp;
