~ai.tron/armagetronad/0.4-winlibs-updated

« back to all changes in this revision

Viewing changes to boost/includes/boost/thread/v2/shared_mutex.hpp

  • Committer: Nik K.
  • Date: 2013-11-07 16:58:35 UTC
  • Revision ID: nik.karbaum@gmail.com-20131107165835-kq99jz23drfj4dkh
Forgot to add some files; here they are

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef BOOST_THREAD_V2_SHARED_MUTEX_HPP
 
2
#define BOOST_THREAD_V2_SHARED_MUTEX_HPP
 
3
 
 
4
//  shared_mutex.hpp
 
5
//
 
6
// Copyright Howard Hinnant 2007-2010.
 
7
// Copyright Vicente J. Botet Escriba 2012.
 
8
//
 
9
//  Distributed under the Boost Software License, Version 1.0. (See
 
10
//  accompanying file LICENSE_1_0.txt or copy at
 
11
//  http://www.boost.org/LICENSE_1_0.txt)
 
12
 
 
13
/*
 
14
<shared_mutex> synopsis
 
15
 
 
16
namespace boost
 
17
{
 
18
namespace thread_v2
 
19
{
 
20
 
 
21
class shared_mutex
 
22
{
 
23
public:
 
24
 
 
25
    shared_mutex();
 
26
    ~shared_mutex();
 
27
 
 
28
    shared_mutex(const shared_mutex&) = delete;
 
29
    shared_mutex& operator=(const shared_mutex&) = delete;
 
30
 
 
31
    // Exclusive ownership
 
32
 
 
33
    void lock();
 
34
    bool try_lock();
 
35
    template <class Rep, class Period>
 
36
        bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time);
 
37
    template <class Clock, class Duration>
 
38
        bool
 
39
        try_lock_until(
 
40
                      const boost::chrono::time_point<Clock, Duration>& abs_time);
 
41
    void unlock();
 
42
 
 
43
    // Shared ownership
 
44
 
 
45
    void lock_shared();
 
46
    bool try_lock_shared();
 
47
    template <class Rep, class Period>
 
48
        bool
 
49
        try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time);
 
50
    template <class Clock, class Duration>
 
51
        bool
 
52
        try_lock_shared_until(
 
53
                      const boost::chrono::time_point<Clock, Duration>& abs_time);
 
54
    void unlock_shared();
 
55
};
 
56
 
 
57
class upgrade_mutex
 
58
{
 
59
public:
 
60
 
 
61
    upgrade_mutex();
 
62
    ~upgrade_mutex();
 
63
 
 
64
    upgrade_mutex(const upgrade_mutex&) = delete;
 
65
    upgrade_mutex& operator=(const upgrade_mutex&) = delete;
 
66
 
 
67
    // Exclusive ownership
 
68
 
 
69
    void lock();
 
70
    bool try_lock();
 
71
    template <class Rep, class Period>
 
72
        bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time);
 
73
    template <class Clock, class Duration>
 
74
        bool
 
75
        try_lock_until(
 
76
                      const boost::chrono::time_point<Clock, Duration>& abs_time);
 
77
    void unlock();
 
78
 
 
79
    // Shared ownership
 
80
 
 
81
    void lock_shared();
 
82
    bool try_lock_shared();
 
83
    template <class Rep, class Period>
 
84
        bool
 
85
        try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time);
 
86
    template <class Clock, class Duration>
 
87
        bool
 
88
        try_lock_shared_until(
 
89
                      const boost::chrono::time_point<Clock, Duration>& abs_time);
 
90
    void unlock_shared();
 
91
 
 
92
    // Upgrade ownership
 
93
 
 
94
    void lock_upgrade();
 
95
    bool try_lock_upgrade();
 
96
    template <class Rep, class Period>
 
97
        bool
 
98
        try_lock_upgrade_for(
 
99
                            const boost::chrono::duration<Rep, Period>& rel_time);
 
100
    template <class Clock, class Duration>
 
101
        bool
 
102
        try_lock_upgrade_until(
 
103
                      const boost::chrono::time_point<Clock, Duration>& abs_time);
 
104
    void unlock_upgrade();
 
105
 
 
106
    // Shared <-> Exclusive
 
107
 
 
108
    bool try_unlock_shared_and_lock();
 
109
    template <class Rep, class Period>
 
110
        bool
 
111
        try_unlock_shared_and_lock_for(
 
112
                            const boost::chrono::duration<Rep, Period>& rel_time);
 
113
    template <class Clock, class Duration>
 
114
        bool
 
115
        try_unlock_shared_and_lock_until(
 
116
                      const boost::chrono::time_point<Clock, Duration>& abs_time);
 
117
    void unlock_and_lock_shared();
 
118
 
 
119
    // Shared <-> Upgrade
 
120
 
 
121
    bool try_unlock_shared_and_lock_upgrade();
 
122
    template <class Rep, class Period>
 
123
        bool
 
124
        try_unlock_shared_and_lock_upgrade_for(
 
125
                            const boost::chrono::duration<Rep, Period>& rel_time);
 
126
    template <class Clock, class Duration>
 
127
        bool
 
128
        try_unlock_shared_and_lock_upgrade_until(
 
129
                      const boost::chrono::time_point<Clock, Duration>& abs_time);
 
130
    void unlock_upgrade_and_lock_shared();
 
131
 
 
132
    // Upgrade <-> Exclusive
 
133
 
 
134
    void unlock_upgrade_and_lock();
 
135
    bool try_unlock_upgrade_and_lock();
 
136
    template <class Rep, class Period>
 
137
        bool
 
138
        try_unlock_upgrade_and_lock_for(
 
139
                            const boost::chrono::duration<Rep, Period>& rel_time);
 
140
    template <class Clock, class Duration>
 
141
        bool
 
142
        try_unlock_upgrade_and_lock_until(
 
143
                      const boost::chrono::time_point<Clock, Duration>& abs_time);
 
144
    void unlock_and_lock_upgrade();
 
145
};
 
146
 
 
147
}  // thread_v2
 
148
}  // boost
 
149
 
 
150
 */
 
