Ticket #6217: 6217.path

File 6217.path, 54.3 KB (added by anonymous, 11 years ago)
Line 
1Index: pthread/shared_mutex.hpp
2===================================================================
3--- pthread/shared_mutex.hpp (revision 77668)
4+++ pthread/shared_mutex.hpp (working copy)
5@@ -437,6 +437,57 @@
6 release_waiters();
7 }
8
9+#ifdef BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
10+ bool try_unlock_shared_and_lock()
11+ {
12+ boost::mutex::scoped_lock lk(state_change);
13+ if( !state.exclusive
14+ && !state.exclusive_waiting_blocked
15+ && !state.upgrade
16+ && state.shared_count==1)
17+ {
18+ state.shared_count=0;
19+ state.exclusive=true;
20+ return true;
21+ }
22+ return false;
23+ }
24+#ifdef BOOST_THREAD_USES_CHRONO
25+ template <class Rep, class Period>
26+ bool
27+ try_unlock_shared_and_lock_for(
28+ const chrono::duration<Rep, Period>& rel_time)
29+ {
30+ return try_unlock_shared_and_lock_until(
31+ chrono::steady_clock::now() + rel_time);
32+ }
33+ template <class Clock, class Duration>
34+ bool
35+ try_unlock_shared_and_lock_until(
36+ const chrono::time_point<Clock, Duration>& abs_time)
37+ {
38+ boost::this_thread::disable_interruption do_not_disturb;
39+ boost::mutex::scoped_lock lk(state_change);
40+ if (state.shared_count != 1)
41+ {
42+ while (true)
43+ {
44+ cv_status status = shared_cond.wait_until(lk,abs_time);
45+ if (state.shared_count == 1)
46+ break;
47+ if(status == cv_status::timeout)
48+ return false;
49+ }
50+ }
51+ state.upgrade=false;
52+ state.exclusive=true;
53+ state.exclusive_waiting_blocked=false;
54+ state.shared_count=0;
55+ return true;
56+ }
57+#endif
58+#endif
59+
60 // Shared <-> Upgrade
61 void unlock_upgrade_and_lock_shared()
62 {
63@@ -446,6 +497,58 @@
64 release_waiters();
65 }
66
67+#ifdef BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
68+ bool try_unlock_shared_and_lock_upgrade()
69+ {
70+ boost::mutex::scoped_lock lk(state_change);
71+ if( !state.exclusive
72+ && !state.exclusive_waiting_blocked
73+ && !state.upgrade
74+ )
75+ {
76+ state.upgrade=true;
77+ return true;
78+ }
79+ return false;
80+ }
81+#ifdef BOOST_THREAD_USES_CHRONO
82+ template <class Rep, class Period>
83+ bool
84+ try_unlock_shared_and_lock_upgrade_for(
85+ const chrono::duration<Rep, Period>& rel_time)
86+ {
87+ return try_unlock_shared_and_lock_upgrade_until(
88+ chrono::steady_clock::now() + rel_time);
89+ }
90+ template <class Clock, class Duration>
91+ bool
92+ try_unlock_shared_and_lock_upgrade_until(
93+ const chrono::time_point<Clock, Duration>& abs_time)
94+ {
95+ boost::this_thread::disable_interruption do_not_disturb;
96+ boost::mutex::scoped_lock lk(state_change);
97+ if( state.exclusive
98+ || state.exclusive_waiting_blocked
99+ || state.upgrade
100+ )
101+ {
102+ while (true)
103+ {
104+ cv_status status = exclusive_cond.wait_until(lk,abs_time);
105+ if( ! state.exclusive
106+ && ! state.exclusive_waiting_blocked
107+ && ! state.upgrade
108+ )
109+ break;
110+ if(status == cv_status::timeout)
111+ return false;
112+ }
113+ }
114+ state.upgrade=true;
115+ return true;
116+ }
117+#endif
118+#endif
119 };
120
121 typedef shared_mutex upgrade_mutex;
122Index: locks.hpp
123===================================================================
124--- locks.hpp (revision 77668)
125+++ locks.hpp (working copy)
126@@ -640,6 +640,181 @@
127 #endif
128 #endif
129
130+#ifdef BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
131+#ifndef BOOST_NO_RVALUE_REFERENCES
132+ // Conversion from shared locking
133+ unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)
134+ : m(0),is_locked(false)
135+ {
136+ if (sl.owns_lock()) {
137+ if (sl.mutex()->try_unlock_shared_and_lock())
138+ {
139+ m = sl.release();
140+ is_locked = true;
141+ }
142+ }
143+ else
144+ {
145+ m = sl.release();
146+ }
147+ }
148+
149+#ifdef BOOST_THREAD_USES_CHRONO
150+ template <class Clock, class Duration>
151+ unique_lock(shared_lock<mutex_type>&& sl,
152+ const chrono::time_point<Clock, Duration>& abs_time)
153+ : m(0),is_locked(false)
154+ {
155+ if (sl.owns_lock()) {
156+ if (sl.mutex()->try_unlock_shared_and_lock_until(abs_time))
157+ {
158+ m = sl.release();
159+ is_locked = true;
160+ }
161+ }
162+ else
163+ {
164+ m = sl.release();
165+ }
166+ }
167+
168+ template <class Rep, class Period>
169+ unique_lock(shared_lock<mutex_type>&& sl,
170+ const chrono::duration<Rep, Period>& rel_time)
171+ : m(0),is_locked(false)
172+ {
173+ if (sl.owns_lock()) {
174+ if (sl.mutex()->try_unlock_shared_and_lock_for(rel_time))
175+ {
176+ m = sl.release();
177+ is_locked = true;
178+ }
179+ }
180+ else
181+ {
182+ m = sl.release();
183+ }
184+ }
185+#endif
186+#else
187+
188+#if defined BOOST_THREAD_USES_MOVE
189+
190+ // Conversion from shared locking
191+ unique_lock(boost::rv<shared_lock<mutex_type> >& sl, try_to_lock_t)
192+ : m(0),is_locked(false)
193+ {
194+ if (sl.owns_lock()) {
195+ if (sl.mutex()->try_unlock_shared_and_lock())
196+ {
197+ m = sl.release();
198+ is_locked = true;
199+ }
200+ }
201+ else
202+ {
203+ m = sl.release();
204+ }
205+ }
206+
207+#ifdef BOOST_THREAD_USES_CHRONO
208+ template <class Clock, class Duration>
209+ unique_lock(boost::rv<shared_lock<mutex_type> >& sl,
210+ const chrono::time_point<Clock, Duration>& abs_time)
211+ : m(0),is_locked(false)
212+ {
213+ if (sl.owns_lock()) {
214+ if (sl.mutex()->try_unlock_shared_and_lock_until(abs_time))
215+ {
216+ m = sl.release();
217+ is_locked = true;
218+ }
219+ }
220+ else
221+ {
222+ m = sl.release();
223+ }
224+ }
225+
226+ template <class Rep, class Period>
227+ unique_lock(boost::rv<shared_lock<mutex_type> >& sl,
228+ const chrono::duration<Rep, Period>& rel_time)
229+ : m(0),is_locked(false)
230+ {
231+ if (sl.owns_lock()) {
232+ if (sl.mutex()->try_unlock_shared_and_lock_for(rel_time))
233+ {
234+ m = sl.release();
235+ is_locked = true;
236+ }
237+ }
238+ else
239+ {
240+ m = sl.release();
241+ }
242+ }
243+#endif
244+#else
245+
246+ // Conversion from shared locking
247+ unique_lock(detail::thread_move_t<shared_lock<mutex_type> > sl, try_to_lock_t)
248+ : m(0),is_locked(false)
249+ {
250+ if (sl.owns_lock()) {
251+ if (sl.mutex()->try_unlock_shared_and_lock())
252+ {
253+ m = sl.release();
254+ is_locked = true;
255+ }
256+ }
257+ else
258+ {
259+ m = sl.release();
260+ }
261+ }
262+
263+#ifdef BOOST_THREAD_USES_CHRONO
264+ template <class Clock, class Duration>
265+ unique_lock(detail::thread_move_t<shared_lock<mutex_type> > sl,
266+ const chrono::time_point<Clock, Duration>& abs_time)
267+ : m(0),is_locked(false)
268+ {
269+ if (sl.owns_lock()) {
270+ if (sl.mutex()->try_unlock_shared_and_lock_until(abs_time))
271+ {
272+ m = sl.release();
273+ is_locked = true;
274+ }
275+ }
276+ else
277+ {
278+ m = sl.release();
279+ }
280+ }
281+
282+ template <class Rep, class Period>
283+ unique_lock(detail::thread_move_t<shared_lock<mutex_type> > sl,
284+ const chrono::duration<Rep, Period>& rel_time)
285+ : m(0),is_locked(false)
286+ {
287+ if (sl.owns_lock()) {
288+ if (sl.mutex()->try_unlock_shared_and_lock_for(rel_time))
289+ {
290+ m = sl.release();
291+ is_locked = true;
292+ }
293+ }
294+ else
295+ {
296+ m = sl.release();
297+ }
298+ }
299+#endif
300+#endif
301+#endif
302+#endif
303+
304+
305 void swap(unique_lock& other) BOOST_NOEXCEPT
306 {
307 std::swap(m,other.m);
308@@ -836,7 +1011,7 @@
309 public:
310 typedef Mutex mutex_type;
311
312- shared_lock():
313+ shared_lock() BOOST_NOEXCEPT:
314 m(0),is_locked(false)
315 {}
316
317@@ -848,7 +1023,7 @@
318 shared_lock(Mutex& m_,adopt_lock_t):
319 m(&m_),is_locked(true)
320 {}
321- shared_lock(Mutex& m_,defer_lock_t):
322+ shared_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:
323 m(&m_),is_locked(false)
324 {}
325 shared_lock(Mutex& m_,try_to_lock_t):
326@@ -876,7 +1051,7 @@
327 #endif
328
329 #ifndef BOOST_NO_RVALUE_REFERENCES
330- shared_lock(shared_lock<Mutex> && other):
331+ shared_lock(shared_lock<Mutex> && other) BOOST_NOEXCEPT:
332 m(other.m),is_locked(other.is_locked)
333 {
334 other.is_locked=false;
335@@ -906,7 +1081,7 @@
336 }
337
338
339- shared_lock& operator=(shared_lock<Mutex> && other)
340+ shared_lock& operator=(shared_lock<Mutex> && other) BOOST_NOEXCEPT
341 {
342 shared_lock temp(::boost::move(other));
343 swap(temp);
344@@ -930,7 +1105,7 @@
345 #endif
346 #else
347 #if defined BOOST_THREAD_USES_MOVE
348- shared_lock(boost::rv<shared_lock<Mutex> >& other):
349+ shared_lock(boost::rv<shared_lock<Mutex> >& other) BOOST_NOEXCEPT:
350 m(other.m),is_locked(other.is_locked)
351 {
352 other.is_locked=false;
353@@ -959,24 +1134,24 @@
354 other.m=0;
355 }
356
357- operator ::boost::rv<shared_lock<Mutex> >&()
358+ operator ::boost::rv<shared_lock<Mutex> >&() BOOST_NOEXCEPT
359 {
360 return *static_cast< ::boost::rv<shared_lock<Mutex> >* >(this);
361 }
362- operator const ::boost::rv<shared_lock<Mutex> >&() const
363+ operator const ::boost::rv<shared_lock<Mutex> >&() const BOOST_NOEXCEPT
364 {
365 return *static_cast<const ::boost::rv<shared_lock<Mutex> >* >(this);
366 }
367- ::boost::rv<shared_lock<Mutex> >& move()
368+ ::boost::rv<shared_lock<Mutex> >& move() BOOST_NOEXCEPT
369 {
370 return *static_cast< ::boost::rv<shared_lock<Mutex> >* >(this);
371 }
372- const ::boost::rv<shared_lock<Mutex> >& move() const
373+ const ::boost::rv<shared_lock<Mutex> >& move() const BOOST_NOEXCEPT
374 {
375 return *static_cast<const ::boost::rv<shared_lock<Mutex> >* >(this);
376 }
377
378- shared_lock& operator=(::boost::rv<shared_lock<Mutex> >& other)
379+ shared_lock& operator=(::boost::rv<shared_lock<Mutex> >& other) BOOST_NOEXCEPT
380 {
381 shared_lock temp(other);
382 swap(temp);
383@@ -1000,7 +1175,7 @@
384 #endif
385 #else
386
387- shared_lock(detail::thread_move_t<shared_lock<Mutex> > other):
388+ shared_lock(detail::thread_move_t<shared_lock<Mutex> > other) BOOST_NOEXCEPT:
389 m(other->m),is_locked(other->is_locked)
390 {
391 other->is_locked=false;
392@@ -1029,18 +1204,18 @@
393 other->m=0;
394 }
395
396- operator detail::thread_move_t<shared_lock<Mutex> >()
397+ operator detail::thread_move_t<shared_lock<Mutex> >() BOOST_NOEXCEPT
398 {
399 return move();
400 }
401
402- detail::thread_move_t<shared_lock<Mutex> > move()
403+ detail::thread_move_t<shared_lock<Mutex> > move() BOOST_NOEXCEPT
404 {
405 return detail::thread_move_t<shared_lock<Mutex> >(*this);
406 }
407
408
409- shared_lock& operator=(detail::thread_move_t<shared_lock<Mutex> > other)
410+ shared_lock& operator=(detail::thread_move_t<shared_lock<Mutex> > other) BOOST_NOEXCEPT
411 {
412 shared_lock temp(other);
413 swap(temp);
414@@ -1065,13 +1240,13 @@
415 #endif
416 #endif
417
418- void swap(shared_lock& other)
419+ void swap(shared_lock& other) BOOST_NOEXCEPT
420 {
421 std::swap(m,other.m);
422 std::swap(is_locked,other.is_locked);
423 }
424
425- Mutex* mutex() const
426+ Mutex* mutex() const BOOST_NOEXCEPT
427 {
428 return m;
429 }
430@@ -1190,21 +1365,21 @@
431
432 #if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
433 typedef void (shared_lock<Mutex>::*bool_type)();
434- operator bool_type() const
435+ operator bool_type() const BOOST_NOEXCEPT
436 {
437 return is_locked?&shared_lock::lock:0;
438 }
439- bool operator!() const
440+ bool operator!() const BOOST_NOEXCEPT
441 {
442 return !owns_lock();
443 }
444 #else
445- explicit operator bool() const
446+ explicit operator bool() const BOOST_NOEXCEPT
447 {
448 return owns_lock();
449 }
450 #endif
451- bool owns_lock() const
452+ bool owns_lock() const BOOST_NOEXCEPT
453 {
454 return is_locked;
455 }
456@@ -1218,8 +1393,9 @@
457 {};
458 #endif
459
460+
461 template<typename Mutex>
462- void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs)
463+ void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) BOOST_NOEXCEPT
464 {
465 lhs.swap(rhs);
466 }
467@@ -1241,7 +1417,7 @@
468 #endif
469 public:
470 typedef Mutex mutex_type;
471- upgrade_lock():
472+ upgrade_lock() BOOST_NOEXCEPT:
473 m(0),is_locked(false)
474 {}
475
476@@ -1253,7 +1429,7 @@
477 upgrade_lock(Mutex& m_,adopt_lock_t):
478 m(&m_),is_locked(true)
479 {}
480- upgrade_lock(Mutex& m_,defer_lock_t):
481+ upgrade_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:
482 m(&m_),is_locked(false)
483 {}
484 upgrade_lock(Mutex& m_,try_to_lock_t):
485@@ -1276,7 +1452,7 @@
486 #endif
487
488 #ifndef BOOST_NO_RVALUE_REFERENCES
489- upgrade_lock(upgrade_lock<Mutex>&& other):
490+ upgrade_lock(upgrade_lock<Mutex>&& other) BOOST_NOEXCEPT:
491 m(other.m),is_locked(other.is_locked)
492 {
493 other.is_locked=false;
494@@ -1294,7 +1470,7 @@
495 other.m=0;
496 }
497
498- upgrade_lock& operator=(upgrade_lock<Mutex>&& other)
499+ upgrade_lock& operator=(upgrade_lock<Mutex>&& other) BOOST_NOEXCEPT
500 {
501 upgrade_lock temp(::boost::move(other));
502 swap(temp);
503@@ -1311,7 +1487,7 @@
504 #endif
505 #else
506 #if defined BOOST_THREAD_USES_MOVE
507- upgrade_lock(boost::rv<upgrade_lock<Mutex> >& other):
508+ upgrade_lock(boost::rv<upgrade_lock<Mutex> >& other) BOOST_NOEXCEPT:
509 m(other.m),is_locked(other.is_locked)
510 {
511 other.is_locked=false;
512@@ -1329,23 +1505,23 @@
513 other.m=0;
514 }
515
516- operator ::boost::rv<upgrade_lock>&()
517+ operator ::boost::rv<upgrade_lock>&() BOOST_NOEXCEPT
518 {
519 return *static_cast< ::boost::rv<upgrade_lock>* >(this);
520 }
521- operator const ::boost::rv<upgrade_lock>&() const
522+ operator const ::boost::rv<upgrade_lock>&() const BOOST_NOEXCEPT
523 {
524 return *static_cast<const ::boost::rv<upgrade_lock>* >(this);
525 }
526- ::boost::rv<upgrade_lock>& move()
527+ ::boost::rv<upgrade_lock>& move() BOOST_NOEXCEPT
528 {
529 return *static_cast< ::boost::rv<upgrade_lock>* >(this);
530 }
531- const ::boost::rv<upgrade_lock>& move() const
532+ const ::boost::rv<upgrade_lock>& move() const BOOST_NOEXCEPT
533 {
534 return *static_cast<const ::boost::rv<upgrade_lock>* >(this);
535 }
536- upgrade_lock& operator=(boost::rv<upgrade_lock<Mutex> >& other)
537+ upgrade_lock& operator=(boost::rv<upgrade_lock<Mutex> >& other) BOOST_NOEXCEPT
538 {
539 upgrade_lock temp(other);
540 swap(temp);
541@@ -1361,7 +1537,7 @@
542 }
543 #endif
544 #else
545- upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
546+ upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other) BOOST_NOEXCEPT:
547 m(other->m),is_locked(other->is_locked)
548 {
549 other->is_locked=false;
550@@ -1379,18 +1555,18 @@
551 other->m=0;
552 }
553
554- operator detail::thread_move_t<upgrade_lock<Mutex> >()
555+ operator detail::thread_move_t<upgrade_lock<Mutex> >() BOOST_NOEXCEPT
556 {
557 return move();
558 }
559
560- detail::thread_move_t<upgrade_lock<Mutex> > move()
561+ detail::thread_move_t<upgrade_lock<Mutex> > move() BOOST_NOEXCEPT
562 {
563 return detail::thread_move_t<upgrade_lock<Mutex> >(*this);
564 }
565
566
567- upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other)
568+ upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other) BOOST_NOEXCEPT
569 {
570 upgrade_lock temp(other);
571 swap(temp);
572@@ -1408,12 +1584,185 @@
573 #endif
574 #endif
575
576- void swap(upgrade_lock& other)
577+#ifdef BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
578+#ifndef BOOST_NO_RVALUE_REFERENCES
579+ // Conversion from shared locking
580+
581+ upgrade_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)
582+ : m(0),is_locked(false)
583 {
584+ if (sl.owns_lock()) {
585+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade())
586+ {
587+ m = sl.release();
588+ is_locked = true;
589+ }
590+ }
591+ else
592+ {
593+ m = sl.release();
594+ }
595+ }
596+#ifdef BOOST_THREAD_USES_CHRONO
597+ template <class Clock, class Duration>
598+ upgrade_lock(shared_lock<mutex_type>&& sl,
599+ const chrono::time_point<Clock, Duration>& abs_time)
600+ : m(0),is_locked(false)
601+ {
602+ if (sl.owns_lock()) {
603+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
604+ {
605+ m = sl.release();
606+ is_locked = true;
607+ }
608+ }
609+ else
610+ {
611+ m = sl.release();
612+ }
613+ }
614+
615+ template <class Rep, class Period>
616+ upgrade_lock(shared_lock<mutex_type>&& sl,
617+ const chrono::duration<Rep, Period>& rel_time)
618+ : m(0),is_locked(false)
619+ {
620+ if (sl.owns_lock()) {
621+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
622+ {
623+ m = sl.release();
624+ is_locked = true;
625+ }
626+ }
627+ else
628+ {
629+ m = sl.release();
630+ }
631+ }
632+#endif
633+#else
634+
635+
636+#if defined BOOST_THREAD_USES_MOVE
637+ // Conversion from shared locking
638+
639+ upgrade_lock(boost::rv<shared_lock<mutex_type> > &sl, try_to_lock_t)
640+ : m(0),is_locked(false)
641+ {
642+ if (sl.owns_lock()) {
643+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade())
644+ {
645+ m = sl.release();
646+ is_locked = true;
647+ }
648+ }
649+ else
650+ {
651+ m = sl.release();
652+ }
653+ }
654+#ifdef BOOST_THREAD_USES_CHRONO
655+ template <class Clock, class Duration>
656+ upgrade_lock(boost::rv<shared_lock<mutex_type> > &sl,
657+ const chrono::time_point<Clock, Duration>& abs_time)
658+ : m(0),is_locked(false)
659+ {
660+ if (sl.owns_lock()) {
661+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
662+ {
663+ m = sl.release();
664+ is_locked = true;
665+ }
666+ }
667+ else
668+ {
669+ m = sl.release();
670+ }
671+ }
672+
673+ template <class Rep, class Period>
674+ upgrade_lock(boost::rv<shared_lock<mutex_type> > &sl,
675+ const chrono::duration<Rep, Period>& rel_time)
676+ : m(0),is_locked(false)
677+ {
678+ if (sl.owns_lock()) {
679+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
680+ {
681+ m = sl.release();
682+ is_locked = true;
683+ }
684+ }
685+ else
686+ {
687+ m = sl.release();
688+ }
689+ }
690+#endif
691+#else
692+ // Conversion from shared locking
693+
694+ upgrade_lock(detail::thread_move_t<shared_lock<mutex_type> > sl, try_to_lock_t)
695+ : m(0),is_locked(false)
696+ {
697+ if (sl.owns_lock()) {
698+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade())
699+ {
700+ m = sl.release();
701+ is_locked = true;
702+ }
703+ }
704+ else
705+ {
706+ m = sl.release();
707+ }
708+ }
709+#ifdef BOOST_THREAD_USES_CHRONO
710+ template <class Clock, class Duration>
711+ upgrade_lock(detail::thread_move_t<shared_lock<mutex_type> > sl,
712+ const chrono::time_point<Clock, Duration>& abs_time)
713+ : m(0),is_locked(false)
714+ {
715+ if (sl.owns_lock()) {
716+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
717+ {
718+ m = sl.release();
719+ is_locked = true;
720+ }
721+ }
722+ else
723+ {
724+ m = sl.release();
725+ }
726+ }
727+
728+ template <class Rep, class Period>
729+ upgrade_lock(detail::thread_move_t<shared_lock<mutex_type> >& sl,
730+ const chrono::duration<Rep, Period>& rel_time)
731+ : m(0),is_locked(false)
732+ {
733+ if (sl.owns_lock()) {
734+ if (sl.mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
735+ {
736+ m = sl.release();
737+ is_locked = true;
738+ }
739+ }
740+ else
741+ {
742+ m = sl.release();
743+ }
744+ }
745+#endif
746+#endif
747+#endif
748+#endif
749+
750+ void swap(upgrade_lock& other) BOOST_NOEXCEPT
751+ {
752 std::swap(m,other.m);
753 std::swap(is_locked,other.is_locked);
754 }
755- Mutex* mutex() const
756+ Mutex* mutex() const BOOST_NOEXCEPT
757 {
758 return m;
759 }
760@@ -1503,21 +1852,21 @@
761 #endif
762 #if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
763 typedef void (upgrade_lock::*bool_type)();
764- operator bool_type() const
765+ operator bool_type() const BOOST_NOEXCEPT
766 {
767 return is_locked?&upgrade_lock::lock:0;
768 }
769- bool operator!() const
770+ bool operator!() const BOOST_NOEXCEPT
771 {
772 return !owns_lock();
773 }
774 #else
775- explicit operator bool() const
776+ explicit operator bool() const BOOST_NOEXCEPT
777 {
778 return owns_lock();
779 }
780 #endif
781- bool owns_lock() const
782+ bool owns_lock() const BOOST_NOEXCEPT
783 {
784 return is_locked;
785 }
786@@ -1605,13 +1954,13 @@
787 }
788
789 #ifndef BOOST_NO_RVALUE_REFERENCES
790- upgrade_to_unique_lock(upgrade_to_unique_lock<Mutex>&& other):
791+ upgrade_to_unique_lock(upgrade_to_unique_lock<Mutex>&& other) BOOST_NOEXCEPT:
792 source(other.source),exclusive(::boost::move(other.exclusive))
793 {
794 other.source=0;
795 }
796
797- upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Mutex>&& other)
798+ upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Mutex>&& other) BOOST_NOEXCEPT
799 {
800 upgrade_to_unique_lock temp(other);
801 swap(temp);
802@@ -1619,59 +1968,59 @@
803 }
804 #else
805 #if defined BOOST_THREAD_USES_MOVE
806- upgrade_to_unique_lock(boost::rv<upgrade_to_unique_lock<Mutex> >& other):
807+ upgrade_to_unique_lock(boost::rv<upgrade_to_unique_lock<Mutex> >& other) BOOST_NOEXCEPT:
808 source(other.source),exclusive(::boost::move(other.exclusive))
809 {
810 other.source=0;
811 }
812
813- upgrade_to_unique_lock& operator=(boost::rv<upgrade_to_unique_lock<Mutex> >& other)
814+ upgrade_to_unique_lock& operator=(boost::rv<upgrade_to_unique_lock<Mutex> >& other) BOOST_NOEXCEPT
815 {
816 upgrade_to_unique_lock temp(other);
817 swap(temp);
818 return *this;
819 }
820- operator ::boost::rv<upgrade_to_unique_lock>&()
821+ operator ::boost::rv<upgrade_to_unique_lock>&() BOOST_NOEXCEPT
822 {
823 return *static_cast< ::boost::rv<upgrade_to_unique_lock>* >(this);
824 }
825- operator const ::boost::rv<upgrade_to_unique_lock>&() const
826+ operator const ::boost::rv<upgrade_to_unique_lock>&() const BOOST_NOEXCEPT
827 {
828 return *static_cast<const ::boost::rv<upgrade_to_unique_lock>* >(this);
829 }
830- ::boost::rv<upgrade_to_unique_lock>& move()
831+ ::boost::rv<upgrade_to_unique_lock>& move() BOOST_NOEXCEPT
832 {
833 return *static_cast< ::boost::rv<upgrade_to_unique_lock>* >(this);
834 }
835- const ::boost::rv<upgrade_to_unique_lock>& move() const
836+ const ::boost::rv<upgrade_to_unique_lock>& move() const BOOST_NOEXCEPT
837 {
838 return *static_cast<const ::boost::rv<upgrade_to_unique_lock>* >(this);
839 }
840 #else
841- upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other):
842+ upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other) BOOST_NOEXCEPT:
843 source(other->source),exclusive(::boost::move(other->exclusive))
844 {
845 other->source=0;
846 }
847
848- upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other)
849+ upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other) BOOST_NOEXCEPT
850 {
851 upgrade_to_unique_lock temp(other);
852 swap(temp);
853 return *this;
854 }
855- operator detail::thread_move_t<upgrade_to_unique_lock<Mutex> >()
856+ operator detail::thread_move_t<upgrade_to_unique_lock<Mutex> >() BOOST_NOEXCEPT
857 {
858 return move();
859 }
860
861- detail::thread_move_t<upgrade_to_unique_lock<Mutex> > move()
862+ detail::thread_move_t<upgrade_to_unique_lock<Mutex> > move() BOOST_NOEXCEPT
863 {
864 return detail::thread_move_t<upgrade_to_unique_lock<Mutex> >(*this);
865 }
866 #endif
867 #endif
868- void swap(upgrade_to_unique_lock& other)
869+ void swap(upgrade_to_unique_lock& other) BOOST_NOEXCEPT
870 {
871 std::swap(source,other.source);
872 exclusive.swap(other.exclusive);
873@@ -1679,22 +2028,22 @@
874
875 #if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
876 typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&);
877- operator bool_type() const
878+ operator bool_type() const BOOST_NOEXCEPT
879 {
880 return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0;
881 }
882- bool operator!() const
883+ bool operator!() const BOOST_NOEXCEPT
884 {
885 return !owns_lock();
886 }
887 #else
888- explicit operator bool() const
889+ explicit operator bool() const BOOST_NOEXCEPT
890 {
891 return owns_lock();
892 }
893 #endif
894
895- bool owns_lock() const
896+ bool owns_lock() const BOOST_NOEXCEPT
897 {
898 return exclusive.owns_lock();
899 }
900Index: ../../libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp
901===================================================================
902--- ../../libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp (revision 0)
903+++ ../../libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp (revision 0)
904@@ -0,0 +1,66 @@
905+//===----------------------------------------------------------------------===//
906+//
907+// The LLVM Compiler Infrastructure
908+//
909+// This file is dual licensed under the MIT and the University of Illinois Open
910+// Source Licenses. See LICENSE.TXT for details.
911+//
912+//===----------------------------------------------------------------------===//
913+
914+// Copyright (C) 2011 Vicente J. Botet Escriba
915+//
916+// Distributed under the Boost Software License, Version 1.0. (See accompanying
917+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
918+
919+// <boost/thread/locks.hpp>
920+
921+// template <class Mutex> class upgrade_lock;
922+
923+// upgrade_lock(shared_lock&& u, try_to_lock);
924+
925+#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
926+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
927+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
928+
929+#include <boost/thread/locks.hpp>
930+#include <boost/thread/shared_mutex.hpp>
931+#include <boost/detail/lightweight_test.hpp>
932+
933+boost::shared_mutex m;
934+
935+int main()
936+{
937+ {
938+ boost::shared_lock<boost::shared_mutex> lk0(m);
939+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock );
940+ BOOST_TEST(lk.mutex() == &m);
941+ BOOST_TEST(lk.owns_lock() == true);
942+ BOOST_TEST(lk0.mutex() == 0);
943+ BOOST_TEST(lk0.owns_lock() == false);
944+ }
945+ {
946+ boost::upgrade_lock<boost::shared_mutex> lk(boost::shared_lock<boost::shared_mutex>(m), boost::try_to_lock);
947+ BOOST_TEST(lk.mutex() == &m);
948+ BOOST_TEST(lk.owns_lock() == true);
949+ }
950+ {
951+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
952+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
953+ BOOST_TEST(lk.mutex() == &m);
954+ BOOST_TEST(lk.owns_lock() == false);
955+ BOOST_TEST(lk0.mutex() == 0);
956+ BOOST_TEST(lk0.owns_lock() == false);
957+ }
958+ {
959+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
960+ lk0.release();
961+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
962+ BOOST_TEST(lk.mutex() == 0);
963+ BOOST_TEST(lk.owns_lock() == false);
964+ BOOST_TEST(lk0.mutex() == 0);
965+ BOOST_TEST(lk0.owns_lock() == false);
966+ }
967+
968+ return boost::report_errors();
969+}
970+
971
972Property changes on: ../../libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp
973___________________________________________________________________
974Added: svn:mime-type
975 + text/plain
976Added: svn:keywords
977 + Id
978Added: svn:eol-style
979 + native
980
981Index: ../../libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp
982===================================================================
983--- ../../libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp (revision 0)
984+++ ../../libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp (revision 0)
985@@ -0,0 +1,69 @@
986+//===----------------------------------------------------------------------===//
987+//
988+// The LLVM Compiler Infrastructure
989+//
990+// This file is dual licensed under the MIT and the University of Illinois Open
991+// Source Licenses. See LICENSE.TXT for details.
992+//
993+//===----------------------------------------------------------------------===//
994+
995+// Copyright (C) 2011 Vicente J. Botet Escriba
996+//
997+// Distributed under the Boost Software License, Version 1.0. (See accompanying
998+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
999+
1000+// <boost/thread/locks.hpp>
1001+
1002+// template <class Mutex> class upgrade_lock;
1003+
1004+// template <class Clock, class Duration>
1005+// upgrade_lock(shared_lock<mutex_type>&&,
1006+// const chrono::duration<Rep, Period>&);
1007+
1008+#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
1009+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
1010+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
1011+
1012+#include <boost/thread/locks.hpp>
1013+#include <boost/thread/shared_mutex.hpp>
1014+#include <boost/detail/lightweight_test.hpp>
1015+
1016+boost::shared_mutex m;
1017+
1018+int main()
1019+{
1020+ {
1021+ boost::shared_lock<boost::shared_mutex> lk0(m);
1022+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
1023+ BOOST_TEST(lk.mutex() == &m);
1024+ BOOST_TEST(lk.owns_lock() == true);
1025+ BOOST_TEST(lk0.mutex() == 0);
1026+ BOOST_TEST(lk0.owns_lock() == false);
1027+ }
1028+ {
1029+ boost::upgrade_lock<boost::shared_mutex>
1030+ lk(boost::shared_lock<boost::shared_mutex>(m), boost::chrono::milliseconds(1));
1031+ BOOST_TEST(lk.mutex() == &m);
1032+ BOOST_TEST(lk.owns_lock() == true);
1033+ }
1034+ {
1035+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
1036+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
1037+ BOOST_TEST(lk.mutex() == &m);
1038+ BOOST_TEST(lk.owns_lock() == false);
1039+ BOOST_TEST(lk0.mutex() == 0);
1040+ BOOST_TEST(lk0.owns_lock() == false);
1041+ }
1042+ {
1043+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
1044+ lk0.release();
1045+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
1046+ BOOST_TEST(lk.mutex() == 0);
1047+ BOOST_TEST(lk.owns_lock() == false);
1048+ BOOST_TEST(lk0.mutex() == 0);
1049+ BOOST_TEST(lk0.owns_lock() == false);
1050+ }
1051+
1052+ return boost::report_errors();
1053+}
1054+
1055
1056Property changes on: ../../libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp
1057___________________________________________________________________
1058Added: svn:mime-type
1059 + text/plain
1060Added: svn:keywords
1061 + Id
1062Added: svn:eol-style
1063 + native
1064
1065Index: ../../libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp
1066===================================================================
1067--- ../../libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp (revision 0)
1068+++ ../../libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp (revision 0)
1069@@ -0,0 +1,69 @@
1070+//===----------------------------------------------------------------------===//
1071+//
1072+// The LLVM Compiler Infrastructure
1073+//
1074+// This file is dual licensed under the MIT and the University of Illinois Open
1075+// Source Licenses. See LICENSE.TXT for details.
1076+//
1077+//===----------------------------------------------------------------------===//
1078+
1079+// Copyright (C) 2011 Vicente J. Botet Escriba
1080+//
1081+// Distributed under the Boost Software License, Version 1.0. (See accompanying
1082+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
1083+
1084+// <boost/thread/locks.hpp>
1085+
1086+// template <class Mutex> class upgrade_lock;
1087+
1088+// template <class Clock, class Duration>
1089+// upgrade_lock(shared_lock<mutex_type>&&,
1090+// const chrono::time_point<Clock, Duration>&);
1091+
1092+#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
1093+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
1094+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
1095+
1096+#include <boost/thread/locks.hpp>
1097+#include <boost/thread/shared_mutex.hpp>
1098+#include <boost/detail/lightweight_test.hpp>
1099+
1100+boost::shared_mutex m;
1101+
1102+int main()
1103+{
1104+ {
1105+ boost::shared_lock<boost::shared_mutex> lk0(m);
1106+ boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
1107+ BOOST_TEST(lk.mutex() == &m);
1108+ BOOST_TEST(lk.owns_lock() == true);
1109+ BOOST_TEST(lk0.mutex() == 0);
1110+ BOOST_TEST(lk0.owns_lock() == false);
1111+ }
1112+ {
1113+ boost::upgrade_lock<boost::shared_mutex>
1114+ lk( boost::shared_lock<boost::shared_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
1115+ BOOST_TEST(lk.mutex() == &m);
1116+ BOOST_TEST(lk.owns_lock() == true);
1117+ }
1118+ {
1119+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
1120+ boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
1121+ BOOST_TEST(lk.mutex() == &m);
1122+ BOOST_TEST(lk.owns_lock() == false);
1123+ BOOST_TEST(lk0.mutex() == 0);
1124+ BOOST_TEST(lk0.owns_lock() == false);
1125+ }
1126+ {
1127+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
1128+ lk0.release();
1129+ boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
1130+ BOOST_TEST(lk.mutex() == 0);
1131+ BOOST_TEST(lk.owns_lock() == false);
1132+ BOOST_TEST(lk0.mutex() == 0);
1133+ BOOST_TEST(lk0.owns_lock() == false);
1134+ }
1135+
1136+ return boost::report_errors();
1137+}
1138+
1139
1140Property changes on: ../../libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp
1141___________________________________________________________________
1142Added: svn:mime-type
1143 + text/plain
1144Added: svn:keywords
1145 + Id
1146Added: svn:eol-style
1147 + native
1148
1149Index: ../../libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp
1150===================================================================
1151--- ../../libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp (revision 0)
1152+++ ../../libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp (revision 0)
1153@@ -0,0 +1,66 @@
1154+//===----------------------------------------------------------------------===//
1155+//
1156+// The LLVM Compiler Infrastructure
1157+//
1158+// This file is dual licensed under the MIT and the University of Illinois Open
1159+// Source Licenses. See LICENSE.TXT for details.
1160+//
1161+//===----------------------------------------------------------------------===//
1162+
1163+// Copyright (C) 2011 Vicente J. Botet Escriba
1164+//
1165+// Distributed under the Boost Software License, Version 1.0. (See accompanying
1166+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
1167+
1168+// <boost/thread/locks.hpp>
1169+
1170+// template <class Mutex> class unique_lock;
1171+
1172+// unique_lock(shared_lock&& u, try_to_lock);
1173+
1174+#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
1175+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
1176+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
1177+
1178+#include <boost/thread/locks.hpp>
1179+#include <boost/thread/shared_mutex.hpp>
1180+#include <boost/detail/lightweight_test.hpp>
1181+
1182+boost::shared_mutex m;
1183+
1184+int main()
1185+{
1186+ {
1187+ boost::shared_lock<boost::shared_mutex> lk0(m);
1188+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock );
1189+ BOOST_TEST(lk.mutex() == &m);
1190+ BOOST_TEST(lk.owns_lock() == true);
1191+ BOOST_TEST(lk0.mutex() == 0);
1192+ BOOST_TEST(lk0.owns_lock() == false);
1193+ }
1194+ {
1195+ boost::unique_lock<boost::shared_mutex> lk(boost::shared_lock<boost::shared_mutex>(m), boost::try_to_lock);
1196+ BOOST_TEST(lk.mutex() == &m);
1197+ BOOST_TEST(lk.owns_lock() == true);
1198+ }
1199+ {
1200+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
1201+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
1202+ BOOST_TEST(lk.mutex() == &m);
1203+ BOOST_TEST(lk.owns_lock() == false);
1204+ BOOST_TEST(lk0.mutex() == 0);
1205+ BOOST_TEST(lk0.owns_lock() == false);
1206+ }
1207+ {
1208+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
1209+ lk0.release();
1210+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
1211+ BOOST_TEST(lk.mutex() == 0);
1212+ BOOST_TEST(lk.owns_lock() == false);
1213+ BOOST_TEST(lk0.mutex() == 0);
1214+ BOOST_TEST(lk0.owns_lock() == false);
1215+ }
1216+
1217+ return boost::report_errors();
1218+}
1219+
1220
1221Property changes on: ../../libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp
1222___________________________________________________________________
1223Added: svn:mime-type
1224 + text/plain
1225Added: svn:keywords
1226 + Id
1227Added: svn:eol-style
1228 + native
1229
1230Index: ../../libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp
1231===================================================================
1232--- ../../libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp (revision 0)
1233+++ ../../libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp (revision 0)
1234@@ -0,0 +1,69 @@
1235+//===----------------------------------------------------------------------===//
1236+//
1237+// The LLVM Compiler Infrastructure
1238+//
1239+// This file is dual licensed under the MIT and the University of Illinois Open
1240+// Source Licenses. See LICENSE.TXT for details.
1241+//
1242+//===----------------------------------------------------------------------===//
1243+
1244+// Copyright (C) 2011 Vicente J. Botet Escriba
1245+//
1246+// Distributed under the Boost Software License, Version 1.0. (See accompanying
1247+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
1248+
1249+// <boost/thread/locks.hpp>
1250+
1251+// template <class Mutex> class unique_lock;
1252+
1253+// template <class Rep, class Period>
1254+// unique_lock(shared_lock<mutex_type>&&,
1255+// const chrono::duration<Rep, Period>&);
1256+
1257+#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
1258+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
1259+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
1260+
1261+#include <boost/thread/locks.hpp>
1262+#include <boost/thread/shared_mutex.hpp>
1263+#include <boost/detail/lightweight_test.hpp>
1264+
1265+boost::shared_mutex m;
1266+
1267+int main()
1268+{
1269+ {
1270+ boost::shared_lock<boost::shared_mutex> lk0(m);
1271+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
1272+ BOOST_TEST(lk.mutex() == &m);
1273+ BOOST_TEST(lk.owns_lock() == true);
1274+ BOOST_TEST(lk0.mutex() == 0);
1275+ BOOST_TEST(lk0.owns_lock() == false);
1276+ }
1277+ {
1278+ boost::unique_lock<boost::shared_mutex>
1279+ lk(boost::shared_lock<boost::shared_mutex>(m), boost::chrono::milliseconds(1));
1280+ BOOST_TEST(lk.mutex() == &m);
1281+ BOOST_TEST(lk.owns_lock() == true);
1282+ }
1283+ {
1284+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
1285+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
1286+ BOOST_TEST(lk.mutex() == &m);
1287+ BOOST_TEST(lk.owns_lock() == false);
1288+ BOOST_TEST(lk0.mutex() == 0);
1289+ BOOST_TEST(lk0.owns_lock() == false);
1290+ }
1291+ {
1292+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
1293+ lk0.release();
1294+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
1295+ BOOST_TEST(lk.mutex() == 0);
1296+ BOOST_TEST(lk.owns_lock() == false);
1297+ BOOST_TEST(lk0.mutex() == 0);
1298+ BOOST_TEST(lk0.owns_lock() == false);
1299+ }
1300+
1301+ return boost::report_errors();
1302+}
1303+
1304
1305Property changes on: ../../libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp
1306___________________________________________________________________
1307Added: svn:mime-type
1308 + text/plain
1309Added: svn:keywords
1310 + Id
1311Added: svn:eol-style
1312 + native
1313
1314Index: ../../libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp
1315===================================================================
1316--- ../../libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp (revision 0)
1317+++ ../../libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp (revision 0)
1318@@ -0,0 +1,69 @@
1319+//===----------------------------------------------------------------------===//
1320+//
1321+// The LLVM Compiler Infrastructure
1322+//
1323+// This file is dual licensed under the MIT and the University of Illinois Open
1324+// Source Licenses. See LICENSE.TXT for details.
1325+//
1326+//===----------------------------------------------------------------------===//
1327+
1328+// Copyright (C) 2011 Vicente J. Botet Escriba
1329+//
1330+// Distributed under the Boost Software License, Version 1.0. (See accompanying
1331+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
1332+
1333+// <boost/thread/locks.hpp>
1334+
1335+// template <class Mutex> class unique_lock;
1336+
1337+// template <class Clock, class Duration>
1338+// unique_lock(shared_lock<mutex_type>&&,
1339+// const chrono::time_point<Clock, Duration>&);
1340+
1341+#define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION
1342+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
1343+#define BOOST_THREAD_SHARED_MUTEX_GENERIC
1344+
1345+#include <boost/thread/locks.hpp>
1346+#include <boost/thread/shared_mutex.hpp>
1347+#include <boost/detail/lightweight_test.hpp>
1348+
1349+boost::shared_mutex m;
1350+
1351+int main()
1352+{
1353+ {
1354+ boost::shared_lock<boost::shared_mutex> lk0(m);
1355+ boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
1356+ BOOST_TEST(lk.mutex() == &m);
1357+ BOOST_TEST(lk.owns_lock() == true);
1358+ BOOST_TEST(lk0.mutex() == 0);
1359+ BOOST_TEST(lk0.owns_lock() == false);
1360+ }
1361+ {
1362+ boost::unique_lock<boost::shared_mutex>
1363+ lk( boost::shared_lock<boost::shared_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
1364+ BOOST_TEST(lk.mutex() == &m);
1365+ BOOST_TEST(lk.owns_lock() == true);
1366+ }
1367+ {
1368+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
1369+ boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
1370+ BOOST_TEST(lk.mutex() == &m);
1371+ BOOST_TEST(lk.owns_lock() == false);
1372+ BOOST_TEST(lk0.mutex() == 0);
1373+ BOOST_TEST(lk0.owns_lock() == false);
1374+ }
1375+ {
1376+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
1377+ lk0.release();
1378+ boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
1379+ BOOST_TEST(lk.mutex() == 0);
1380+ BOOST_TEST(lk.owns_lock() == false);
1381+ BOOST_TEST(lk0.mutex() == 0);
1382+ BOOST_TEST(lk0.owns_lock() == false);
1383+ }
1384+
1385+ return boost::report_errors();
1386+}
1387+
1388
1389Property changes on: ../../libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp
1390___________________________________________________________________
1391Added: svn:mime-type
1392 + text/plain
1393Added: svn:keywords
1394 + Id
1395Added: svn:eol-style
1396 + native
1397
1398Index: ../../libs/thread/build/Jamfile.v2
1399===================================================================
1400--- ../../libs/thread/build/Jamfile.v2 (revision 77640)
1401+++ ../../libs/thread/build/Jamfile.v2 (working copy)
1402@@ -225,7 +225,7 @@
1403 explicit thread_sources ;
1404
1405 lib boost_thread
1406- : thread_sources future.cpp
1407+ : thread_sources future.cpp shared_mutex.cpp
1408 : <conditional>@requirements
1409 :
1410 : <link>shared:<define>BOOST_THREAD_USE_DLL=1
1411Index: ../../libs/thread/src/shared_mutex.cpp
1412===================================================================
1413--- ../../libs/thread/src/shared_mutex.cpp (revision 0)
1414+++ ../../libs/thread/src/shared_mutex.cpp (revision 0)
1415@@ -0,0 +1,328 @@
1416+// Copyright Howard Hinnant 2007-2010.
1417+// Copyright Vicente J. Botet Escriba 2012.
1418+// Use, modification and distribution are subject to the
1419+// Boost Software License, Version 1.0. (See accompanying file
1420+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
1421+
1422+#include <boost/thread/v2/shared_mutex.hpp>
1423+#include <boost/thread/locks.hpp>
1424+
1425+namespace boost
1426+{
1427+
1428+ namespace thread_v2
1429+ {
1430+
1431+ // shared_mutex
1432+
1433+ shared_mutex::shared_mutex()
1434+ : state_(0)
1435+ {
1436+ }
1437+
1438+ shared_mutex::~shared_mutex()
1439+ {
1440+ boost::lock_guard<mutex_t> _(mut_);
1441+ }
1442+
1443+ // Exclusive ownership
1444+
1445+ void
1446+ shared_mutex::lock()
1447+ {
1448+ boost::unique_lock<mutex_t> lk(mut_);
1449+ while (state_ & write_entered_)
1450+ gate1_.wait(lk);
1451+ state_ |= write_entered_;
1452+ while (state_ & n_readers_)
1453+ gate2_.wait(lk);
1454+ }
1455+
1456+ bool
1457+ shared_mutex::try_lock()
1458+ {
1459+ boost::unique_lock<mutex_t> lk(mut_);
1460+ if (state_ == 0)
1461+ {
1462+ state_ = write_entered_;
1463+ return true;
1464+ }
1465+ return false;
1466+ }
1467+
1468+ void
1469+ shared_mutex::unlock()
1470+ {
1471+ boost::lock_guard<mutex_t> _(mut_);
1472+ state_ = 0;
1473+ gate1_.notify_all();
1474+ }
1475+
1476+ // Shared ownership
1477+
1478+ void
1479+ shared_mutex::lock_shared()
1480+ {
1481+ boost::unique_lock<mutex_t> lk(mut_);
1482+ while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
1483+ gate1_.wait(lk);
1484+ count_t num_readers = (state_ & n_readers_) + 1;
1485+ state_ &= ~n_readers_;
1486+ state_ |= num_readers;
1487+ }
1488+
1489+ bool
1490+ shared_mutex::try_lock_shared()
1491+ {
1492+ boost::unique_lock<mutex_t> lk(mut_);
1493+ count_t num_readers = state_ & n_readers_;
1494+ if (!(state_ & write_entered_) && num_readers != n_readers_)
1495+ {
1496+ ++num_readers;
1497+ state_ &= ~n_readers_;
1498+ state_ |= num_readers;
1499+ return true;
1500+ }
1501+ return false;
1502+ }
1503+
1504+ void
1505+ shared_mutex::unlock_shared()
1506+ {
1507+ boost::lock_guard<mutex_t> _(mut_);
1508+ count_t num_readers = (state_ & n_readers_) - 1;
1509+ state_ &= ~n_readers_;
1510+ state_ |= num_readers;
1511+ if (state_ & write_entered_)
1512+ {
1513+ if (num_readers == 0)
1514+ gate2_.notify_one();
1515+ }
1516+ else
1517+ {
1518+ if (num_readers == n_readers_ - 1)
1519+ gate1_.notify_one();
1520+ }
1521+ }
1522+
1523+ // upgrade_mutex
1524+
1525+ upgrade_mutex::upgrade_mutex()
1526+ : gate1_(),
1527+ gate2_(),
1528+ state_(0)
1529+ {
1530+ }
1531+
1532+ upgrade_mutex::~upgrade_mutex()
1533+ {
1534+ boost::lock_guard<mutex_t> _(mut_);
1535+ }
1536+
1537+ // Exclusive ownership
1538+
1539+ void
1540+ upgrade_mutex::lock()
1541+ {
1542+ boost::unique_lock<mutex_t> lk(mut_);
1543+ while (state_ & (write_entered_ | upgradable_entered_))
1544+ gate1_.wait(lk);
1545+ state_ |= write_entered_;
1546+ while (state_ & n_readers_)
1547+ gate2_.wait(lk);
1548+ }
1549+
1550+ bool
1551+ upgrade_mutex::try_lock()
1552+ {
1553+ boost::unique_lock<mutex_t> lk(mut_);
1554+ if (state_ == 0)
1555+ {
1556+ state_ = write_entered_;
1557+ return true;
1558+ }
1559+ return false;
1560+ }
1561+
1562+ void
1563+ upgrade_mutex::unlock()
1564+ {
1565+ boost::lock_guard<mutex_t> _(mut_);
1566+ state_ = 0;
1567+ gate1_.notify_all();
1568+ }
1569+
1570+ // Shared ownership
1571+
1572+ void
1573+ upgrade_mutex::lock_shared()
1574+ {
1575+ boost::unique_lock<mutex_t> lk(mut_);
1576+ while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
1577+ gate1_.wait(lk);
1578+ count_t num_readers = (state_ & n_readers_) + 1;
1579+ state_ &= ~n_readers_;
1580+ state_ |= num_readers;
1581+ }
1582+
1583+ bool
1584+ upgrade_mutex::try_lock_shared()
1585+ {
1586+ boost::unique_lock<mutex_t> lk(mut_);
1587+ count_t num_readers = state_ & n_readers_;
1588+ if (!(state_ & write_entered_) && num_readers != n_readers_)
1589+ {
1590+ ++num_readers;
1591+ state_ &= ~n_readers_;
1592+ state_ |= num_readers;
1593+ return true;
1594+ }
1595+ return false;
1596+ }
1597+
1598+ void
1599+ upgrade_mutex::unlock_shared()
1600+ {
1601+ boost::lock_guard<mutex_t> _(mut_);
1602+ count_t num_readers = (state_ & n_readers_) - 1;
1603+ state_ &= ~n_readers_;
1604+ state_ |= num_readers;
1605+ if (state_ & write_entered_)
1606+ {
1607+ if (num_readers == 0)
1608+ gate2_.notify_one();
1609+ }
1610+ else
1611+ {
1612+ if (num_readers == n_readers_ - 1)
1613+ gate1_.notify_one();
1614+ }
1615+ }
1616+
1617+ // Upgrade ownership
1618+
1619+ void
1620+ upgrade_mutex::lock_upgrade()
1621+ {
1622+ boost::unique_lock<mutex_t> lk(mut_);
1623+ while ((state_ & (write_entered_ | upgradable_entered_)) ||
1624+ (state_ & n_readers_) == n_readers_)
1625+ gate1_.wait(lk);
1626+ count_t num_readers = (state_ & n_readers_) + 1;
1627+ state_ &= ~n_readers_;
1628+ state_ |= upgradable_entered_ | num_readers;
1629+ }
1630+
1631+ bool
1632+ upgrade_mutex::try_lock_upgrade()
1633+ {
1634+ boost::unique_lock<mutex_t> lk(mut_);
1635+ count_t num_readers = state_ & n_readers_;
1636+ if (!(state_ & (write_entered_ | upgradable_entered_))
1637+ && num_readers != n_readers_)
1638+ {
1639+ ++num_readers;
1640+ state_ &= ~n_readers_;
1641+ state_ |= upgradable_entered_ | num_readers;
1642+ return true;
1643+ }
1644+ return false;
1645+ }
1646+
1647+ void
1648+ upgrade_mutex::unlock_upgrade()
1649+ {
1650+ {
1651+ boost::lock_guard<mutex_t> _(mut_);
1652+ count_t num_readers = (state_ & n_readers_) - 1;
1653+ state_ &= ~(upgradable_entered_ | n_readers_);
1654+ state_ |= num_readers;
1655+ }
1656+ gate1_.notify_all();
1657+ }
1658+
1659+ // Shared <-> Exclusive
1660+
1661+ bool
1662+ upgrade_mutex::try_unlock_shared_and_lock()
1663+ {
1664+ boost::unique_lock<mutex_t> lk(mut_);
1665+ if (state_ == 1)
1666+ {
1667+ state_ = write_entered_;
1668+ return true;
1669+ }
1670+ return false;
1671+ }
1672+
1673+ void
1674+ upgrade_mutex::unlock_and_lock_shared()
1675+ {
1676+ {
1677+ boost::lock_guard<mutex_t> _(mut_);
1678+ state_ = 1;
1679+ }
1680+ gate1_.notify_all();
1681+ }
1682+
1683+ // Shared <-> Upgrade
1684+
1685+ bool
1686+ upgrade_mutex::try_unlock_shared_and_lock_upgrade()
1687+ {
1688+ boost::unique_lock<mutex_t> lk(mut_);
1689+ if (!(state_ & (write_entered_ | upgradable_entered_)))
1690+ {
1691+ state_ |= upgradable_entered_;
1692+ return true;
1693+ }
1694+ return false;
1695+ }
1696+
1697+ void
1698+ upgrade_mutex::unlock_upgrade_and_lock_shared()
1699+ {
1700+ {
1701+ boost::lock_guard<mutex_t> _(mut_);
1702+ state_ &= ~upgradable_entered_;
1703+ }
1704+ gate1_.notify_all();
1705+ }
1706+
1707+ // Upgrade <-> Exclusive
1708+
1709+ void
1710+ upgrade_mutex::unlock_upgrade_and_lock()
1711+ {
1712+ boost::unique_lock<mutex_t> lk(mut_);
1713+ count_t num_readers = (state_ & n_readers_) - 1;
1714+ state_ &= ~(upgradable_entered_ | n_readers_);
1715+ state_ |= write_entered_ | num_readers;
1716+ while (state_ & n_readers_)
1717+ gate2_.wait(lk);
1718+ }
1719+
1720+ bool
1721+ upgrade_mutex::try_unlock_upgrade_and_lock()
1722+ {
1723+ boost::unique_lock<mutex_t> lk(mut_);
1724+ if (state_ == (upgradable_entered_ | 1))
1725+ {
1726+ state_ = write_entered_;
1727+ return true;
1728+ }
1729+ return false;
1730+ }
1731+
1732+ void
1733+ upgrade_mutex::unlock_and_lock_upgrade()
1734+ {
1735+ {
1736+ boost::lock_guard<mutex_t> _(mut_);
1737+ state_ = upgradable_entered_ | 1;
1738+ }
1739+ gate1_.notify_all();
1740+ }
1741+
1742+ } // thread_v2
1743+} // boost
1744
1745Property changes on: ../../libs/thread/src/shared_mutex.cpp
1746___________________________________________________________________
1747Added: svn:mime-type
1748 + text/plain
1749Added: svn:keywords
1750 + Id
1751Added: svn:eol-style
1752 + native
1753