This file is indexed.

/usr/include/sigx-2.0/sigx/lock_acquirer.h is in libsigx-2.0-dev 2.0.2-1build1.

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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
#ifndef _SIGX_LOCK_ACQUIRER_H_
#define _SIGX_LOCK_ACQUIRER_H_

/*
 * Copyright 2006 Klaus Triendl
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free 
 * Software Foundation, 51 Franklin Street, Fifth Floor, 
 * Boston, MA 02110-1301, USA.
*/

/*
 * Inspired by Andrei Alexandrescu's article "volatile - Multithreaded 
 * Programmer's Best Friend":
 * http://www.ddj.com/dept/cpp/184403766
 */

#include <tr1/type_traits>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <sigx/noncopyable.h>
//#include <sigx/nonheapallocatable.h>
#include <sigx/nonpointeraliasing.h>
#include <sigx/lockable_fwddecl.h>
#include <sigx/choose_lock.h>


namespace sigx
{

/**	@addtogroup threadsafety
 *	@{
 */


/**	@short Locks the given mutex and ensures threadsafe write 
 *	access to the given locked type.
 *	
 *	Collects acquisition of a mutex lock and a volatile_cast from a 
 *	volatile object.
 *	A lock_acquirer object is initialized with a lock from an associated mutex 
 *	and a volatile object.
 *	The appropriate lock is chosen by the metafunction choose_lock according to the 
 *	mutex and the locking policy (read/write). Note that because the lock_acquirer is 
 *	scope bound choose_lock must only choose scoped lock types.
 *	
 *	During its lifetime, a lock_acquirer keeps the lock acquired. Also, lock_acquirer 
 *	offers read or write access (according to the locking policy) to the volatile-stripped object. 
 *	Access is granted by a protected friend template function access_acquiree(). 
 *	The volatile_cast is performed by access_acquiree(). 
 *	The cast is semantically valid because lock_acquirer keeps the lock acquired 
 *	for its lifetime.
 *	
 *	If the locking policy is readlock then the lock_acquirer grants only const access to the 
 *	protected variable.
 *	
 *	The following template arguments are used:
 *	- @e T_type The type to be protected by the lock, e.g. an int.
 *	- @e T_mutex The lock, e.g. a Glib::Mutex.
 *	- @e I_islockable Whether T_type derives from lockable_base
 *	
 *	@note The locked type can only be accessed with access_acquiree()
 *	@code
 *	// somewhere
 *	boost::mutex mtx;
 *	int x;
 *	
 *	// a scope somewhere else
 *	{
 *		lock_acquirer<writelock, int, boost::mutex> l(x, mtx);
 *		int& i = access_acquiree(l);
 *		i = 42;
 *	}
 *	@endcode
 */
template<locking_policy I_policy, typename T_type, typename T_mutex, typename T_islockable>
class lock_acquirer: noncopyable/*, nonheapallocatable*/, nonpointeraliasing
{
protected:
    typedef T_type acquired_type;
    typedef T_mutex mutex_type;
    // value_type = acquired_type with top-level reference stripped off
    typedef typename std::tr1::remove_reference<acquired_type>::type value_type;
    // const_or_value_type = unchanged value_type if policy is writelock, const value_type if readlock
    typedef typename boost::mpl::eval_if_c<
        I_policy == readlock, 
        std::tr1::add_const<value_type>, 
        boost::mpl::identity<value_type> 
    >::type const_or_value_type;
    typedef typename std::tr1::add_reference<typename std::tr1::add_volatile<value_type>::type>::type volatile_reference_type;
    typedef typename std::tr1::add_reference<typename std::tr1::remove_volatile<const_or_value_type>::type>::type reference_type;

    /**	@short Gives non-volatile access to the locked type
     *	
     *	Forces the programmer to pass a previously named lock_acquirer object thus
     *	ensuring that the lock is active throughout the usage of the locked object.
     */
    friend reference_type 
    access_acquiree(lock_acquirer& l) throw()
    {
        return l.access_acquiree();
    }


public:
    /**	@short Constructs a lock_acquirer from a volatile type to protect and a lock.
     *	@note Acquires the lock immediately, unlocks when it goes out of scope.
     *	@attention	We rely here on the fact that members are initialized according
     *				to the order in which they are declared in a class, such that
     *				the lock is acquired before _a_value is accessed non-volatile.
     */
    lock_acquirer(volatile_reference_type _a_value, mutex_type& _a_mutex): 
        m_lock(_a_mutex), 
        // volatile_cast
        m_acquiree(const_cast<reference_type>(_a_value))
    {}
    /**	@short	Constructs a lock_acquirer from a volatile type to protect, a lock and 
     *			an additional argument forwarded to the lock constructor.
     *	@note Acquires the lock immediately, unlocks when it goes out of scope
     */
    template<typename T_lockfwd_arg1>
    lock_acquirer(volatile_reference_type _a_value, mutex_type& _a_mutex, T_lockfwd_arg1 lockfwd_arg1): 
        m_lock(_a_mutex, lockfwd_arg1), 
        // volatile_cast
        m_acquiree(const_cast<reference_type>(_a_value))
    {}


protected:		
    /**	@return The locked type with the `volatile" qualifier removed
     */
    reference_type access_acquiree() throw()
    {
        return m_acquiree;
    }
        
        
protected:
    /**	@short lock manager appropriate for the lock type
     */
    typename choose_lock<mutex_type, I_policy>::type m_lock;