151
 
 
152
#include <boost/thread/detail/config.hpp>
 
153
#include <boost/thread/mutex.hpp>
 
154
#include <boost/thread/condition_variable.hpp>
 
155
#include <boost/thread/mutex.hpp>
 
156
#include <boost/chrono.hpp>
 
157
#include <climits>
 
158
#include <boost/system/system_error.hpp>
 
159
#define BOOST_THREAD_INLINE inline
 
160
 
 
161
namespace boost {
 
162
  namespace thread_v2 {
 
163
 
 
164
    class shared_mutex
 
165
    {
 
166
      typedef ::boost::mutex              mutex_t;
 
167
      typedef ::boost::condition_variable cond_t;
 
168
      typedef unsigned                count_t;
 
169
 
 
170
      mutex_t mut_;
 
171
      cond_t  gate1_;
 
172
      cond_t  gate2_;
 
173
      count_t state_;
 
174
 
 
175
      static const count_t write_entered_ = 1U << (sizeof(count_t)*CHAR_BIT - 1);
 
176
      static const count_t n_readers_ = ~write_entered_;
 
177
 
 
178
    public:
 
179
      BOOST_THREAD_INLINE shared_mutex();
 
180
      BOOST_THREAD_INLINE ~shared_mutex();
 
181
 
 
182
#ifndef BOOST_NO_DELETED_FUNCTIONS
 
183
      shared_mutex(shared_mutex const&) = delete;
 
184
      shared_mutex& operator=(shared_mutex const&) = delete;
 
185
#else // BOOST_NO_DELETED_FUNCTIONS
 
186
    private:
 
187
      shared_mutex(shared_mutex const&);
 
188
      shared_mutex& operator=(shared_mutex const&);
 
189
    public:
 
190
#endif // BOOST_NO_DELETED_FUNCTIONS
 
191
 
 
192
      // Exclusive ownership
 
193
 
 
194
      BOOST_THREAD_INLINE void lock();
 
195
      BOOST_THREAD_INLINE bool try_lock();
 
196
      template <class Rep, class Period>
 
197
      bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time)
 
198
      {
 
199
        return try_lock_until(boost::chrono::steady_clock::now() + rel_time);
 
200
      }
 
201
      template <class Clock, class Duration>
 
202
      bool
 
203
      try_lock_until(
 
204
          const boost::chrono::time_point<Clock, Duration>& abs_time);
 
205
      BOOST_THREAD_INLINE void unlock();
 
206
 
 
207
 
 
208
      // Shared ownership
 
209
 
 
210
      BOOST_THREAD_INLINE void lock_shared();
 
211
      BOOST_THREAD_INLINE bool try_lock_shared();
 
212
      template <class Rep, class Period>
 
213
      bool
 
214
      try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
 
215
      {
 
216
        return try_lock_shared_until(boost::chrono::steady_clock::now() +
 
217
            rel_time);
 
218
      }
 
219
      template <class Clock, class Duration>
 
220
      bool
 
221
      try_lock_shared_until(
 
222
          const boost::chrono::time_point<Clock, Duration>& abs_time);
 
223
      BOOST_THREAD_INLINE void unlock_shared();
 
224
 
 
225
#if defined BOOST_THREAD_USES_DATETIME
 
226
      bool timed_lock(system_time const& timeout);
 
227
      template<typename TimeDuration>
 
228
      bool timed_lock(TimeDuration const & relative_time)
 
229
      {
 
230
          return timed_lock(get_system_time()+relative_time);
 
231
      }
 
232
      bool timed_lock_shared(system_time const& timeout);
 
233
      template<typename TimeDuration>
 
234
      bool timed_lock_shared(TimeDuration const & relative_time)
 
235
      {
 
236
        return timed_lock_shared(get_system_time()+relative_time);
 
237
      }
 
238
#endif
 
239
    };
 
240
 
 
241
    template <class Clock, class Duration>
 
242
    bool
 
243
    shared_mutex::try_lock_until(
 
244
        const boost::chrono::time_point<Clock, Duration>& abs_time)
 
245
    {
 
246
      boost::unique_lock<mutex_t> lk(mut_);
 
247
      if (state_ & write_entered_)
 
248
      {
 
249
        while (true)
 
250
        {
 
251
          boost::cv_status status = gate1_.wait_until(lk, abs_time);
 
252
          if ((state_ & write_entered_) == 0)
 
253
            break;
 
254
          if (status == boost::cv_status::timeout)
 
255
            return false;
 
256
        }
 
257
      }
 
258
      state_ |= write_entered_;
 
259
      if (state_ & n_readers_)
 
260
      {
 
261
        while (true)
 
262
        {
 
263
          boost::cv_status status = gate2_.wait_until(lk, abs_time);
 
264
          if ((state_ & n_readers_) == 0)
 
265
            break;
 
266
          if (status == boost::cv_status::timeout)
 
267
          {
 
268
            state_ &= ~write_entered_;
 
269
            return false;
 
270
          }
 
271
        }
 
272
      }
 
273
      return true;
 
274
    }
 
275
 
 
276
    template <class Clock, class Duration>
 
277
    bool
 
278
    shared_mutex::try_lock_shared_until(
 
279
        const boost::chrono::time_point<Clock, Duration>& abs_time)
 
280
    {
 
281
      boost::unique_lock<mutex_t> lk(mut_);
 
282
      if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
 
283
      {
 
284
        while (true)
 
285
        {
 
286
          boost::cv_status status = gate1_.wait_until(lk, abs_time);
 
287
          if ((state_ & write_entered_) == 0 &&
 
288
              (state_ & n_readers_) < n_readers_)
 
289
            break;
 
290
          if (status == boost::cv_status::timeout)
 
291
            return false;
 
292
        }
 
293
      }
 
294
      count_t num_readers = (state_ & n_readers_) + 1;
 
295
      state_ &= ~n_readers_;
 
296
      state_ |= num_readers;
 
297
      return true;
 
298
    }
 
299
 
 
300
#if defined BOOST_THREAD_USES_DATETIME
 
301
    bool shared_mutex::timed_lock(system_time const& abs_time)
 
302
    {
 
303
      boost::unique_lock<mutex_t> lk(mut_);
 
304
      if (state_ & write_entered_)
 
305
      {
 
306
        while (true)
 
307
        {
 
308
          bool status = gate1_.timed_wait(lk, abs_time);
 
309
          if ((state_ & write_entered_) == 0)
 
310
            break;
 
311
          if (!status)
 
312
            return false;
 
313
        }
 
314
      }
 
315
      state_ |= write_entered_;
 
316
      if (state_ & n_readers_)
 
317
      {
 
318
        while (true)
 
319
        {
 
320
          bool status = gate2_.timed_wait(lk, abs_time);
 
321
          if ((state_ & n_readers_) == 0)
 
322
            break;
 
323
          if (!status)
 
324
          {
 
325
            state_ &= ~write_entered_;
 
326
            return false;
 
327
          }
 
328
        }
 
329
      }
 
330
      return true;
 
331
    }
 
332
      bool shared_mutex::timed_lock_shared(system_time const& abs_time)
 
333
      {
 
334
        boost::unique_lock<mutex_t> lk(mut_);
 
335
        if (state_ & write_entered_)
 
336
        {
 
337
          while (true)
 
338
          {
 
339
            bool status = gate1_.timed_wait(lk, abs_time);
 
340
            if ((state_ & write_entered_) == 0)
 
341
              break;
 
342
            if (!status )
 
343
              return false;
 
344
          }
 
345
        }
 
346
        state_ |= write_entered_;
 
347
        if (state_ & n_readers_)
 
348
        {
 
349
          while (true)
 
350
          {
 
351
            bool status = gate2_.timed_wait(lk, abs_time);
 
352
            if ((state_ & n_readers_) == 0)
 
353
              break;
 
354
            if (!status)
 
355
            {
 
356
              state_ &= ~write_entered_;
 
357
              return false;
 
358
            }
 
359
          }
 
360
        }
 
361
        return true;
 
362
      }
 
363
#endif
 
364
    class upgrade_mutex
 
365
    {
 
366
      typedef boost::mutex              mutex_t;
 
367
      typedef boost::condition_variable cond_t;
 
368
      typedef unsigned                count_t;
 
369
 
 
370
      mutex_t mut_;
 
371
      cond_t  gate1_;
 
372
      cond_t  gate2_;
 
373
      count_t state_;
 
374
 
 
375
      static const unsigned write_entered_ = 1U << (sizeof(count_t)*CHAR_BIT - 1);
 
376
      static const unsigned upgradable_entered_ = write_entered_ >> 1;
 
377
      static const unsigned n_readers_ = ~(write_entered_ | upgradable_entered_);
 
378
 
 
379
    public:
 
380
 
 
381
      BOOST_THREAD_INLINE upgrade_mutex();
 
382
      BOOST_THREAD_INLINE ~upgrade_mutex();
 
383
 
 
384
#ifndef BOOST_NO_DELETED_FUNCTIONS
 
385
      upgrade_mutex(const upgrade_mutex&) = delete;
 
386
      upgrade_mutex& operator=(const upgrade_mutex&) = delete;
 
387
#else // BOOST_NO_DELETED_FUNCTIONS
 
388
    private:
 
389
      upgrade_mutex(const upgrade_mutex&);
 
390
      upgrade_mutex& operator=(const upgrade_mutex&);
 
391
    public:
 
392
#endif // BOOST_NO_DELETED_FUNCTIONS
 
393
 
 
394
      // Exclusive ownership
 
395
 
 
396
      BOOST_THREAD_INLINE void lock();
 
397
      BOOST_THREAD_INLINE bool try_lock();
 
398
      template <class Rep, class Period>
 
399
      bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time)
 
400
      {
 
401
        return try_lock_until(boost::chrono::steady_clock::now() + rel_time);
 
402
      }
 
403
      template <class Clock, class Duration>
 
404
      bool
 
405
      try_lock_until(
 
406
          const boost::chrono::time_point<Clock, Duration>& abs_time);
 
407
      BOOST_THREAD_INLINE void unlock();
 
408
 
 
409
      // Shared ownership
 
410
 
 
411
      BOOST_THREAD_INLINE void lock_shared();
 
412
      BOOST_THREAD_INLINE bool try_lock_shared();
 
413
      template <class Rep, class Period>
 
414
      bool
 
415
      try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
 
416
      {
 
417
        return try_lock_shared_until(boost::chrono::steady_clock::now() +
 
418
            rel_time);
 
419
      }
 
420
      template <class Clock, class Duration>
 
421
      bool
 
422
      try_lock_shared_until(
 
423
          const boost::chrono::time_point<Clock, Duration>& abs_time);
 
424
      BOOST_THREAD_INLINE void unlock_shared();
 
425
 
 
426
      // Upgrade ownership
 
427
 
 
428
      BOOST_THREAD_INLINE void lock_upgrade();
 
429
      BOOST_THREAD_INLINE bool try_lock_upgrade();
 
430
      template <class Rep, class Period>
 
431
      bool
 
432
      try_lock_upgrade_for(
 
433
          const boost::chrono::duration<Rep, Period>& rel_time)
 
434
      {
 
435
        return try_lock_upgrade_until(boost::chrono::steady_clock::now() +
 
436
            rel_time);
 
437
      }
 
438
      template <class Clock, class Duration>
 
439
      bool
 
440
      try_lock_upgrade_until(
 
441
          const boost::chrono::time_point<Clock, Duration>& abs_time);
 
442
      BOOST_THREAD_INLINE void unlock_upgrade();
 
443
 
 
444
      // Shared <-> Exclusive
 
445
 
 
446
      BOOST_THREAD_INLINE bool try_unlock_shared_and_lock();
 
447
      template <class Rep, class Period>
 
448
      bool
 
449
      try_unlock_shared_and_lock_for(
 
450
          const boost::chrono::duration<Rep, Period>& rel_time)
 
451
      {
 
452
        return try_unlock_shared_and_lock_until(
 
453
            boost::chrono::steady_clock::now() + rel_time);
 
454
      }
 
455
      template <class Clock, class Duration>
 
456
      bool
 
457
      try_unlock_shared_and_lock_until(
 
458
          const boost::chrono::time_point<Clock, Duration>& abs_time);
 
459
      BOOST_THREAD_INLINE void unlock_and_lock_shared();
 
460
 
 
461
      // Shared <-> Upgrade
 
462
 
 
463
      BOOST_THREAD_INLINE bool try_unlock_shared_and_lock_upgrade();
 
464
      template <class Rep, class Period>
 
465
      bool
 
466
      try_unlock_shared_and_lock_upgrade_for(
 
467
          const boost::chrono::duration<Rep, Period>& rel_time)
 
468
      {
 
469
        return try_unlock_shared_and_lock_upgrade_until(
 
470
            boost::chrono::steady_clock::now() + rel_time);
 
471
      }
 
472
      template <class Clock, class Duration>
 
473
      bool
 
474
      try_unlock_shared_and_lock_upgrade_until(
 
475
          const boost::chrono::time_point<Clock, Duration>& abs_time);
 
476
      BOOST_THREAD_INLINE void unlock_upgrade_and_lock_shared();
 
477
 
 
478
      // Upgrade <-> Exclusive
 
479
 
 
480
      BOOST_THREAD_INLINE void unlock_upgrade_and_lock();
 
481
      BOOST_THREAD_INLINE bool try_unlock_upgrade_and_lock();
 
482
      template <class Rep, class Period>
 
483
      bool
 
484
      try_unlock_upgrade_and_lock_for(
 
485
          const boost::chrono::duration<Rep, Period>& rel_time)
 
486
      {
 
487
        return try_unlock_upgrade_and_lock_until(
 
488
            boost::chrono::steady_clock::now() + rel_time);
 
489
      }
 
490
      template <class Clock, class Duration>
 
491
      bool
 
492
      try_unlock_upgrade_and_lock_until(
 
493
          const boost::chrono::time_point<Clock, Duration>& abs_time);
 
494
      BOOST_THREAD_INLINE void unlock_and_lock_upgrade();
 
495
 
 
496
#if defined BOOST_THREAD_USES_DATETIME
 
497
      inline bool timed_lock(system_time const& abs_time);
 
498
      template<typename TimeDuration>
 
499
      bool timed_lock(TimeDuration const & relative_time)
 
500
      {
 
501
          return timed_lock(get_system_time()+relative_time);
 
502
      }
 
503
      inline bool timed_lock_shared(system_time const& abs_time);
 
504
      template<typename TimeDuration>
 
505
      bool timed_lock_shared(TimeDuration const & relative_time)
 
506
      {
 
507
        return timed_lock_shared(get_system_time()+relative_time);
 
508
      }
 
509
      inline bool timed_lock_upgrade(system_time const& abs_time);
 
510
      template<typename TimeDuration>
 
511
      bool timed_lock_upgrade(TimeDuration const & relative_time)
 
512
      {
 
513
          return timed_lock_upgrade(get_system_time()+relative_time);
 
514
      }
 
515
#endif
 
516
 
 
517
    };
 
