1 // Copyright (C) 2006-2012 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #ifndef __ALTERNATETHREADPT_HXX__
20 #define __ALTERNATETHREADPT_HXX__
24 #include "YACSBasesExport.hxx"
30 //! This class provides a mechanism to run two threads alternately.
32 * Alternate threads can be necessary when two pieces of code must run alternately
33 * and communicate but are difficult or impossible to synchronize explicitly
34 * (e.g. asynchronous algorithms in optimizer loop). This class guarantees that the
35 * two threads NEVER run concurrently, so no lock mechanism is necessary when sharing
38 * The two threads are called "master thread" and "slave thread". The master thread is
39 * the one that calls the method start() and that will continue to run after the
40 * destruction of this object. The slave thread is created when the method start() is
41 * called. It will run the code in the method run() and will be destroyed when the
42 * master thread calls terminateSlaveThread() or at the destruction of this object.
44 * When the master thread calls start(), it will block and the slave thread will begin
45 * to execute the code in the method run(). The two threads can then alternate by
46 * calling the method signalMasterAndWait() (in the slave thread) and signalSlaveAndWait()
47 * (in the master thread). Finally, the master thread must call terminateSlaveThread()
48 * to terminate the slave thread. There is no explicit mechanism for the slave thread to
49 * request its own termination, but this can be done with an external flag (see the pool
50 * object in OptimizerLoop for instance).
52 * This class is purely virtual. Subclasses must implement the run() method that will
53 * be executed in the slave thread.
55 class YACSBASES_EXPORT AlternateThreadPT
58 enum ThreadStatus {UNEXISTING, NORMAL_CYCLE, TERMINATION_REQUESTED, READY_TO_JOIN};
61 virtual ~AlternateThreadPT();
63 //! Create and launch the slave thread.
65 * This method must not be called by the slave thread or
66 * if a slave thread is already running.
70 //! Block the master thread and release the slave thread.
71 virtual void signalSlaveAndWait();
73 //! Terminate the slave thread.
74 void terminateSlaveThread();
76 //! Block the slave thread and release the master thread.
77 virtual void signalMasterAndWait();
79 //! Return true if the master requested the slave thread termination.
80 bool isTerminationRequested() const;
82 //! Return the thread status.
83 ThreadStatus getThreadStatus() const;
86 //! This method must be implemented in subclasses and will be run in the slave thread.
88 * The slave thread must call signalMasterAndWait() when necessary to give the control
89 * back to the master thread. When returning from this method, the slave thread MUST
90 * check for an eventual termination request (with the method isTerminationRequested()).
91 * If the termination is requested, the slave thread must perform any necessary cleanup
92 * and finish as soon as possible.
99 static void * runThread(void * instance);
100 static void threadCleanupFct(void * instance);
103 ThreadStatus _threadStatus;
104 pthread_cond_t _pingPongCond;
105 pthread_mutex_t _pingPongMutex;