This file is indexed.

/usr/include/libfilezilla/mutex.hpp is in libfilezilla-dev 0.11.0-1.

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
#ifndef LIBFILEZILLA_MUTEX_HEADER
#define LIBFILEZILLA_MUTEX_HEADER

/** \file
 * \brief Thread synchronization primitives: mutex, scoped_lock and condition
 */
#include "libfilezilla.hpp"
#include "time.hpp"

#ifdef FZ_WINDOWS
#include "private/windows.hpp"
#else
#include <pthread.h>
#endif

namespace fz {

/**
 * \brief Lean replacement for std::(recursive_)mutex
 *
 * Unfortunately we can't use std::mutex and std::condition_variable as MinGW doesn't implement
 * C++11 threading yet. Even in those variants that at least mutexes and condition variables, they doen't
 * make use of Vista+'s CONDITION_VARIABLE, so it's too slow for our needs.
 *
 * \note Once all platforms have C++11 threading implemented _in the fastest way possible_, this class will be removed.
 */
class FZ_PUBLIC_SYMBOL mutex final
{
public:
	explicit mutex(bool recursive = true);
	~mutex();

	mutex(mutex const&) = delete;
	mutex& operator=(mutex const&) = delete;

	/// Beware, manual locking isn't exception safe, use scoped_lock
	void lock();

	/// Beware, manual locking isn't exception safe, use scoped_lock
	void unlock();

private:
	friend class condition;
	friend class scoped_lock;

#ifdef FZ_WINDOWS
	CRITICAL_SECTION m_;
#else
	pthread_mutex_t m_;
#endif
};

/** \brief A simple scoped lock.
 *
 * The lock is aquired on construction and, if still locked, released on destruction.
 * You can manually unlock and re-lock if needed.
 *
 * \note While this can be used with recursive mutexes, scoped_lock does not implement reference
 * counting.
 */
class FZ_PUBLIC_SYMBOL scoped_lock final
{
public:
	explicit scoped_lock(mutex& m)
		: m_(&m.m_)
	{
#ifdef FZ_WINDOWS
		EnterCriticalSection(m_);
#else
		pthread_mutex_lock(m_);
#endif
	}

	~scoped_lock()
	{
		if (locked_) {
#ifdef FZ_WINDOWS
			LeaveCriticalSection(m_);
#else
			pthread_mutex_unlock(m_);
#endif
		}

	}

	scoped_lock(scoped_lock const&) = delete;
	scoped_lock& operator=(scoped_lock const&) = delete;

	/** \brief Obtains the mutex.
	 *
	 * Locking an already locked scoped_lock results in undefined behavior.
	 */
	void lock()
	{
		locked_ = true;
#ifdef FZ_WINDOWS
		EnterCriticalSection(m_);
#else
		pthread_mutex_lock(m_);
#endif
	}

	/** \brief Releases the mutex.
	 *
	 * Releasing a scoped_lock that isn't locked results in undefined behavior.
	 */
	void unlock()
	{
		locked_ = false;
#ifdef FZ_WINDOWS
		LeaveCriticalSection(m_);
#else
		pthread_mutex_unlock(m_);
#endif
	}

private:
	friend class condition;

#ifdef FZ_WINDOWS
	CRITICAL_SECTION * const m_;
#else
	pthread_mutex_t * const m_;
#endif
	bool locked_{true};
};

/** \brief Waitable condition variable
 *
 * Allows one thread to wait for the condition variable to become signalled by another thread.
 */
class FZ_PUBLIC_SYMBOL condition final
{
public:
	condition();
	~condition();

	condition(condition const&) = delete;
	condition& operator=(condition const&) = delete;

	/** \brief Wait indefinitely for condition to become signalled.
	 *
	 * Atomically unlocks the mutex and waits for the condition. Atomically consumes the signal and re-locks the mutex.
	 *
	 * \note The lock must have be on the same mutex that is used for both signalling and for waiting.
	 */
	void wait(scoped_lock& l);

	/** \brief Wait until timeout for condition to become signalled.
	 *
	 * Atomically unlocks the mutex and waits for the condition. Atomically consumes the signal and re-locks the mutex.
	 *
	 * \return true if the condition has been signalled.
	 * \return false if the condition could not be obtained before the timeout has elapsed.
	 *
	 * \note Spurious signals are a rare possibility.
	 *
	 * \note The lock must have be on the same mutex that is used for both signalling and for waiting.
	 */
	bool wait(scoped_lock& l, duration const& timeout);

	/** \brief Signal condition variable
	 *
	 * To avoid race conditions leading to lost signals, you must pass
	 * a locked mutex.
	 *
	 * \note Spurious signals are a rare possibility.
	 *
	 * \note The lock must have be on the same mutex that is used for both signalling and for waiting.
	 */
	void signal(scoped_lock& l);

	/** \brief Check if condition is already signalled
	 *
	 * To avoid race conditions leading to lost signals, you must pass
	 * a locked mutex.
	 *
	 * \note The lock must have be on the same mutex that is used for both signalling and for waiting.
	 */
	bool signalled(scoped_lock const&) const { return signalled_; }
private:
#ifdef FZ_WINDOWS
	CONDITION_VARIABLE cond_;
#else
	pthread_cond_t cond_;
#endif
	bool signalled_{};
};

}
#endif