]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
4ac4a490 | 2 | * Copyright (C) 1996-2017 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 | ||
f28b12e7 CT |
9 | #ifndef SQUID_IPC_STORE_MAP_H |
10 | #define SQUID_IPC_STORE_MAP_H | |
11 | ||
12 | #include "Debug.h" | |
13 | #include "ipc/mem/FlexibleArray.h" | |
14 | #include "ipc/mem/Pointer.h" | |
15 | #include "ipc/ReadWriteLock.h" | |
65e41a45 | 16 | #include "sbuf/SBuf.h" |
2745fea5 | 17 | #include "store/forward.h" |
e1ba42a4 | 18 | #include "store_key_md5.h" |
f28b12e7 | 19 | #include "tools.h" |
f28b12e7 | 20 | |
75a24b04 AJ |
21 | #include <atomic> |
22 | ||
f28b12e7 CT |
23 | namespace Ipc |
24 | { | |
25 | ||
26 | // The MEMMAP_SLOT_KEY_SIZE and MEMMAP_SLOT_DATA_SIZE must be enough big | |
27 | // to hold cached keys and data. Currently MemMap used only to store SSL | |
28 | // shared session data which have keys of 32bytes and at most 10K data | |
29 | #define MEMMAP_SLOT_KEY_SIZE 32 | |
30 | #define MEMMAP_SLOT_DATA_SIZE 10*1024 | |
31 | ||
32 | /// a MemMap basic element, holding basic shareable memory block info | |
33 | class MemMapSlot | |
34 | { | |
35 | public: | |
36 | MemMapSlot(); | |
37 | size_t size() const {return sizeof(MemMapSlot);} | |
38 | size_t keySize() const {return sizeof(key);} | |
39 | bool sameKey(const cache_key *const aKey) const; | |
40 | void set(const unsigned char *aKey, const void *block, size_t blockSize, time_t expire = 0); | |
41 | bool empty() const; | |
42 | bool reading() const { return lock.readers; } | |
43 | bool writing() const { return lock.writing; } | |
44 | ||
75a24b04 | 45 | std::atomic<uint8_t> waitingToBeFreed; ///< may be accessed w/o a lock |
f28b12e7 CT |
46 | mutable ReadWriteLock lock; ///< protects slot data below |
47 | unsigned char key[MEMMAP_SLOT_KEY_SIZE]; ///< The entry key | |
48 | unsigned char p[MEMMAP_SLOT_DATA_SIZE]; ///< The memory block; | |
49 | size_t pSize; | |
50 | time_t expire; | |
51 | }; | |
52 | ||
53 | class MemMapCleaner; | |
54 | ||
55 | /// A map of MemMapSlots indexed by their keys, with read/write slot locking. | |
56 | class MemMap | |
57 | { | |
58 | public: | |
59 | typedef MemMapSlot Slot; | |
60 | ||
61 | /// data shared across maps in different processes | |
62 | class Shared | |
63 | { | |
64 | public: | |
65 | Shared(const int aLimit, const size_t anExtrasSize); | |
66 | size_t sharedMemorySize() const; | |
67 | static size_t SharedMemorySize(const int limit, const size_t anExtrasSize); | |
68 | ~Shared(); | |
69 | ||
70 | const int limit; ///< maximum number of map slots | |
71 | const size_t extrasSize; ///< size of slot extra data | |
75a24b04 | 72 | std::atomic<int> count; ///< current number of map slots |
f28b12e7 CT |
73 | Ipc::Mem::FlexibleArray<Slot> slots; ///< storage |
74 | }; | |
75 | ||
76 | public: | |
77 | typedef Mem::Owner<Shared> Owner; | |
78 | ||
79 | /// initialize shared memory | |
80 | static Owner *Init(const char *const path, const int limit); | |
81 | ||
82 | MemMap(const char *const aPath); | |
83 | ||
84 | /// finds, locks and return a slot for an empty key position, | |
85 | /// erasing the old entry (if any) | |
86 | Slot *openForWriting(const cache_key *const key, sfileno &fileno); | |
87 | ||
88 | /// locks and returns a slot for the empty fileno position; if | |
89 | /// overwriteExisting is false and the position is not empty, returns nil | |
90 | Slot *openForWritingAt(sfileno fileno, bool overwriteExisting = true); | |
91 | ||
92 | /// successfully finish writing the entry | |
93 | void closeForWriting(const sfileno fileno, bool lockForReading = false); | |
94 | ||
95 | /// only works on locked entries; returns nil unless the slot is readable | |
96 | const Slot *peekAtReader(const sfileno fileno) const; | |
97 | ||
98 | /// mark the slot as waiting to be freed and, if possible, free it | |
99 | void free(const sfileno fileno); | |
100 | ||
101 | /// open slot for reading, increments read level | |
102 | const Slot *openForReading(const cache_key *const key, sfileno &fileno); | |
103 | ||
104 | /// open slot for reading, increments read level | |
105 | const Slot *openForReadingAt(const sfileno fileno); | |
106 | ||
107 | /// close slot after reading, decrements read level | |
108 | void closeForReading(const sfileno fileno); | |
109 | ||
110 | bool full() const; ///< there are no empty slots left | |
111 | bool valid(const int n) const; ///< whether n is a valid slot coordinate | |
112 | int entryCount() const; ///< number of used slots | |
113 | int entryLimit() const; ///< maximum number of slots that can be used | |
114 | ||
115 | /// adds approximate current stats to the supplied ones | |
116 | void updateStats(ReadWriteLockStats &stats) const; | |
117 | ||
118 | /// The cleaner MemMapCleaner::noteFreeMapSlot method called when a | |
119 | /// readable entry is freed. | |
120 | MemMapCleaner *cleaner; | |
121 | ||
122 | protected: | |
123 | static Owner *Init(const char *const path, const int limit, const size_t extrasSize); | |
124 | ||
125 | const SBuf path; ///< cache_dir path, used for logging | |
126 | Mem::Pointer<Shared> shared; | |
f28b12e7 CT |
127 | |
128 | private: | |
129 | int slotIndexByKey(const cache_key *const key) const; | |
130 | Slot &slotByKey(const cache_key *const key); | |
131 | ||
132 | Slot *openForReading(Slot &s); | |
133 | void abortWriting(const sfileno fileno); | |
134 | void freeIfNeeded(Slot &s); | |
135 | void freeLocked(Slot &s, bool keepLocked); | |
136 | }; | |
137 | ||
138 | /// API for adjusting external state when dirty map slot is being freed | |
139 | class MemMapCleaner | |
140 | { | |
141 | public: | |
142 | virtual ~MemMapCleaner() {} | |
143 | ||
144 | /// adjust slot-linked state before a locked Readable slot is erased | |
145 | virtual void noteFreeMapSlot(const sfileno slotId) = 0; | |
146 | }; | |
147 | ||
148 | } // namespace Ipc | |
149 | ||
150 | #endif /* SQUID_IPC_STORE_MAP_H */ | |
f53969cc | 151 |