19
19
#define SWIFT_RUNTIME_MUTEX_H
20
20
21
21
#include < type_traits>
22
+ #include < utility>
22
23
23
24
#if __has_include(<unistd.h>)
24
25
#include < unistd.h>
@@ -211,10 +212,10 @@ class ConditionVariable {
211
212
// /
212
213
// / Precondition: Mutex not held by this thread, undefined otherwise.
213
214
template <typename CriticalSection>
214
- auto withLock (CriticalSection criticalSection)
215
- -> decltype(criticalSection()) {
215
+ auto withLock (CriticalSection && criticalSection)
216
+ -> decltype(std::forward<CriticalSection>( criticalSection) ()) {
216
217
ScopedLock guard (*this );
217
- return criticalSection ();
218
+ return std::forward<CriticalSection>( criticalSection) ();
218
219
}
219
220
220
221
// / Acquires lock before calling the supplied critical section. If critical
@@ -242,7 +243,7 @@ class ConditionVariable {
242
243
// / Precondition: Mutex not held by this thread, undefined otherwise.
243
244
template <typename CriticalSection>
244
245
void withLockOrWait (ConditionVariable &condition,
245
- CriticalSection criticalSection) {
246
+ CriticalSection && criticalSection) {
246
247
withLock ([&] {
247
248
while (!criticalSection ()) {
248
249
wait (condition);
@@ -266,11 +267,11 @@ class ConditionVariable {
266
267
// / Precondition: Mutex not held by this thread, undefined otherwise.
267
268
template <typename CriticalSection>
268
269
auto withLockThenNotifyOne (ConditionVariable &condition,
269
- CriticalSection criticalSection)
270
- -> decltype(criticalSection()) {
270
+ CriticalSection && criticalSection)
271
+ -> decltype(std::forward<CriticalSection>( criticalSection) ()) {
271
272
return withLock ([&] {
272
273
ScopedNotifyOne guard (condition);
273
- return criticalSection ();
274
+ return std::forward<CriticalSection>( criticalSection) ();
274
275
});
275
276
}
276
277
@@ -290,11 +291,11 @@ class ConditionVariable {
290
291
// / Precondition: Mutex not held by this thread, undefined otherwise.
291
292
template <typename CriticalSection>
292
293
auto withLockThenNotifyAll (ConditionVariable &condition,
293
- CriticalSection criticalSection)
294
- -> decltype(criticalSection()) {
294
+ CriticalSection && criticalSection)
295
+ -> decltype(std::forward<CriticalSection>( criticalSection) ()) {
295
296
return withLock ([&] {
296
297
ScopedNotifyAll guard (condition);
297
- return criticalSection ();
298
+ return std::forward<CriticalSection>( criticalSection) ();
298
299
});
299
300
}
300
301
@@ -389,10 +390,10 @@ class Mutex {
389
390
// /
390
391
// / Precondition: Mutex not held by this thread, undefined otherwise.
391
392
template <typename CriticalSection>
392
- auto withLock (CriticalSection criticalSection)
393
- -> decltype(criticalSection()) {
393
+ auto withLock (CriticalSection && criticalSection)
394
+ -> decltype(std::forward<CriticalSection>( criticalSection) ()) {
394
395
ScopedLock guard (*this );
395
- return criticalSection ();
396
+ return std::forward<CriticalSection>( criticalSection) ();
396
397
}
397
398
398
399
// / A stack based object that locks the supplied mutex on construction
@@ -613,10 +614,10 @@ class ReadWriteLock {
613
614
// /
614
615
// / Precondition: ReadWriteLock not held by this thread, undefined otherwise.
615
616
template <typename CriticalSection>
616
- auto withReadLock (CriticalSection criticalSection)
617
- -> decltype(criticalSection()) {
617
+ auto withReadLock (CriticalSection && criticalSection)
618
+ -> decltype(std::forward<CriticalSection>( criticalSection) ()) {
618
619
ScopedReadLock guard (*this );
619
- return criticalSection ();
620
+ return std::forward<CriticalSection>( criticalSection) ();
620
621
}
621
622
622
623
// / Acquires write lock before calling the supplied critical section and
@@ -633,10 +634,10 @@ class ReadWriteLock {
633
634
// /
634
635
// / Precondition: ReadWriteLock not held by this thread, undefined otherwise.
635
636
template <typename CriticalSection>
636
- auto withWriteLock (CriticalSection criticalSection)
637
- -> decltype(criticalSection()) {
637
+ auto withWriteLock (CriticalSection && criticalSection)
638
+ -> decltype(std::forward<CriticalSection>( criticalSection) ()) {
638
639
ScopedWriteLock guard (*this );
639
- return criticalSection ();
640
+ return std::forward<CriticalSection>( criticalSection) ();
640
641
}
641
642
642
643
private:
@@ -683,7 +684,7 @@ class StaticConditionVariable {
683
684
#if SWIFT_MUTEX_SUPPORTS_CONSTEXPR
684
685
constexpr
685
686
#endif
686
- StaticMutex ()
687
+ StaticMutex ()
687
688
: Handle(MutexPlatformHelper::conditionStaticInit()) {
688
689
}
689
690
@@ -706,16 +707,16 @@ class StaticConditionVariable {
706
707
707
708
// / See Mutex::lock
708
709
template <typename CriticalSection>
709
- auto withLock (CriticalSection criticalSection)
710
- -> decltype(criticalSection()) {
710
+ auto withLock (CriticalSection && criticalSection)
711
+ -> decltype(std::forward<CriticalSection>( criticalSection) ()) {
711
712
ScopedLock guard (*this );
712
- return criticalSection ();
713
+ return std::forward<CriticalSection>( criticalSection) ();
713
714
}
714
715
715
716
// / See Mutex::withLockOrWait
716
717
template <typename CriticalSection>
717
718
void withLockOrWait (StaticConditionVariable &condition,
718
- CriticalSection criticalSection) {
719
+ CriticalSection && criticalSection) {
719
720
withLock ([&] {
720
721
while (!criticalSection ()) {
721
722
wait (condition);
@@ -726,22 +727,22 @@ class StaticConditionVariable {
726
727
// / See Mutex::withLockThenNotifyOne
727
728
template <typename CriticalSection>
728
729
auto withLockThenNotifyOne (StaticConditionVariable &condition,
729
- CriticalSection criticalSection)
730
- -> decltype(criticalSection()) {
730
+ CriticalSection && criticalSection)
731
+ -> decltype(std::forward<CriticalSection>( criticalSection) ()) {
731
732
return withLock ([&] {
732
733
StaticConditionVariable::ScopedNotifyOne guard (condition);
733
- return criticalSection ();
734
+ return std::forward<CriticalSection>( criticalSection) ();
734
735
});
735
736
}
736
737
737
738
// / See Mutex::withLockThenNotifyAll
738
739
template <typename CriticalSection>
739
740
auto withLockThenNotifyAll (StaticConditionVariable &condition,
740
- CriticalSection criticalSection)
741
- -> decltype(criticalSection()) {
741
+ CriticalSection && criticalSection)
742
+ -> decltype(std::forward<CriticalSection>( criticalSection) ()) {
742
743
return withLock ([&] {
743
744
StaticConditionVariable::ScopedNotifyAll guard (condition);
744
- return criticalSection ();
745
+ return std::forward<CriticalSection>( criticalSection) ();
745
746
});
746
747
}
747
748
@@ -779,7 +780,7 @@ class StaticMutex {
779
780
#if SWIFT_MUTEX_SUPPORTS_CONSTEXPR
780
781
constexpr
781
782
#endif
782
- StaticMutex ()
783
+ StaticMutex ()
783
784
: Handle(MutexPlatformHelper::staticInit()) {
784
785
}
785
786
@@ -794,10 +795,10 @@ class StaticMutex {
794
795
795
796
// / See Mutex::lock
796
797
template <typename CriticalSection>
797
- auto withLock (CriticalSection criticalSection)
798
- -> decltype(criticalSection()) {
798
+ auto withLock (CriticalSection && criticalSection)
799
+ -> decltype(std::forward<CriticalSection>( criticalSection) ()) {
799
800
ScopedLock guard (*this );
800
- return criticalSection ();
801
+ return std::forward<CriticalSection>( criticalSection) ();
801
802
}
802
803
803
804
// / A stack based object that locks the supplied mutex on construction
@@ -830,7 +831,7 @@ class StaticReadWriteLock {
830
831
#if SWIFT_READWRITELOCK_SUPPORTS_CONSTEXPR
831
832
constexpr
832
833
#endif
833
- StaticReadWriteLock ()
834
+ StaticReadWriteLock ()
834
835
: Handle(ReadWriteLockPlatformHelper::staticInit()) {
835
836
}
836
837
@@ -858,18 +859,18 @@ class StaticReadWriteLock {
858
859
859
860
// / See ReadWriteLock::withReadLock
860
861
template <typename CriticalSection>
861
- auto withReadLock (CriticalSection criticalSection)
862
- -> decltype(criticalSection()) {
862
+ auto withReadLock (CriticalSection && criticalSection)
863
+ -> decltype(std::forward<CriticalSection>( criticalSection) ()) {
863
864
StaticScopedReadLock guard (*this );
864
- return criticalSection ();
865
+ return std::forward<CriticalSection>( criticalSection) ();
865
866
}
866
867
867
868
// / See ReadWriteLock::withWriteLock
868
869
template <typename CriticalSection>
869
- auto withWriteLock (CriticalSection criticalSection)
870
- -> decltype(criticalSection()) {
870
+ auto withWriteLock (CriticalSection && criticalSection)
871
+ -> decltype(std::forward<CriticalSection>( criticalSection) ()) {
871
872
StaticScopedWriteLock guard (*this );
872
- return criticalSection ();
873
+ return std::forward<CriticalSection>( criticalSection) ();
873
874
}
874
875
875
876
private:
@@ -895,7 +896,7 @@ class StaticUnsafeMutex {
895
896
#if SWIFT_MUTEX_SUPPORTS_CONSTEXPR
896
897
constexpr
897
898
#endif
898
- StaticUnsafeMutex ()
899
+ StaticUnsafeMutex ()
899
900
: Handle(MutexPlatformHelper::staticInit()) {
900
901
}
901
902
@@ -920,6 +921,16 @@ class StaticUnsafeMutex {
920
921
// / - Ignores errors that may happen, undefined when an error happens.
921
922
void unlock () { MutexPlatformHelper::unsafeUnlock (Handle); }
922
923
924
+ template <typename CriticalSection>
925
+ auto withLock (CriticalSection &&criticalSection)
926
+ -> decltype(std::forward<CriticalSection>(criticalSection)()) {
927
+ ScopedLock guard (*this );
928
+ return std::forward<CriticalSection>(criticalSection)();
929
+ }
930
+
931
+ typedef ScopedLockT<StaticUnsafeMutex, false > ScopedLock;
932
+ typedef ScopedLockT<StaticUnsafeMutex, true > ScopedUnlock;
933
+
923
934
private:
924
935
MutexHandle Handle;
925
936
};
@@ -943,6 +954,12 @@ class IndirectMutex {
943
954
944
955
bool try_lock () { return Ptr->try_lock (); }
945
956
957
+ template <typename CriticalSection>
958
+ auto withLock (CriticalSection &&criticalSection)
959
+ -> decltype(criticalSection()) {
960
+ return Ptr->withLock (std::forward<CriticalSection>(criticalSection));
961
+ }
962
+
946
963
// / A stack based object that locks the supplied mutex on construction
947
964
// / and unlocks it on destruction.
948
965
// /
0 commit comments