This file is indexed.

/usr/include/SurgSim/Framework/LockedContainer.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
191
192
193
194
195
196
197
198
199
200
201
202
// 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_LOCKEDCONTAINER_H
#define SURGSIM_FRAMEWORK_LOCKEDCONTAINER_H

#include <boost/thread/mutex.hpp>
#include <boost/thread/locks.hpp>


namespace SurgSim
{
namespace Framework
{

/// A simple thread-safe data container that can support multiple writers and readers.
///
/// The type of the contained data is determined by the template argument, and should satisfy the following:
///  - It must be either default-constructable or copy-constructable or move-constructable.  In other words,
///    construction must be possible using either <code>T()</code> or <code>T(const T&amp;)</code> or
///    <code>T(T&amp;&amp;)</code>, or compiler-generated equivalents.
///  - It must be either copy-assignable or move-assignable.  In other words, assignment must be possible using
///    either <code>operator=(const T&amp;)</code> or <code>operator=(T&amp;&amp;)</code>, or compiler-generated
///    equivalents.  (If it is only move-assignable, then you can't get the value in the container without
///    erasing it.)
///
/// Note that STL container types, plain-old-data structs, and most other things you might want to use satisfy
/// those requirements.
///
/// The container will create and manage an extra internal instance of the data object.
///
/// The interface has been designed to be incredibly simple.  The trade-off is that the overhead of reading or
/// writing to the container is significant (Each write incurs either a copy or a move of the data, plus a mutex
/// lock/unlock. Each read incurs a copy, plus a mutex lock/unlock.  Applications that write and read heavily
/// may also become mutex-bound.)
///
/// Writers write the data by calling the \ref set method, which copies or moves the data into internal storage.
/// Readers read the data by calling the \ref get method, which copies the data from internal storage.
///
/// \tparam T Type of the data held by the LockedContainer.
template <typename T>
class LockedContainer
{
public:
	/// Create the container and the data it contains.
	///
	/// The data will be initialized using the default constructor.
	LockedContainer() :
		m_buffer(),
		m_haveNewData(false)
	{
	}

	/// Create the container and the data it contains.
	///
	/// The data will be initialized using the copy constructor.
	/// \param initialValue The initial value to be used.
	explicit LockedContainer(const T& initialValue) :
		m_buffer(initialValue),
		m_haveNewData(false)
	{
	}

	/// Create the container and the data it contains.
	///
	/// The data in the active buffer will be initialized using the move constructor.
	/// The data in the second, inactive buffer will be initialized using the default constructor.
	/// \param initialValue The initial value to be moved into the active buffer.
	explicit LockedContainer(T&& initialValue) :
		m_buffer(std::move(initialValue)),
		m_haveNewData(false)
	{
	}


	/// Destroy the container and the data it contains.
	~LockedContainer()
	{
	}

	/// Write (copy) new data into the container.
	///
	/// The data will be copied into internal storage.  If \ref set is called again before the next \ref get,
	/// the first data will be overwritten and lost.
	/// \param value The value to be written.
	void set(const T& value)
	{
		boost::lock_guard<boost::mutex> lock(m_mutex);
		m_buffer = value;
		m_haveNewData = true;
	}

	/// Write (move) new data into the container.
	///
	/// The data will be moved into internal storage.  If \ref set is called again before the next \ref get, the
	/// first data will be overwritten and lost.
	/// \param value The value to be written.
	void set(T&& value)
	{
		boost::lock_guard<boost::mutex> lock(m_mutex);
		m_buffer = std::move(value);
		m_haveNewData = true;
	}

	/// Read (copy) the data from the container.
	/// \param [out] value The location to write the data from the container.  The pointer must be non-null.
	void get(T* value) const
	{
		boost::lock_guard<boost::mutex> lock(m_mutex);
		m_haveNewData = false;
		*value = m_buffer;
	}

	/// Move the data out of the container.
	/// For types that support move assignment, the internal state of the container will be invalidated.
	/// \param [out] value The location to write the data from the container.  The pointer must be non-null.
	void take(T* value)
	{
		boost::lock_guard<boost::mutex> lock(m_mutex);
		m_haveNewData = false;
		*value = std::move(m_buffer);
	}

	/// Read (copy) the data from the container if it has been modified since the last access.
	/// If \ref set has not been called since the last \ref get, \ref take, \ref tryGetChanged or
	/// \ref tryTakeChanged, the method returns \c false and doesn't modify the data.
	///
	/// \param [out] value The location to write the data from the container if it has changed.  The pointer
	/// 	must be non-null.
	/// \return true if there was new data (which may or may not be equal to the old).  Note that the initial
	/// 	value created when the object was constructed (if any) is not considered "new" data by this method.
	bool tryGetChanged(T* value) const
	{
		boost::lock_guard<boost::mutex> lock(m_mutex);
		if (! m_haveNewData)
		{
			return false;
		}
		else
		{
			m_haveNewData = false;
			*value = m_buffer;
			return true;
		}
	}

	/// Move the data out of the container if it has been modified since the last access.
	/// If \ref set has not been called since the last \ref get, \ref take, \ref tryGetChanged or
	/// \ref tryTakeChanged, the method returns \c false and doesn't modify the data.
	///
	/// \param [out] value The location to write the data from the container if it has changed.  The pointer
	/// 	must be non-null.
	/// \return true if there was new data (which may or may not be equal to the old).  Note that the initial
	/// 	value created when the object was constructed (if any) is not considered "new" data by this method.
	bool tryTakeChanged(T* value)
	{
		boost::lock_guard<boost::mutex> lock(m_mutex);
		if (! m_haveNewData)
		{
			return false;
		}
		else
		{
			m_haveNewData = false;
			*value = std::move(m_buffer);
			return true;
		}
	}

private:
	/// Prevent copying
	LockedContainer(const LockedContainer&);
	/// Prevent assignment
	LockedContainer& operator=(const LockedContainer&);


	/// Internal buffer.
	T m_buffer;

	/// True if there data that has been written, but not yet pulled in by get, take, etc.
	mutable bool m_haveNewData;

	/// Mutex for synchronization of set() and get() calls.
	mutable boost::mutex m_mutex;
};

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

#endif  // SURGSIM_FRAMEWORK_LOCKEDCONTAINER_H