]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/mem/PagePool.cc
Use size_t instead of unsigned int for the page size to prevent int overflows
[thirdparty/squid.git] / src / ipc / mem / PagePool.cc
1 /*
2 * $Id$
3 *
4 * DEBUG: section 54 Interprocess Communication
5 *
6 */
7
8 #include "config.h"
9 #include "base/TextException.h"
10 #include "ipc/mem/Page.h"
11 #include "ipc/mem/PagePool.h"
12
13
14 static String
15 PageIndexId(String id)
16 {
17 id.append("-index");
18 return id;
19 }
20
21
22 // Ipc::Mem::PagePool
23
24 Ipc::Mem::PagePool::PagePool(const String &id, const unsigned int capacity, const size_t pageSize):
25 pageIndex(PageIndexId(id), capacity),
26 shm(id.termedBuf())
27 {
28 shm.create(sizeof(Shared) + pageSize*capacity);
29 assert(shm.mem());
30 shared = new (shm.mem()) Shared(capacity, pageSize);
31 }
32
33 Ipc::Mem::PagePool::PagePool(const String &id):
34 pageIndex(PageIndexId(id)), shm(id.termedBuf())
35 {
36 shm.open();
37 shared = reinterpret_cast<Shared *>(shm.mem());
38 assert(shared);
39 }
40
41 bool
42 Ipc::Mem::PagePool::get(PageId &page)
43 {
44 if (pageIndex.pop(page.number)) {
45 page.pool = shared->theId;
46 return true;
47 }
48 return false;
49 }
50
51 void
52 Ipc::Mem::PagePool::put(PageId &page)
53 {
54 Must(pageIdIsValid(page));
55 pageIndex.push(page.number);
56 page = PageId();
57 }
58
59 void *
60 Ipc::Mem::PagePool::pagePointer(const PageId &page)
61 {
62 Must(pageIdIsValid(page));
63 return shared->theBuf + shared->thePageSize * (page.number - 1);
64 }
65
66 bool
67 Ipc::Mem::PagePool::pageIdIsValid(const PageId &page) const
68 {
69 return page.pool == shared->theId &&
70 0 < page.number && page.number <= shared->theCapacity;
71 }
72
73
74 // Ipc::Mem::PagePool::Shared
75
76 static unsigned int LastPagePoolId = 0;
77
78 Ipc::Mem::PagePool::Shared::Shared(const unsigned int aCapacity, size_t aPageSize):
79 theId(++LastPagePoolId), theCapacity(aCapacity), thePageSize(aPageSize)
80 {
81 if (LastPagePoolId + 1 == 0)
82 ++LastPagePoolId; // skip zero pool id
83 }