518
 
 
519
    template <class Clock, class Duration>
 
520
    bool
 
521
    upgrade_mutex::try_lock_until(
 
522
        const boost::chrono::time_point<Clock, Duration>& abs_time)
 
523
    {
 
524
      boost::unique_lock<mutex_t> lk(mut_);
 
525
      if (state_ & (write_entered_ | upgradable_entered_))
 
526
      {
 
527
        while (true)
 
528
        {
 
529
          boost::cv_status status = gate1_.wait_until(lk, abs_time);
 
530
          if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
 
531
            break;
 
532
          if (status == boost::cv_status::timeout)
 
533
            return false;
 
534
        }
 
535
      }
 
536
      state_ |= write_entered_;
 
537
      if (state_ & n_readers_)
 
538
      {
 
539
        while (true)
 
540
        {
 
541
          boost::cv_status status = gate2_.wait_until(lk, abs_time);
 
542
          if ((state_ & n_readers_) == 0)
 
543
            break;
 
544
          if (status == boost::cv_status::timeout)
 
545
          {
 
546
            state_ &= ~write_entered_;
 
547
            return false;
 
548
          }
 
549
        }
 
550
      }
 
551
      return true;
 
552
    }
 
553
 
 
554
    template <class Clock, class Duration>
 
555
    bool
 
