]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ipc/MemMap.h
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / ipc / MemMap.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
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
23namespace 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
33class MemMapSlot
34{
35public:
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
53class MemMapCleaner;
54
55/// A map of MemMapSlots indexed by their keys, with read/write slot locking.
56class MemMap
57{
58public:
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
76public:
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
8253d451
AR
93 void closeForWriting(const sfileno fileno);
94
95 /// stop writing the locked entry and start reading it
96 void switchWritingToReading(const sfileno fileno);
f28b12e7
CT
97
98 /// only works on locked entries; returns nil unless the slot is readable
99 const Slot *peekAtReader(const sfileno fileno) const;
100
101 /// mark the slot as waiting to be freed and, if possible, free it
102 void free(const sfileno fileno);
103
104 /// open slot for reading, increments read level
105 const Slot *openForReading(const cache_key *const key, sfileno &fileno);
106
107 /// open slot for reading, increments read level
108 const Slot *openForReadingAt(const sfileno fileno);
109
110 /// close slot after reading, decrements read level
111 void closeForReading(const sfileno fileno);
112
113 bool full() const; ///< there are no empty slots left
114 bool valid(const int n) const; ///< whether n is a valid slot coordinate
115 int entryCount() const; ///< number of used slots
116 int entryLimit() const; ///< maximum number of slots that can be used
117
118 /// adds approximate current stats to the supplied ones
119 void updateStats(ReadWriteLockStats &stats) const;
120
121 /// The cleaner MemMapCleaner::noteFreeMapSlot method called when a
122 /// readable entry is freed.
123 MemMapCleaner *cleaner;
124
125protected:
126 static Owner *Init(const char *const path, const int limit, const size_t extrasSize);
127
128 const SBuf path; ///< cache_dir path, used for logging
129 Mem::Pointer<Shared> shared;
f28b12e7
CT
130
131private:
132 int slotIndexByKey(const cache_key *const key) const;
133 Slot &slotByKey(const cache_key *const key);
134
135 Slot *openForReading(Slot &s);
136 void abortWriting(const sfileno fileno);
137 void freeIfNeeded(Slot &s);
138 void freeLocked(Slot &s, bool keepLocked);
139};
140
141/// API for adjusting external state when dirty map slot is being freed
142class MemMapCleaner
143{
144public:
145 virtual ~MemMapCleaner() {}
146
147 /// adjust slot-linked state before a locked Readable slot is erased
148 virtual void noteFreeMapSlot(const sfileno slotId) = 0;
149};
150
151} // namespace Ipc
152
153#endif /* SQUID_IPC_STORE_MAP_H */
f53969cc 154