]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
5b74111a | 2 | * Copyright (C) 1996-2018 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> |
44c95fcf AR |
13 | |
14 | class StoreEntry; | |
15 | ||
9199139f AR |
16 | namespace Ipc |
17 | { | |
44c95fcf AR |
18 | |
19 | class ReadWriteLockStats; | |
20 | ||
21 | /// an atomic readers-writer or shared-exclusive lock suitable for maps/tables | |
ce49546e AR |
22 | /// Also supports reading-while-appending mode when readers and writer are |
23 | /// allowed to access the same locked object because the writer promisses | |
24 | /// to only append new data and all size-related object properties are atomic. | |
9199139f AR |
25 | class ReadWriteLock |
26 | { | |
44c95fcf | 27 | public: |
36a704f0 FC |
28 | ReadWriteLock() : readers(0), writing(false), appending(false), readLevel(0), writeLevel(0) |
29 | {} | |
44c95fcf AR |
30 | |
31 | bool lockShared(); ///< lock for reading or return false | |
32 | bool lockExclusive(); ///< lock for modification or return false | |
abf396ec | 33 | bool lockHeaders(); ///< lock for [readable] metadata update or return false |
44c95fcf AR |
34 | void unlockShared(); ///< undo successful sharedLock() |
35 | void unlockExclusive(); ///< undo successful exclusiveLock() | |
abf396ec | 36 | void unlockHeaders(); ///< undo successful lockHeaders() |
44c95fcf AR |
37 | void switchExclusiveToShared(); ///< stop writing, start reading |
38 | ||
ce49546e AR |
39 | void startAppending(); ///< writer keeps its lock but also allows reading |
40 | ||
44c95fcf AR |
41 | /// adds approximate current stats to the supplied ones |
42 | void updateStats(ReadWriteLockStats &stats) const; | |
43 | ||
44 | public: | |
77c9f409 AJ |
45 | mutable std::atomic<uint32_t> readers; ///< number of reading users |
46 | std::atomic<bool> writing; ///< there is a writing user (there can be at most 1) | |
abf396ec AR |
47 | std::atomic<bool> appending; ///< the writer has promised to only append |
48 | std::atomic_flag updating; ///< a reader is updating metadata/headers | |
92e29797 AR |
49 | |
50 | private: | |
77c9f409 AJ |
51 | mutable std::atomic<uint32_t> readLevel; ///< number of users reading (or trying to) |
52 | std::atomic<uint32_t> writeLevel; ///< number of users writing (or trying to write) | |
44c95fcf AR |
53 | }; |
54 | ||
44c95fcf | 55 | /// approximate stats of a set of ReadWriteLocks |
9199139f AR |
56 | class ReadWriteLockStats |
57 | { | |
44c95fcf AR |
58 | public: |
59 | ReadWriteLockStats(); | |
60 | ||
61 | void dump(StoreEntry &e) const; | |
62 | ||
63 | int count; ///< the total number of locks | |
64 | int readable; ///< number of locks locked for reading | |
65 | int writeable; ///< number of locks locked for writing | |
66 | int idle; ///< number of unlocked locks | |
67 | int readers; ///< sum of lock.readers | |
68 | int writers; ///< sum of lock.writers | |
ce49546e | 69 | int appenders; ///< number of appending writers |
44c95fcf AR |
70 | }; |
71 | ||
abf396ec AR |
72 | /// Same as assert(flag is set): The process assert()s if flag is not set. |
73 | /// Side effect: The unset flag becomes set just before we assert(). | |
74 | /// Needed because atomic_flag cannot be compared with a boolean. | |
75 | void AssertFlagIsSet(std::atomic_flag &flag); | |
76 | ||
44c95fcf AR |
77 | } // namespace Ipc |
78 | ||
79 | #endif /* SQUID_IPC_READ_WRITE_LOCK_H */ | |
f53969cc | 80 |