From Jason Turner

[thread.lock]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpnh_d056w/{from.md → to.md} +313 -2
tmp/tmpnh_d056w/{from.md → to.md} RENAMED
@@ -107,11 +107,11 @@ namespace std {
107
 
108
  unique_lock(unique_lock const&) = delete;
109
  unique_lock& operator=(unique_lock const&) = delete;
110
 
111
  unique_lock(unique_lock&& u) noexcept;
112
- unique_lock& operator=(unique_lock&& u) noexcept;
113
 
114
  // [thread.lock.unique.locking], locking:
115
  void lock();
116
  bool try_lock();
117
 
@@ -251,11 +251,11 @@ unique_lock(unique_lock&& u) noexcept;
251
  *Postconditions:* `pm == u_p.pm` and `owns == u_p.owns` (where `u_p` is
252
  the state of `u` just prior to this construction), `u.pm == 0` and
253
  `u.owns == false`.
254
 
255
  ``` cpp
256
- unique_lock& operator=(unique_lock&& u) noexcept;
257
  ```
258
 
259
  *Effects:* If `owns` calls `pm->unlock()`.
260
 
261
  *Postconditions:* `pm == u_p.pm` and `owns == u_p.owns` (where `u_p` is
@@ -264,10 +264,12 @@ the state of `u` just prior to this construction), `u.pm == 0` and
264
 
265
  With a recursive mutex it is possible for both `*this` and `u` to own
266
  the same mutex before the assignment. In this case, `*this` will own the
267
  mutex after the assignment and `u` will not.
268
 
 
 
269
  ``` cpp
270
  ~unique_lock();
271
  ```
272
 
273
  *Effects:* If `owns` calls `pm->unlock()`.
@@ -406,5 +408,314 @@ explicit operator bool() const noexcept;
406
  mutex_type *mutex() const noexcept;
407
  ```
408
 
409
  *Returns:* `pm`
410
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
  unique_lock(unique_lock const&) = delete;
109
  unique_lock& operator=(unique_lock const&) = delete;
110
 
111
  unique_lock(unique_lock&& u) noexcept;
112
+ unique_lock& operator=(unique_lock&& u);
113
 
114
  // [thread.lock.unique.locking], locking:
115
  void lock();
116
  bool try_lock();
117
 
 
251
  *Postconditions:* `pm == u_p.pm` and `owns == u_p.owns` (where `u_p` is
252
  the state of `u` just prior to this construction), `u.pm == 0` and
253
  `u.owns == false`.
254
 
255
  ``` cpp
256
+ unique_lock& operator=(unique_lock&& u);
257
  ```
258
 
259
  *Effects:* If `owns` calls `pm->unlock()`.
260
 
261
  *Postconditions:* `pm == u_p.pm` and `owns == u_p.owns` (where `u_p` is
 
264
 
265
  With a recursive mutex it is possible for both `*this` and `u` to own
266
  the same mutex before the assignment. In this case, `*this` will own the
267
  mutex after the assignment and `u` will not.
268
 
269
+ *Throws:* Nothing.
270
+
271
  ``` cpp
272
  ~unique_lock();
273
  ```
274
 
275
  *Effects:* If `owns` calls `pm->unlock()`.
 
408
  mutex_type *mutex() const noexcept;
409
  ```
410
 
411
  *Returns:* `pm`
412
 
413
+ #### Class template `shared_lock` <a id="thread.lock.shared">[[thread.lock.shared]]</a>
414
+
415
+ ``` cpp
416
+ namespace std {
417
+
418
+ template <class Mutex>
419
+ class shared_lock {
420
+ public:
421
+ typedef Mutex mutex_type;
422
+
423
+ // Shared locking
424
+ shared_lock() noexcept;
425
+ explicit shared_lock(mutex_type& m); // blocking
426
+ shared_lock(mutex_type& m, defer_lock_t) noexcept;
427
+ shared_lock(mutex_type& m, try_to_lock_t);
428
+ shared_lock(mutex_type& m, adopt_lock_t);
429
+ template <class Clock, class Duration>
430
+ shared_lock(mutex_type& m,
431
+ const chrono::time_point<Clock, Duration>& abs_time);
432
+ template <class Rep, class Period>
433
+ shared_lock(mutex_type& m,
434
+ const chrono::duration<Rep, Period>& rel_time);
435
+ ~shared_lock();
436
+
437
+ shared_lock(shared_lock const&) = delete;
438
+ shared_lock& operator=(shared_lock const&) = delete;
439
+
440
+ shared_lock(shared_lock&& u) noexcept;
441
+ shared_lock& operator=(shared_lock&& u) noexcept;
442
+
443
+ void lock(); // blocking
444
+ bool try_lock();
445
+ template <class Rep, class Period>
446
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
447
+ template <class Clock, class Duration>
448
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
449
+ void unlock();
450
+
451
+ // Setters
452
+ void swap(shared_lock& u) noexcept;
453
+ mutex_type* release() noexcept;
454
+
455
+ // Getters
456
+ bool owns_lock() const noexcept;
457
+ explicit operator bool () const noexcept;
458
+ mutex_type* mutex() const noexcept;
459
+
460
+ private:
461
+ mutex_type* pm; // exposition only
462
+ bool owns; // exposition only
463
+ };
464
+
465
+ template <class Mutex>
466
+ void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
467
+
468
+ } // std
469
+ ```
470
+
471
+ An object of type `shared_lock` controls the shared ownership of a
472
+ lockable object within a scope. Shared ownership of the lockable object
473
+ may be acquired at construction or after construction, and may be
474
+ transferred, after acquisition, to another `shared_lock` object. Objects
475
+ of type `shared_lock` are not copyable but are movable. The behavior of
476
+ a program is undefined if the contained pointer `pm` is not null and the
477
+ lockable object pointed to by `pm` does not exist for the entire
478
+ remaining lifetime ([[basic.life]]) of the `shared_lock` object. The
479
+ supplied `Mutex` type shall meet the shared mutex requirements (
480
+ [[thread.sharedtimedmutex.requirements]]).
481
+
482
+ `shared_lock<Mutex>` meets the `TimedLockable` requirements (
483
+ [[thread.req.lockable.timed]]).
484
+
485
+ ##### `shared_lock` constructors, destructor, and assignment <a id="thread.lock.shared.cons">[[thread.lock.shared.cons]]</a>
486
+
487
+ ``` cpp
488
+ shared_lock() noexcept;
489
+ ```
490
+
491
+ *Effects:* Constructs an object of type `shared_lock`.
492
+
493
+ *Postconditions:* `pm == nullptr` and `owns == false`.
494
+
495
+ ``` cpp
496
+ explicit shared_lock(mutex_type& m);
497
+ ```
498
+
499
+ *Requires:* The calling thread does not own the mutex for any ownership
500
+ mode.
501
+
502
+ *Effects:* Constructs an object of type `shared_lock` and calls
503
+ `m.lock_shared()`.
504
+
505
+ *Postconditions:* `pm == &m` and `owns == true`.
506
+
507
+ ``` cpp
508
+ shared_lock(mutex_type& m, defer_lock_t) noexcept;
509
+ ```
510
+
511
+ *Effects:* Constructs an object of type `shared_lock`.
512
+
513
+ *Postconditions:* `pm == &m` and `owns == false`.
514
+
515
+ ``` cpp
516
+ shared_lock(mutex_type& m, try_to_lock_t);
517
+ ```
518
+
519
+ *Requires:* The calling thread does not own the mutex for any ownership
520
+ mode.
521
+
522
+ *Effects:* Constructs an object of type `shared_lock` and calls
523
+ `m.try_lock_shared()`.
524
+
525
+ *Postconditions:* `pm == &m` and `owns == res` where `res` is the value
526
+ returned by the call to `m.try_lock_shared()`.
527
+
528
+ ``` cpp
529
+ shared_lock(mutex_type& m, adopt_lock_t);
530
+ ```
531
+
532
+ *Requires:* The calling thread has shared ownership of the mutex.
533
+
534
+ *Effects:* Constructs an object of type `shared_lock`.
535
+
536
+ *Postconditions:* `pm == &m` and `owns == true`.
537
+
538
+ ``` cpp
539
+ template <class Clock, class Duration>
540
+ shared_lock(mutex_type& m,
541
+ const chrono::time_point<Clock, Duration>& abs_time);
542
+ ```
543
+
544
+ *Requires:* The calling thread does not own the mutex for any ownership
545
+ mode.
546
+
547
+ *Effects:* Constructs an object of type `shared_lock` and calls
548
+ `m.try_lock_shared_until(abs_time)`.
549
+
550
+ *Postconditions:* `pm == &m` and `owns == res` where `res` is the value
551
+ returned by the call to `m.try_lock_shared_until(abs_time)`.
552
+
553
+ ``` cpp
554
+ template <class Rep, class Period>
555
+ shared_lock(mutex_type& m,
556
+ const chrono::duration<Rep, Period>& rel_time);
557
+ ```
558
+
559
+ *Requires:* The calling thread does not own the mutex for any ownership
560
+ mode.
561
+
562
+ *Effects:* Constructs an object of type `shared_lock` and calls
563
+ `m.try_lock_shared_for(rel_time)`.
564
+
565
+ *Postconditions:* `pm == &m` and `owns == res` where `res` is the value
566
+ returned by the call to `m.try_lock_shared_for(rel_time)`.
567
+
568
+ ``` cpp
569
+ ~shared_lock();
570
+ ```
571
+
572
+ *Effects:* If `owns` calls `pm->unlock_shared()`.
573
+
574
+ ``` cpp
575
+ shared_lock(shared_lock&& sl) noexcept;
576
+ ```
577
+
578
+ *Postconditions:* `pm == &sl_p.pm` and `owns == sl_p.owns` (where `sl_p`
579
+ is the state of `sl` just prior to this construction),
580
+ `sl.pm == nullptr` and `sl.owns == false`.
581
+
582
+ ``` cpp
583
+ shared_lock& operator=(shared_lock&& sl) noexcept;
584
+ ```
585
+
586
+ *Effects:* If `owns` calls `pm->unlock_shared()`.
587
+
588
+ *Postconditions:* `pm == &sl_p.pm` and `owns == sl_p.owns` (where `sl_p`
589
+ is the state of `sl` just prior to this assignment), `sl.pm == nullptr`
590
+ and `sl.owns == false`.
591
+
592
+ ##### `shared_lock` locking <a id="thread.lock.shared.locking">[[thread.lock.shared.locking]]</a>
593
+
594
+ ``` cpp
595
+ void lock();
596
+ ```
597
+
598
+ *Effects:* `pm->lock_shared()`.
599
+
600
+ *Postconditions:* `owns == true`.
601
+
602
+ *Throws:* Any exception thrown by `pm->lock_shared()`. `system_error` if
603
+ an exception is required ([[thread.req.exception]]). `system_error`
604
+ with an error condition of `operation_not_permitted` if `pm` is
605
+ `nullptr`. `system_error` with an error condition of
606
+ `resource_deadlock_would_occur` if on entry `owns` is `true`.
607
+
608
+ ``` cpp
609
+ bool try_lock();
610
+ ```
611
+
612
+ *Effects:* `pm->try_lock_shared()`.
613
+
614
+ *Returns:* The value returned by the call to `pm->try_lock_shared()`.
615
+
616
+ *Postconditions:* `owns == res`, where `res` is the value returned by
617
+ the call to `pm->try_lock_shared()`.
618
+
619
+ *Throws:* Any exception thrown by `pm->try_lock_shared()`.
620
+ `system_error` if an exception is required ([[thread.req.exception]]).
621
+ `system_error` with an error condition of `operation_not_permitted` if
622
+ `pm` is `nullptr`. `system_error` with an error condition of
623
+ `resource_deadlock_would_occur` if on entry `owns` is `true`.
624
+
625
+ ``` cpp
626
+ template <class Clock, class Duration>
627
+ bool
628
+ try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
629
+ ```
630
+
631
+ *Effects:* `pm->try_lock_shared_until(abs_time)`.
632
+
633
+ *Returns:* The value returned by the call to
634
+ `pm->try_lock_shared_until(abs_time)`.
635
+
636
+ *Postconditions:* `owns == res`, where `res` is the value returned by
637
+ the call to `pm->try_lock_shared_until(abs_time)`.
638
+
639
+ *Throws:* Any exception thrown by `pm->try_lock_shared_until(abs_time)`.
640
+ `system_error` if an exception is required ([[thread.req.exception]]).
641
+ `system_error` with an error condition of `operation_not_permitted` if
642
+ `pm` is `nullptr`. `system_error` with an error condition of
643
+ `resource_deadlock_would_occur` if on entry `owns` is `true`.
644
+
645
+ ``` cpp
646
+ template <class Rep, class Period>
647
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
648
+ ```
649
+
650
+ *Effects:* `pm->try_lock_shared_for(rel_time)`.
651
+
652
+ *Returns:* The value returned by the call to
653
+ `pm->try_lock_shared_for(rel_time)`.
654
+
655
+ *Postconditions:* `owns == res`, where `res` is the value returned by
656
+ the call to `pm->try_lock_shared_for(rel_time)`.
657
+
658
+ *Throws:* Any exception thrown by `pm->try_lock_shared_for(rel_time)`.
659
+ `system_error` if an exception is required  ([[thread.req.exception]]).
660
+ `system_error` with an error condition of `operation_not_permitted` if
661
+ `pm` is `nullptr`. `system_error` with an error condition of
662
+ `resource_deadlock_would_occur` if on entry `owns` is `true`.
663
+
664
+ ``` cpp
665
+ void unlock();
666
+ ```
667
+
668
+ *Effects:* `pm->unlock_shared()`.
669
+
670
+ *Postconditions:* `owns == false`.
671
+
672
+ *Throws:* `system_error` when an exception is required
673
+  ([[thread.req.exception]]).
674
+
675
+ *Error conditions:*
676
+
677
+ - `operation_not_permitted` — if on entry `owns` is `false`.
678
+
679
+ ##### `shared_lock` modifiers <a id="thread.lock.shared.mod">[[thread.lock.shared.mod]]</a>
680
+
681
+ ``` cpp
682
+ void swap(shared_lock& sl) noexcept;
683
+ ```
684
+
685
+ *Effects:* Swaps the data members of `*this` and `sl`.
686
+
687
+ ``` cpp
688
+ mutex_type* release() noexcept;
689
+ ```
690
+
691
+ *Returns:* The previous value of `pm`.
692
+
693
+ *Postconditions:* `pm == nullptr` and `owns == false`.
694
+
695
+ ``` cpp
696
+ template <class Mutex>
697
+ void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
698
+ ```
699
+
700
+ *Effects:* `x.swap(y)`.
701
+
702
+ ##### `shared_lock` observers <a id="thread.lock.shared.obs">[[thread.lock.shared.obs]]</a>
703
+
704
+ ``` cpp
705
+ bool owns_lock() const noexcept;
706
+ ```
707
+
708
+ *Returns:* `owns`.
709
+
710
+ ``` cpp
711
+ explicit operator bool () const noexcept;
712
+ ```
713
+
714
+ *Returns:* `owns`.
715
+
716
+ ``` cpp
717
+ mutex_type* mutex() const noexcept;
718
+ ```
719
+
720
+ *Returns:* `pm`.
721
+