This file is indexed.

/usr/include/SurgSim/Framework/BasicThread.h is in libopensurgsim-dev 0.7.0-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SURGSIM_FRAMEWORK_BASICTHREAD_H
#define SURGSIM_FRAMEWORK_BASICTHREAD_H

#include <memory>
#include <string>

#include <boost/thread.hpp>
#include <boost/chrono.hpp>

#include "SurgSim/Framework/Barrier.h"
#include "SurgSim/Framework/Timer.h"

namespace SurgSim
{
namespace Framework
{

class Component;
class Runtime;

/// Basic thread implementation, tries to maintain a constant rate, supplies
/// startup an initialization, can be synchronized with other threads at startup
/// after calling doRun() a thread be be set off and doInit() and doStartup() will
/// be called in succession. If given a startup barrier the sequence will pause at
/// both steps until all other threads are done with these steps.
/// Initialization can be further customized by implementing a executeInitialization() function.
/// When a barrier was used to start up the thread it can also be used to run the thread in a
/// synchronous fashion. Use setIsSynchrous(true) to switch the thread over, after that the thread
/// will wait for the barrier to trigger before it executes another update. When running asynchronously the thread
/// cannot be stopped with the stop() call, a barrier wait with an argument of false has to be used
/// to stop the thread. The thread can be set back to asynchronous execution, one last barrier wait after
/// the switch has to be executed for the thread to come out of the wait.
class BasicThread
{
public:
	explicit BasicThread(const std::string& name = "Unknown Thread");
#ifdef _MSC_VER
	virtual ~BasicThread() throw(...);  // Visual Studio does not support noexcept. The throw(...) is optional.
#else
	virtual ~BasicThread() noexcept(false);  /// C++11 introduced noexcept
#endif

	/// Live cycle functions, public implementation.
	/// All of these have virtual partners as private functions

	/// Start the thread from the outside, this will call the private
	/// run() function that can be overridden for each implementor of this
	/// interface.
	/// \param startupBarrier is a barrier it synchronizes a group of thread that should go through their startup
	/// sequence in step.
	/// \param isSynchronous when true the thread will wait on the barrier after each call to update(dt), this
	/// 					 means that only one step will be performed at a time
	void start(std::shared_ptr<Barrier> startupBarrier = nullptr, bool isSynchronous = false);

	/// Stopping the execution, blocks until the running thread has actually stopped,
	/// \note When the thread is in synchronous mode, it needs to be stopped with a call to
	/// 	  the barrier wait function with an argument of false, of course it can always be stopped
	/// 	  by going back to asynchronous mode and then calling stop
	void stop();

	/// Set/Unset the thread in an idle state (doUpdate() called or not in the update() method)
	/// \param isIdle True to set the thread in an idle state, false otherwise
	void setIdle(bool isIdle);

	/// Query if this thread is in idle state or not
	/// \return	true if the thread is in idle state, false otherwise.
	bool isIdle();

	/// Query if this object is initialized.
	/// \return	true if initialized, false if not.
	bool isInitialized();

	/// Query if this object is running.
	/// \return	true if the threads update() function is being called
	bool isRunning() const;

	/// This is what boost::thread executes on thread creation.
	void operator()();

	/// \return the boost threading object
	boost::thread& getThread();

	/// \return the name of the thread
	std::string getName() const;

	/// Set the update rate of the thread
	/// \param val	rate in hertz (updates per second) of the thread
	void setRate(double val)
	{
		m_period = boost::chrono::duration<double>(1.0 / val);
	}

	/// Sets the thread to synchronized execution in concert with the startup
	/// barrier, the startup barrier has to exist for this call to succeed.
	/// When the thread is set to run synchronized it will only execute one update at a time
	/// and then wait for the startup barrier to wake it up again.
	/// \param	val	if true the thread will need to be controlled via the barrier.
	/// \return the actual value of isSynchronous()
	/// \note HS-2013-nov-01 Currently mostly for use in unit tests and debugging, when multiple thread with differing
	/// 	  rates are being synchronized the call rates will not correspond to the expected rates.
	bool setSynchronous(bool val);

	/// Query if this object is synchronized.
	/// \return	true if synchronized, false if not.
	bool isSynchronous();

	/// \return the cumulated cpu time taken to run all update since last reset or thread creation
	/// \note Only the latest 1,000,000 frames since last reset are cumulated, so if the timer is never reset,
	/// \note the Cpu time will not increase past that limit.
	double getCpuTime() const;

	/// \return the number of updates done since last reset or thread creation
	/// \note The update count since last reset has a limit of 1,000,000.
	size_t getUpdateCount() const;

	/// Reset the cpu time and the update count to 0
	void resetCpuTimeAndUpdateCount();

protected:

	/// Timer to measure the actual time taken to doUpdate
	Timer m_timer;

	/// Trigger the initialization of this object, this will be called before all other threads doStartup()
	/// are called
	/// \return true on success
	bool initialize();

	/// Trigger the startup of this object, this will be called after all other threads doInit() was called
	/// the thread will only enter the run loop triggering upated() if all threads doInit() and doStartup()
	/// returned true
	/// \return true on success
	bool startUp();

	bool waitForBarrier(bool success);

	virtual bool executeInitialization();

	/// Logger for this thread
	std::shared_ptr<SurgSim::Framework::Logger> m_logger;

private:
	std::string m_name;

	boost::thread m_thisThread;
	boost::chrono::duration<double> m_period;
	std::shared_ptr<Barrier> m_startupBarrier;

	// Protects the start and stop functions so on can only execute once the other is done
	boost::mutex m_mutexStartStop;

	bool m_isIdle;
	bool m_isInitialized;
	bool m_isRunning;
	bool m_stopExecution;
	bool m_isSynchronous;

	virtual bool doInitialize() = 0;
	virtual bool doStartUp() = 0;

	/// Implementation of actual work function for this thread, this has a default implementation to handle
	/// destruction better, as it could be called while the thread is under destruction, if left unimplemented
	/// this would trigger a call to a pure virtual function.
	/// \return false when the thread is done, this will stop execution
	virtual bool doUpdate(double dt);

	/// Prepares the thread for its execution to be stopped
	/// \note	Called from this thread before joined
	virtual void doBeforeStop();
};

}; // namespace Framework
}; // namespace SurgSim

#endif // SURGSIM_FRAMEWORK_BASICTHREAD_H