556
    upgrade_mutex::try_lock_shared_until(
 
557
        const boost::chrono::time_point<Clock, Duration>& abs_time)
 
558
    {
 
559
      boost::unique_lock<mutex_t> lk(mut_);
 
560
      if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
 
561
      {
 
562
        while (true)
 
563
        {
 
564
          boost::cv_status status = gate1_.wait_until(lk, abs_time);
 
565
          if ((state_ & write_entered_) == 0 &&
 
566
              (state_ & n_readers_) < n_readers_)
 
567
            break;
 
568
          if (status == boost::cv_status::timeout)
 
569
            return false;
 
570
        }
 
571
      }
 
572
      count_t num_readers = (state_ & n_readers_) + 1;
 
573
      state_ &= ~n_readers_;
 
574
      state_ |= num_readers;
 
575
      return true;
 
576
    }
 
577
 
 
578
    template <class Clock, class Duration>
 
579
    bool
 
580
    upgrade_mutex::try_lock_upgrade_until(
 
581
        const boost::chrono::time_point<Clock, Duration>& abs_time)
 
582
    {
 
583
      boost::unique_lock<mutex_t> lk(mut_);
 
584
      if ((state_ & (write_entered_ | upgradable_entered_)) ||
 
585
          (state_ & n_readers_) == n_readers_)
 
586
      {
 
587
        while (true)
 
588
        {
 
589
          boost::cv_status status = gate1_.wait_until(lk, abs_time);
 
590
          if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
 
591
              (state_ & n_readers_) < n_readers_)
 
592
            break;
 
593
          if (status == boost::cv_status::timeout)
 
594
            return false;
 
595
        }
 
596
      }
 