    /**	@short non-const reference to the locked object
     */
    reference_type m_acquiree;
};



template<typename T_type, typename T_mutex, typename T_islockable>
class writelock_acquirer: public lock_acquirer<writelock, T_type, T_mutex, T_islockable>
{
    typedef lock_acquirer<writelock, T_type, T_mutex, T_islockable> parent_type;
	typedef typename parent_type::mutex_type mutex_type;
	typedef typename parent_type::volatile_reference_type volatile_reference_type;

public:
    /**	@short Constructs a lock_acquirer from a volatile type to lock and a lock.
     *	@note Acquires the lock immediately, unlocks when it goes out of scope
     */
    writelock_acquirer(volatile_reference_type _a_value, mutex_type& _a_mutex): 
        parent_type(_a_value, _a_mutex)
    {}
    /**	@short	Constructs a lock_acquirer from a volatile type to protect, a lock and 
     *			an additional argument forwarded to the lock constructor.
     *	@note Acquires the lock immediately, unlocks when it goes out of scope
     */
    template<typename T_lockfwd_arg1>
    writelock_acquirer(volatile_reference_type _a_value, mutex_type& _a_mutex, T_lockfwd_arg1 lockfwd_arg1): 
        parent_type(_a_value, _a_mutex, lockfwd_arg1)
    {}
};

template<typename T_type, typename T_mutex, typename T_islockable>
class readlock_acquirer: public lock_acquirer<readlock, T_type, T_mutex, T_islockable>
{
    typedef lock_acquirer<readlock, T_type, T_mutex, T_islockable> parent_type;
	typedef typename parent_type::mutex_type mutex_type;
	typedef typename parent_type::volatile_reference_type volatile_reference_type;

public:
    /**	@short Constructs a lock_acquirer from a volatile type to lock and a lock.
     *	@note Acquires the lock immediately, unlocks when it goes out of scope
     */
    readlock_acquirer(volatile_reference_type _a_value, mutex_type& _a_mutex): 
        parent_type(_a_value, _a_mutex)
    {}
    /**	@short	Constructs a lock_acquirer from a volatile type to protect, a lock and 
     *			an additional argument forwarded to the lock constructor.
     *	@note Acquires the lock immediately, unlocks when it goes out of scope
     */
    template<typename T_lockfwd_arg1>
    readlock_acquirer(volatile_reference_type _a_value, mutex_type& _a_mutex, T_lockfwd_arg1 lockfwd_arg1): 
        parent_type(_a_value, _a_mutex, lockfwd_arg1)
    {}
};

/**	@short Specialization for a lockable_base derived object; locks the given 
 *	lockable object (e.g. a mutex_lockable) and ensures 
 *	threadsafe write access to the locked type.
 *	
 *	Collects acquisition of a mutex lock and a volatile_cast from the volatile 
 *	object contained in the lockable.
 *	A lock_acquirer object is initialized with a lockable object.
 *	During its lifetime, a lock_acquirer keeps the lock acquired. Also, lock_acquirer 
 *	offers write access to the volatile-stripped object. The access is offered 
 *	with a related access_acquiree() function. The volatile_cast is performed by access_acquiree(). 
 *	The cast is semantically valid because lock_acquirer keeps the lock acquired 
 *	for its lifetime.
 *	
 *	The following template arguments are used:
 *	- @e T_lockable A lockable_base derived type, e.g. a mutex_lockable<int>.
 *	
 *	The lock_acquirer chooses the appropriate lock manager for the lock automatically 
 *	by applying the choose_lock.
 *	
 *	@note The locked type can only be accessed with access_acquiree()
 *	@code
 *	// somewhere
 *	mutex_lockable<int> lockable_int;
 *	
 *	// a scope somewhere else
 *	{
 *		lock_acquirer<writelock, mutex_lockable<int> > l(lockable_int);
 *		int& i = access_acquiree(l);
 *		i = 42;
 *	}
 *	@endcode
 */
template<locking_policy I_policy, typename T_type, typename T_mutex>
class lock_acquirer<I_policy, T_type, T_mutex, std::tr1::true_type>: 
    // derive from lock_acquirer for the locked type (which is lockable::acquired_type);
    public lock_acquirer<
        I_policy, 
        // if the lockable is const ...
        typename boost::mpl::eval_if<
            std::tr1::is_const<T_type>, 
            // ... then transfer constness to the type to protect (constness for lockables and the locked type is transitive)
            std::tr1::add_const<typename T_type::acquired_type>, 
            // ... otherwise keep it as specified
            boost::mpl::identity<typename T_type::acquired_type>
        >::type, 
        T_mutex
        // let compiler deduce whether acquired_type is again a lockable
        /*, std::tr1::false_type*/
    >
{
    typedef lock_acquirer<
        I_policy, 
        typename boost::mpl::eval_if<
            std::tr1::is_const<T_type>, 
            std::tr1::add_const<typename T_type::acquired_type>, 
            boost::mpl::identity<typename T_type::acquired_type>
        >::type, 
        T_mutex
        /*, std::tr1::false_type*/
    > parent_type;
    typedef T_type lockable_type;


public:
    /**	@short Constructs a lock_acquirer from a lockable.
     *	@note Acquires the lock immediately, unlocks when it goes out of scope
     */
    explicit lock_acquirer(lockable_type& _a_lockable): 
        parent_type(_a_lockable.access_volatile(), _a_lockable.mutex())
    {}
    /**	@short	Constructs a lock_acquirer from a volatile type to protect, a lock and 
     *			an additional argument forwarded to the lock constructor.
     *	@note Acquires the lock immediately, unlocks when it goes out of scope
     */
    template<typename T_lockfwd_arg1>
    lock_acquirer(lockable_type& _a_lockable, T_lockfwd_arg1 lockfwd_arg1): 
        parent_type(_a_lockable.access_volatile(), _a_lockable.mutex(), lockfwd_arg1)
    {}
};


/**	@short	writelock_acquirer specialization for lockable's.
 */
template<typename T_type, typename T_mutex>
class writelock_acquirer<T_type, T_mutex, std::tr1::true_type>: public lock_acquirer<writelock, T_type, T_mutex, std::tr1::true_type>
{
    typedef lock_acquirer<writelock, T_type, T_mutex, std::tr1::true_type> parent_type;
    typedef T_type lockable_type;


public:
    /**	@short Constructs a lock_acquirer from a lockable.
     *	@note Acquires the lock immediately, unlocks when it goes out of scope
     */
    explicit writelock_acquirer(lockable_type& _a_lockable): 
        parent_type(_a_lockable)
    {}
    /**	@short	Constructs a lock_acquirer from a volatile type to protect, a lock and 
     *			an additional argument forwarded to the lock constructor.
     *	@note Acquires the lock immediately, unlocks when it goes out of scope
     */
    template<typename T_lockfwd_arg1>
    writelock_acquirer(lockable_type& _a_lockable, T_lockfwd_arg1 lockfwd_arg1): 
        parent_type(_a_lockable, lockfwd_arg1)
    {}
};


/**	@short	readlock_acquirer specialization for lockable's.
 */
template<typename T_type, typename T_mutex>
class readlock_acquirer<T_type, T_mutex, std::tr1::true_type>: public lock_acquirer<readlock, T_type, T_mutex, std::tr1::true_type>
{
    typedef lock_acquirer<readlock, T_type, T_mutex, std::tr1::true_type> parent_type;
    typedef T_type lockable_type;


public:
    /**	@short Constructs a lock_acquirer from a lockable.
     *	@note Acquires the lock immediately, unlocks when it goes out of scope
     */
    explicit readlock_acquirer(lockable_type& _a_lockable): 
        parent_type(_a_lockable)
    {}
    /**	@short	Constructs a lock_acquirer from a volatile type to protect, a lock and 
     *			an additional argument forwarded to the lock constructor.
     *	@note Acquires the lock immediately, unlocks when it goes out of scope
     */
    template<typename T_lockfwd_arg1>
    readlock_acquirer(lockable_type& _a_lockable, T_lockfwd_arg1 lockfwd_arg1): 
        parent_type(_a_lockable, lockfwd_arg1)
    {}
};


// @addtogroup threadsafety
/**	@}
 */

} // namespace mbox


#endif // end file guard