]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ipc/ReadWriteLock.h
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / ipc / ReadWriteLock.h
CommitLineData
bbc27441 1/*
f70aedc4 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
bbc27441
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
44c95fcf
AR
9#ifndef SQUID_IPC_READ_WRITE_LOCK_H
10#define SQUID_IPC_READ_WRITE_LOCK_H
11
77c9f409 12#include <atomic>
b2aca62a 13#include <iosfwd>
44c95fcf
AR
14
15class StoreEntry;
16
9199139f
AR
17namespace Ipc
18{
44c95fcf
AR
19
20class ReadWriteLockStats;
21
22/// an atomic readers-writer or shared-exclusive lock suitable for maps/tables
ce49546e
AR
23/// Also supports reading-while-appending mode when readers and writer are
24/// allowed to access the same locked object because the writer promisses
25/// to only append new data and all size-related object properties are atomic.
9199139f
AR
26class ReadWriteLock
27{
44c95fcf 28public:
36a704f0
FC
29 ReadWriteLock() : readers(0), writing(false), appending(false), readLevel(0), writeLevel(0)
30 {}
44c95fcf
AR
31
32 bool lockShared(); ///< lock for reading or return false
33 bool lockExclusive(); ///< lock for modification or return false
abf396ec 34 bool lockHeaders(); ///< lock for [readable] metadata update or return false
44c95fcf
AR
35 void unlockShared(); ///< undo successful sharedLock()
36 void unlockExclusive(); ///< undo successful exclusiveLock()
abf396ec 37 void unlockHeaders(); ///< undo successful lockHeaders()
44c95fcf 38 void switchExclusiveToShared(); ///< stop writing, start reading
d1d3b4dc
EB
39 /// same as unlockShared() but also attempts to get a writer lock beforehand
40 /// \returns whether the writer lock was acquired
41 bool unlockSharedAndSwitchToExclusive();
44c95fcf 42
ce49546e
AR
43 void startAppending(); ///< writer keeps its lock but also allows reading
44
44c95fcf
AR
45 /// adds approximate current stats to the supplied ones
46 void updateStats(ReadWriteLockStats &stats) const;
47
48public:
77c9f409
AJ
49 mutable std::atomic<uint32_t> readers; ///< number of reading users
50 std::atomic<bool> writing; ///< there is a writing user (there can be at most 1)
abf396ec
AR
51 std::atomic<bool> appending; ///< the writer has promised to only append
52 std::atomic_flag updating; ///< a reader is updating metadata/headers
92e29797
AR
53
54private:
77c9f409
AJ
55 mutable std::atomic<uint32_t> readLevel; ///< number of users reading (or trying to)
56 std::atomic<uint32_t> writeLevel; ///< number of users writing (or trying to write)
44c95fcf
AR
57};
58
b2aca62a
EB
59/// dumps approximate lock state (for debugging)
60std::ostream &operator <<(std::ostream &os, const Ipc::ReadWriteLock &);
61
44c95fcf 62/// approximate stats of a set of ReadWriteLocks
9199139f
AR
63class ReadWriteLockStats
64{
44c95fcf
AR
65public:
66 ReadWriteLockStats();
67
68 void dump(StoreEntry &e) const;
69
70 int count; ///< the total number of locks
71 int readable; ///< number of locks locked for reading
72 int writeable; ///< number of locks locked for writing
73 int idle; ///< number of unlocked locks
74 int readers; ///< sum of lock.readers
75 int writers; ///< sum of lock.writers
ce49546e 76 int appenders; ///< number of appending writers
44c95fcf
AR
77};
78
abf396ec
AR
79/// Same as assert(flag is set): The process assert()s if flag is not set.
80/// Side effect: The unset flag becomes set just before we assert().
81/// Needed because atomic_flag cannot be compared with a boolean.
82void AssertFlagIsSet(std::atomic_flag &flag);
83
44c95fcf
AR
84} // namespace Ipc
85
86#endif /* SQUID_IPC_READ_WRITE_LOCK_H */
f53969cc 87