597
      count_t num_readers = (state_ & n_readers_) + 1;
 
598
      state_ &= ~n_readers_;
 
599
      state_ |= upgradable_entered_ | num_readers;
 
600
      return true;
 
601
    }
 
602
 
 
603
#if defined BOOST_THREAD_USES_DATETIME
 
604
      bool upgrade_mutex::timed_lock(system_time const& abs_time)
 
605
      {
 
606
        boost::unique_lock<mutex_t> lk(mut_);
 
607
        if (state_ & (write_entered_ | upgradable_entered_))
 
608
        {
 
609
          while (true)
 
610
          {
 
611
            bool status = gate1_.timed_wait(lk, abs_time);
 
612
            if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
 
613
              break;
 
614
            if (!status)
 
615
              return false;
 
616
          }
 
617
        }
 
618
        state_ |= write_entered_;
 
619
        if (state_ & n_readers_)
 
620
        {
 
621
          while (true)
 
622
          {
 
623
            bool status = gate2_.timed_wait(lk, abs_time);
 
624
            if ((state_ & n_readers_) == 0)
 
625
              break;
 
626
            if (!status)
 
627
            {
 
628
              state_ &= ~write_entered_;
 
629
              return false;
 
630
            }
 
631
          }
 
632
        }
 
633
        return true;
 
634
      }
 
