Skip to content

Commit 1f82aee

Browse files
committed
[NFC] Assorted API improvements in Mutex.h
- take critical sections by reference - forward critical sections into calls (except when called multiple times) - add withLock methods where they were missing
1 parent 3fbb52c commit 1f82aee

File tree

1 file changed

+59
-42
lines changed

1 file changed

+59
-42
lines changed

include/swift/Runtime/Mutex.h

Lines changed: 59 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define SWIFT_RUNTIME_MUTEX_H
2020

2121
#include <type_traits>
22+
#include <utility>
2223

2324
#if __has_include(<unistd.h>)
2425
#include <unistd.h>
@@ -211,10 +212,10 @@ class ConditionVariable {
211212
///
212213
/// Precondition: Mutex not held by this thread, undefined otherwise.
213214
template <typename CriticalSection>
214-
auto withLock(CriticalSection criticalSection)
215-
-> decltype(criticalSection()) {
215+
auto withLock(CriticalSection &&criticalSection)
216+
-> decltype(std::forward<CriticalSection>(criticalSection)()) {
216217
ScopedLock guard(*this);
217-
return criticalSection();
218+
return std::forward<CriticalSection>(criticalSection)();
218219
}
219220

220221
/// Acquires lock before calling the supplied critical section. If critical
@@ -242,7 +243,7 @@ class ConditionVariable {
242243
/// Precondition: Mutex not held by this thread, undefined otherwise.
243244
template <typename CriticalSection>
244245
void withLockOrWait(ConditionVariable &condition,
245-
CriticalSection criticalSection) {
246+
CriticalSection &&criticalSection) {
246247
withLock([&] {
247248
while (!criticalSection()) {
248249
wait(condition);
@@ -266,11 +267,11 @@ class ConditionVariable {
266267
/// Precondition: Mutex not held by this thread, undefined otherwise.
267268
template <typename CriticalSection>
268269
auto withLockThenNotifyOne(ConditionVariable &condition,
269-
CriticalSection criticalSection)
270-
-> decltype(criticalSection()) {
270+
CriticalSection &&criticalSection)
271+
-> decltype(std::forward<CriticalSection>(criticalSection)()) {
271272
return withLock([&] {
272273
ScopedNotifyOne guard(condition);
273-
return criticalSection();
274+
return std::forward<CriticalSection>(criticalSection)();
274275
});
275276
}
276277

@@ -290,11 +291,11 @@ class ConditionVariable {
290291
/// Precondition: Mutex not held by this thread, undefined otherwise.
291292
template <typename CriticalSection>
292293
auto withLockThenNotifyAll(ConditionVariable &condition,
293-
CriticalSection criticalSection)
294-
-> decltype(criticalSection()) {
294+
CriticalSection &&criticalSection)
295+
-> decltype(std::forward<CriticalSection>(criticalSection)()) {
295296
return withLock([&] {
296297
ScopedNotifyAll guard(condition);
297-
return criticalSection();
298+
return std::forward<CriticalSection>(criticalSection)();
298299
});
299300
}
300301

@@ -389,10 +390,10 @@ class Mutex {
389390
///
390391
/// Precondition: Mutex not held by this thread, undefined otherwise.
391392
template <typename CriticalSection>
392-
auto withLock(CriticalSection criticalSection)
393-
-> decltype(criticalSection()) {
393+
auto withLock(CriticalSection &&criticalSection)
394+
-> decltype(std::forward<CriticalSection>(criticalSection)()) {
394395
ScopedLock guard(*this);
395-
return criticalSection();
396+
return std::forward<CriticalSection>(criticalSection)();
396397
}
397398

398399
/// A stack based object that locks the supplied mutex on construction
@@ -613,10 +614,10 @@ class ReadWriteLock {
613614
///
614615
/// Precondition: ReadWriteLock not held by this thread, undefined otherwise.
615616
template <typename CriticalSection>
616-
auto withReadLock(CriticalSection criticalSection)
617-
-> decltype(criticalSection()) {
617+
auto withReadLock(CriticalSection &&criticalSection)
618+
-> decltype(std::forward<CriticalSection>(criticalSection)()) {
618619
ScopedReadLock guard(*this);
619-
return criticalSection();
620+
return std::forward<CriticalSection>(criticalSection)();
620621
}
621622

622623
/// Acquires write lock before calling the supplied critical section and
@@ -633,10 +634,10 @@ class ReadWriteLock {
633634
///
634635
/// Precondition: ReadWriteLock not held by this thread, undefined otherwise.
635636
template <typename CriticalSection>
636-
auto withWriteLock(CriticalSection criticalSection)
637-
-> decltype(criticalSection()) {
637+
auto withWriteLock(CriticalSection &&criticalSection)
638+
-> decltype(std::forward<CriticalSection>(criticalSection)()) {
638639
ScopedWriteLock guard(*this);
639-
return criticalSection();
640+
return std::forward<CriticalSection>(criticalSection)();
640641
}
641642

642643
private:
@@ -683,7 +684,7 @@ class StaticConditionVariable {
683684
#if SWIFT_MUTEX_SUPPORTS_CONSTEXPR
684685
constexpr
685686
#endif
686-
StaticMutex()
687+
StaticMutex()
687688
: Handle(MutexPlatformHelper::conditionStaticInit()) {
688689
}
689690

@@ -706,16 +707,16 @@ class StaticConditionVariable {
706707

707708
/// See Mutex::lock
708709
template <typename CriticalSection>
709-
auto withLock(CriticalSection criticalSection)
710-
-> decltype(criticalSection()) {
710+
auto withLock(CriticalSection &&criticalSection)
711+
-> decltype(std::forward<CriticalSection>(criticalSection)()) {
711712
ScopedLock guard(*this);
712-
return criticalSection();
713+
return std::forward<CriticalSection>(criticalSection)();
713714
}
714715

715716
/// See Mutex::withLockOrWait
716717
template <typename CriticalSection>
717718
void withLockOrWait(StaticConditionVariable &condition,
718-
CriticalSection criticalSection) {
719+
CriticalSection &&criticalSection) {
719720
withLock([&] {
720721
while (!criticalSection()) {
721722
wait(condition);
@@ -726,22 +727,22 @@ class StaticConditionVariable {
726727
/// See Mutex::withLockThenNotifyOne
727728
template <typename CriticalSection>
728729
auto withLockThenNotifyOne(StaticConditionVariable &condition,
729-
CriticalSection criticalSection)
730-
-> decltype(criticalSection()) {
730+
CriticalSection &&criticalSection)
731+
-> decltype(std::forward<CriticalSection>(criticalSection)()) {
731732
return withLock([&] {
732733
StaticConditionVariable::ScopedNotifyOne guard(condition);
733-
return criticalSection();
734+
return std::forward<CriticalSection>(criticalSection)();
734735
});
735736
}
736737

737738
/// See Mutex::withLockThenNotifyAll
738739
template <typename CriticalSection>
739740
auto withLockThenNotifyAll(StaticConditionVariable &condition,
740-
CriticalSection criticalSection)
741-
-> decltype(criticalSection()) {
741+
CriticalSection &&criticalSection)
742+
-> decltype(std::forward<CriticalSection>(criticalSection)()) {
742743
return withLock([&] {
743744
StaticConditionVariable::ScopedNotifyAll guard(condition);
744-
return criticalSection();
745+
return std::forward<CriticalSection>(criticalSection)();
745746
});
746747
}
747748

@@ -779,7 +780,7 @@ class StaticMutex {
779780
#if SWIFT_MUTEX_SUPPORTS_CONSTEXPR
780781
constexpr
781782
#endif
782-
StaticMutex()
783+
StaticMutex()
783784
: Handle(MutexPlatformHelper::staticInit()) {
784785
}
785786

@@ -794,10 +795,10 @@ class StaticMutex {
794795

795796
/// See Mutex::lock
796797
template <typename CriticalSection>
797-
auto withLock(CriticalSection criticalSection)
798-
-> decltype(criticalSection()) {
798+
auto withLock(CriticalSection &&criticalSection)
799+
-> decltype(std::forward<CriticalSection>(criticalSection)()) {
799800
ScopedLock guard(*this);
800-
return criticalSection();
801+
return std::forward<CriticalSection>(criticalSection)();
801802
}
802803

803804
/// A stack based object that locks the supplied mutex on construction
@@ -830,7 +831,7 @@ class StaticReadWriteLock {
830831
#if SWIFT_READWRITELOCK_SUPPORTS_CONSTEXPR
831832
constexpr
832833
#endif
833-
StaticReadWriteLock()
834+
StaticReadWriteLock()
834835
: Handle(ReadWriteLockPlatformHelper::staticInit()) {
835836
}
836837

@@ -858,18 +859,18 @@ class StaticReadWriteLock {
858859

859860
/// See ReadWriteLock::withReadLock
860861
template <typename CriticalSection>
861-
auto withReadLock(CriticalSection criticalSection)
862-
-> decltype(criticalSection()) {
862+
auto withReadLock(CriticalSection &&criticalSection)
863+
-> decltype(std::forward<CriticalSection>(criticalSection)()) {
863864
StaticScopedReadLock guard(*this);
864-
return criticalSection();
865+
return std::forward<CriticalSection>(criticalSection)();
865866
}
866867

867868
/// See ReadWriteLock::withWriteLock
868869
template <typename CriticalSection>
869-
auto withWriteLock(CriticalSection criticalSection)
870-
-> decltype(criticalSection()) {
870+
auto withWriteLock(CriticalSection &&criticalSection)
871+
-> decltype(std::forward<CriticalSection>(criticalSection)()) {
871872
StaticScopedWriteLock guard(*this);
872-
return criticalSection();
873+
return std::forward<CriticalSection>(criticalSection)();
873874
}
874875

875876
private:
@@ -895,7 +896,7 @@ class StaticUnsafeMutex {
895896
#if SWIFT_MUTEX_SUPPORTS_CONSTEXPR
896897
constexpr
897898
#endif
898-
StaticUnsafeMutex()
899+
StaticUnsafeMutex()
899900
: Handle(MutexPlatformHelper::staticInit()) {
900901
}
901902

@@ -920,6 +921,16 @@ class StaticUnsafeMutex {
920921
/// - Ignores errors that may happen, undefined when an error happens.
921922
void unlock() { MutexPlatformHelper::unsafeUnlock(Handle); }
922923

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+
923934
private:
924935
MutexHandle Handle;
925936
};
@@ -943,6 +954,12 @@ class IndirectMutex {
943954

944955
bool try_lock() { return Ptr->try_lock(); }
945956

957+
template <typename CriticalSection>
958+
auto withLock(CriticalSection &&criticalSection)
959+
-> decltype(criticalSection()) {
960+
return Ptr->withLock(std::forward<CriticalSection>(criticalSection));
961+
}
962+
946963
/// A stack based object that locks the supplied mutex on construction
947964
/// and unlocks it on destruction.
948965
///

0 commit comments

Comments
 (0)