ThreadRunner.hpp 2.78 KB
Newer Older
1
/*************************************************************************
2 3
*  Copyright (C) 2006 by Janek Kozicki                                   *
*  cosurgi@berlios.de                                                    *
4 5 6 7
*                                                                        *
*  This program is free software; it is licensed under the terms of the  *
*  GNU General Public License v2 or later. See file LICENSE for details. *
*************************************************************************/
8

9
#pragma once
10

11
#include <boost/thread/mutex.hpp>
12

13 14
namespace yade { // Cannot have #include directive inside.

15
/*! 
Janek Kozicki's avatar
Janek Kozicki committed
16
\brief	ThreadRunner takes care of starting/stopping (executing) the
17
	ThreadWorker in the separate thread. 
18

19 20
	It is achieved by either:
	- one execution of { ThreadWorker::singleAction(); } in separate thread
Janek Kozicki's avatar
Janek Kozicki committed
21
	- a loop { while(looping() ) ThreadWorker::singleAction(); } in separate thread
22

Janek Kozicki's avatar
Janek Kozicki committed
23
	Lifetime of ThreadRunner is guaranteed to be longer or equal to
24
	the lifetime of	the separate thread of execution.
25

26 27 28
	The ThreadRunner owner must make sure that ThreadWorker has longer or
	equal lifetime than instance of ThreadRunner. Otherwise ThreadRunner
	will try to execute a dead object, which will lead to crash.
29

30
	Do not destroy immediately after call to singleAction(). Destructor can
31 32
	kick in before a separate thread starts, which will lead to a crash.

33 34
	User can explicitly ask the running thread to terminate execution. If
	the thread supports it, it will terminate.
35 36

\note	This code is reentrant. Simultaneous requests from other threads to
37
	start/stop or perform singleAction() are expected.
38
	   
39
	So ThreadWorker(s) are running, while the user is interacting with the
40 41 42 43 44
	UI frontend (doesn't matter whether the UI is graphical, ncurses or
	any other).

 */

Janek Kozicki's avatar
Janek Kozicki committed
45
class ThreadWorker;
46

Janek Kozicki's avatar
Janek Kozicki committed
47
class ThreadRunner
48
{
49
	private :
50
		ThreadWorker*	m_thread_worker;
Janek Kozicki's avatar
Janek Kozicki committed
51 52 53 54
		bool		m_looping;
		boost::mutex	m_boolmutex;
		boost::mutex	m_callmutex;
		boost::mutex	m_runmutex;
55 56 57
		void		run();
		void		call();

58 59
		DECLARE_LOGGER;

60
	public :
61
		ThreadRunner(ThreadWorker* c) : m_thread_worker(c), m_looping(false), workerThrew(false) {};
Janek Kozicki's avatar
Janek Kozicki committed
62
		~ThreadRunner();
63

Janek Kozicki's avatar
Janek Kozicki committed
64
		/// perform ThreadWorker::singleAction() in separate thread
65
		void spawnSingleAction();
Janek Kozicki's avatar
Janek Kozicki committed
66
		/// start doing singleAction() in a loop in separate thread
Janek Kozicki's avatar
Janek Kozicki committed
67
		void start();
Janek Kozicki's avatar
Janek Kozicki committed
68
		/// stop the loop (changes the flag checked by looping() )
Janek Kozicki's avatar
Janek Kozicki committed
69
		void stop();
Janek Kozicki's avatar
Janek Kozicki committed
70
		/// kindly ask the separate thread to terminate
71
		void pleaseTerminate();
Janek Kozicki's avatar
Janek Kozicki committed
72 73
		/// precondition for the loop started with start().
		bool looping();
74 75 76 77
		//! if true, workerException is copy of the exception thrown by the worker
		bool workerThrew;
		//! last exception thrown by the worker, if any
		std::exception workerException;
78 79
};

80
} // namespace yade
81