635
      bool upgrade_mutex::timed_lock_shared(system_time const& abs_time)
 
636
      {
 
637
        boost::unique_lock<mutex_t> lk(mut_);
 
638
        if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
 
639
        {
 
640
          while (true)
 
641
          {
 
642
            bool status = gate1_.timed_wait(lk, abs_time);
 
643
            if ((state_ & write_entered_) == 0 &&
 
644
                (state_ & n_readers_) < n_readers_)
 
645
              break;
 
646
            if (!status)
 
647
              return false;
 
648
          }
 
649
        }
 
650
        count_t num_readers = (state_ & n_readers_) + 1;
 
651
        state_ &= ~n_readers_;
 
652
        state_ |= num_readers;
 
653
        return true;
 
654
      }
 
655
      bool upgrade_mutex::timed_lock_upgrade(system_time const& abs_time)
 
656
      {
 
657
        boost::unique_lock<mutex_t> lk(mut_);
 
658
        if ((state_ & (write_entered_ | upgradable_entered_)) ||
 
659
            (state_ & n_readers_) == n_readers_)
 
660
        {
 
661
          while (true)
 
662
          {
 
663
            bool status = gate1_.timed_wait(lk, abs_time);
 
664
            if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
 
665
                (state_ & n_readers_) < n_readers_)
 
666
              break;
 
667
            if (!status)
 
668
              return false;
 
669
          }
 
670
        }
 
671
        count_t num_readers = (state_ & n_readers_) + 1;
 
672
        state_ &= ~n_readers_;
 
673
        state_ |= upgradable_entered_ | num_readers;
 
674
        return true;
 
675
      }
 
676
 
 
677
#endif
 
678
    template <class Clock, class Duration>
 
679
    bool
 
680
    upgrade_mutex::try_unlock_shared_and_lock_until(
 
681
        const boost::chrono::time_point<Clock, Duration>& abs_time)
 
682
    {
 
683
      boost::unique_lock<mutex_t> lk(mut_);
 
684
      if (state_ != 1)
 
685
      {
 
686
        while (true)
 
687
        {
 
688
          boost::cv_status status = gate2_.wait_until(lk, abs_time);
 
689
          if (state_ == 1)
 
690
            break;
 
691
          if (status == boost::cv_status::timeout)
 
692
            return false;
 
693
        }
 
694
      }
 
695
      state_ = write_entered_;
 
696
      return true;
 
697
    }
 
698
 
 
699
    template <class Clock, class Duration>
 
700
    bool
 
701
    upgrade_mutex::try_unlock_shared_and_lock_upgrade_until(
 
702
        const boost::chrono::time_point<Clock, Duration>& abs_time)
 
703
    {
 
704
      boost::unique_lock<mutex_t> lk(mut_);
 
705
      if ((state_ & (write_entered_ | upgradable_entered_)) != 0)
 
706
      {
 
707
        while (true)
 
708
        {
 
709
          boost::cv_status status = gate2_.wait_until(lk, abs_time);
 
710
          if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
 
711
            break;
 
712
          if (status == boost::cv_status::timeout)
 
713
            return false;
 
714
        }
 
715
      }
 
716
      state_ |= upgradable_entered_;
 
717
      return true;
 
718
    }
 
719
 
 
720
    template <class Clock, class Duration>
 
721
    bool
 
722
    upgrade_mutex::try_unlock_upgrade_and_lock_until(
 
723
        const boost::chrono::time_point<Clock, Duration>& abs_time)
 
724
    {
 
725
      boost::unique_lock<mutex_t> lk(mut_);
 
726
      if ((state_ & n_readers_) != 1)
 
727
      {
 
728
        while (true)
 
729
        {
 
730
          boost::cv_status status = gate2_.wait_until(lk, abs_time);
 
731
          if ((state_ & n_readers_) == 1)
 
732
            break;
 
733
          if (status == boost::cv_status::timeout)
 
734
            return false;
 
735
        }
 
736
      }
 
737
      state_ = write_entered_;
 
738
      return true;
 
739
    }
 
740
 
 
741
    //////
 
742
    // shared_mutex
 
743
 
 
744
    shared_mutex::shared_mutex()
 
745
    : state_(0)
 
746
    {
 
747
    }
 
748
 
 
749
    shared_mutex::~shared_mutex()
 
750
    {
 
751
      boost::lock_guard<mutex_t> _(mut_);
 
752
    }
 
753
 
 
754
    // Exclusive ownership
 
755
 
 
756
    void
 
757
    shared_mutex::lock()
 
758
    {
 
759
      boost::unique_lock<mutex_t> lk(mut_);
 
760
      while (state_ & write_entered_)
 
761
        gate1_.wait(lk);
 
762
      state_ |= write_entered_;
 
763
      while (state_ & n_readers_)
 
764
        gate2_.wait(lk);
 
765
    }
 
766
 
 
767
    bool
 
768
    shared_mutex::try_lock()
 
769
    {
 
770
      boost::unique_lock<mutex_t> lk(mut_);
 
771
      if (state_ == 0)
 
772
      {
 
773
        state_ = write_entered_;
 
774
        return true;
 
775
      }
 
776
      return false;
 
777
    }
 
778
 
 
779
    void
 
780
    shared_mutex::unlock()
 
781
    {
 
782
      boost::lock_guard<mutex_t> _(mut_);
 
783
      state_ = 0;
 
784
      gate1_.notify_all();
 
785
    }
 
786
 
 
787
    // Shared ownership
 
788
 
 
789
    void
 
790
    shared_mutex::lock_shared()
 
791
    {
 
792
      boost::unique_lock<mutex_t> lk(mut_);
 
793
      while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
 
794
        gate1_.wait(lk);
 
795
      count_t num_readers = (state_ & n_readers_) + 1;
 
796
      state_ &= ~n_readers_;
 
797
      state_ |= num_readers;
 
798
    }
 
799
 
 
800
    bool
 
801
    shared_mutex::try_lock_shared()
 
802
    {
 
803
      boost::unique_lock<mutex_t> lk(mut_);
 
804
      count_t num_readers = state_ & n_readers_;
 
805
      if (!(state_ & write_entered_) && num_readers != n_readers_)
 
806
      {
 
807
        ++num_readers;
 
808
        state_ &= ~n_readers_;
 
809
        state_ |= num_readers;
 
810
        return true;
 
811
      }
 
812
      return false;
 
813
    }
 
814
 
 
815
    void
 
816
    shared_mutex::unlock_shared()
 
817
    {
 
818
      boost::lock_guard<mutex_t> _(mut_);
 
819
      count_t num_readers = (state_ & n_readers_) - 1;
 
820
      state_ &= ~n_readers_;
 
821
      state_ |= num_readers;
 
822
      if (state_ & write_entered_)
 
823
      {
 
824
        if (num_readers == 0)
 
825
          gate2_.notify_one();
 
826
      }
 
827
      else
 
828
      {
 
829
        if (num_readers == n_readers_ - 1)
 
830
          gate1_.notify_one();
 
831
      }
 
832
    }
 
833
 
 
834
    // upgrade_mutex
 
835
 
 
836
    upgrade_mutex::upgrade_mutex()
 
837
    : gate1_(),
 
838
      gate2_(),
 
839
      state_(0)
 
840
    {
 
841
    }
 
842
 
 
843
    upgrade_mutex::~upgrade_mutex()
 
844
    {
 
845
      boost::lock_guard<mutex_t> _(mut_);
 
846
    }
 
847
 
 
848
    // Exclusive ownership
 
849
 
 
850
    void
 
851
    upgrade_mutex::lock()
 
852
    {
 
853
      boost::unique_lock<mutex_t> lk(mut_);
 
854
      while (state_ & (write_entered_ | upgradable_entered_))
 
855
        gate1_.wait(lk);
 
856
      state_ |= write_entered_;
 
857
      while (state_ & n_readers_)
 
858
        gate2_.wait(lk);
 
859
    }
 
860
 
 
861
    bool
 
862
    upgrade_mutex::try_lock()
 
863
    {
 
864
      boost::unique_lock<mutex_t> lk(mut_);
 
865
      if (state_ == 0)
 
866
      {
 
867
        state_ = write_entered_;
 
868
        return true;
 
869
      }
 
870
      return false;
 
871
    }
 
872
 
 
873
    void
 
874
    upgrade_mutex::unlock()
 
875
    {
 
876
      boost::lock_guard<mutex_t> _(mut_);
 
877
      state_ = 0;
 
878
      gate1_.notify_all();
 
879
    }
 
880
 
 
881
    // Shared ownership
 
882
 
 
883
    void
 
884
    upgrade_mutex::lock_shared()
 
885
    {
 
886
      boost::unique_lock<mutex_t> lk(mut_);
 
887
      while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
 
888
        gate1_.wait(lk);
 
889
      count_t num_readers = (state_ & n_readers_) + 1;
 
890
      state_ &= ~n_readers_;
 
891
      state_ |= num_readers;
 
892
    }
 
893
 
 
894
    bool
 
895
    upgrade_mutex::try_lock_shared()
 
896
    {
 
897
      boost::unique_lock<mutex_t> lk(mut_);
 
898
      count_t num_readers = state_ & n_readers_;
 
899
      if (!(state_ & write_entered_) && num_readers != n_readers_)
 
900
      {
 
901
        ++num_readers;
 
902
        state_ &= ~n_readers_;
 
903
        state_ |= num_readers;
 
904
        return true;
 
905
      }
 
906
      return false;
 
907
    }
 
908
 
 
909
    void
 
910
    upgrade_mutex::unlock_shared()
 
911
    {
 
912
      boost::lock_guard<mutex_t> _(mut_);
 
913
      count_t num_readers = (state_ & n_readers_) - 1;
 
914
      state_ &= ~n_readers_;
 
915
      state_ |= num_readers;
 
916
      if (state_ & write_entered_)
 
917
      {
 
918
        if (num_readers == 0)
 
919
          gate2_.notify_one();
 
920
      }
 
921
      else
 
922
      {
 
923
        if (num_readers == n_readers_ - 1)
 
924
          gate1_.notify_one();
 
925
      }
 
926
    }
 
927
 
 
928
    // Upgrade ownership
 
929
 
 
930
    void
 
931
    upgrade_mutex::lock_upgrade()
 
932
    {
 
933
      boost::unique_lock<mutex_t> lk(mut_);
 
934
      while ((state_ & (write_entered_ | upgradable_entered_)) ||
 
935
          (state_ & n_readers_) == n_readers_)
 
936
        gate1_.wait(lk);
 
937
      count_t num_readers = (state_ & n_readers_) + 1;
 
938
      state_ &= ~n_readers_;
 
939
      state_ |= upgradable_entered_ | num_readers;
 
940
    }
 
941
 
 
942
    bool
 
943
    upgrade_mutex::try_lock_upgrade()
 
944
    {
 
945
      boost::unique_lock<mutex_t> lk(mut_);
 
946
      count_t num_readers = state_ & n_readers_;
 
947
      if (!(state_ & (write_entered_ | upgradable_entered_))
 
948
          && num_readers != n_readers_)
 
949
      {
 
950
        ++num_readers;
 
951
        state_ &= ~n_readers_;
 
952
        state_ |= upgradable_entered_ | num_readers;
 
953
        return true;
 
954
      }
 
955
      return false;
 
956
    }
 
957
 
 
958
    void
 
959
    upgrade_mutex::unlock_upgrade()
 
960
    {
 
961
      {
 
962
        boost::lock_guard<mutex_t> _(mut_);
 
963
        count_t num_readers = (state_ & n_readers_) - 1;
 
964
        state_ &= ~(upgradable_entered_ | n_readers_);
 
965
        state_ |= num_readers;
 
966
      }
 
967
      gate1_.notify_all();
 
968
    }
 
969
 
 
970
    // Shared <-> Exclusive
 
971
 
 
972
    bool
 
973
    upgrade_mutex::try_unlock_shared_and_lock()
 
974
    {
 
975
      boost::unique_lock<mutex_t> lk(mut_);
 
976
      if (state_ == 1)
 
977
      {
 
978
        state_ = write_entered_;
 
979
        return true;
 
980
      }
 
981
      return false;
 
982
    }
 
983
 
 
984
    void
 
985
    upgrade_mutex::unlock_and_lock_shared()
 
986
    {
 
987
      {
 
988
        boost::lock_guard<mutex_t> _(mut_);
 
989
        state_ = 1;
 
990
      }
 
991
      gate1_.notify_all();
 
992
    }
 
993
 
 
994
    // Shared <-> Upgrade
 
995
 
 
996
    bool
 
997
    upgrade_mutex::try_unlock_shared_and_lock_upgrade()
 
998
    {
 
999
      boost::unique_lock<mutex_t> lk(mut_);
 
1000
      if (!(state_ & (write_entered_ | upgradable_entered_)))
 
1001
      {
 
1002
        state_ |= upgradable_entered_;
 
1003
        return true;
 
1004
      }
 
1005
      return false;
 
1006
    }
 
1007
 
 
1008
    void
 
1009
    upgrade_mutex::unlock_upgrade_and_lock_shared()
 
1010
    {
 
1011
      {
 
1012
        boost::lock_guard<mutex_t> _(mut_);
 
1013
        state_ &= ~upgradable_entered_;
 
1014
      }
 
1015
      gate1_.notify_all();
 
1016
    }
 
1017
 
 
1018
    // Upgrade <-> Exclusive
 
1019
 
 
1020
    void
 
1021
    upgrade_mutex::unlock_upgrade_and_lock()
 
1022
    {
 
1023
      boost::unique_lock<mutex_t> lk(mut_);
 
1024
      count_t num_readers = (state_ & n_readers_) - 1;
 
1025
      state_ &= ~(upgradable_entered_ | n_readers_);
 
1026
      state_ |= write_entered_ | num_readers;
 
1027
      while (state_ & n_readers_)
 
1028
        gate2_.wait(lk);
 
1029
    }
 
1030
 
 
1031
    bool
 
1032
    upgrade_mutex::try_unlock_upgrade_and_lock()
 
1033
    {
 
1034
      boost::unique_lock<mutex_t> lk(mut_);
 
1035
      if (state_ == (upgradable_entered_ | 1))
 
1036
      {
 
1037
        state_ = write_entered_;
 
1038
        return true;
 
1039
      }
 
1040
      return false;
 
1041
    }
 
1042
 
 
1043
    void
 
1044
    upgrade_mutex::unlock_and_lock_upgrade()
 
1045
    {
 
1046
      {
 
1047
        boost::lock_guard<mutex_t> _(mut_);
 
1048
        state_ = upgradable_entered_ | 1;
 
1049
      }
 
1050
      gate1_.notify_all();
 
1051
    }
 
1052
 
 
1053
  }  // thread_v2
 
1054
}  // boost
 
1055
 
 
1056
namespace boost {
 
1057
  //using thread_v2::shared_mutex;
 
1058
  using thread_v2::upgrade_mutex;
 
1059
  typedef thread_v2::upgrade_mutex shared_mutex;
 
1060
}
 
1061
 
 
1062
#endif