source: vendor/google/auth/src/Cache/SysVCacheItemPool.php

Last change on this file was e3d4e0a, checked in by Vlado 222039 <vlado.popovski@…>, 7 days ago

Upload project files

  • Property mode set to 100644
File size: 6.2 KB
Line 
1<?php
2/**
3 * Copyright 2018 Google Inc. All Rights Reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17namespace Google\Auth\Cache;
18
19use Psr\Cache\CacheItemInterface;
20use Psr\Cache\CacheItemPoolInterface;
21
22/**
23 * SystemV shared memory based CacheItemPool implementation.
24 *
25 * This CacheItemPool implementation can be used among multiple processes, but
26 * it doesn't provide any locking mechanism. If multiple processes write to
27 * this ItemPool, you have to avoid race condition manually in your code.
28 */
29class SysVCacheItemPool implements CacheItemPoolInterface
30{
31 const VAR_KEY = 1;
32
33 const DEFAULT_PROJ = 'A';
34
35 const DEFAULT_MEMSIZE = 10000;
36
37 const DEFAULT_PERM = 0600;
38
39 /**
40 * @var int
41 */
42 private $sysvKey;
43
44 /**
45 * @var CacheItemInterface[]
46 */
47 private $items;
48
49 /**
50 * @var CacheItemInterface[]
51 */
52 private $deferredItems;
53
54 /**
55 * @var array<mixed>
56 */
57 private $options;
58
59 /**
60 * @var bool
61 */
62 private $hasLoadedItems = false;
63
64 /**
65 * Create a SystemV shared memory based CacheItemPool.
66 *
67 * @param array<mixed> $options {
68 * [optional] Configuration options.
69 *
70 * @type int $variableKey The variable key for getting the data from the shared memory. **Defaults to** 1.
71 * @type string $proj The project identifier for ftok. This needs to be a one character string.
72 * **Defaults to** 'A'.
73 * @type int $memsize The memory size in bytes for shm_attach. **Defaults to** 10000.
74 * @type int $perm The permission for shm_attach. **Defaults to** 0600.
75 * }
76 */
77 public function __construct($options = [])
78 {
79 if (! extension_loaded('sysvshm')) {
80 throw new \RuntimeException(
81 'sysvshm extension is required to use this ItemPool'
82 );
83 }
84 $this->options = $options + [
85 'variableKey' => self::VAR_KEY,
86 'proj' => self::DEFAULT_PROJ,
87 'memsize' => self::DEFAULT_MEMSIZE,
88 'perm' => self::DEFAULT_PERM
89 ];
90 $this->items = [];
91 $this->deferredItems = [];
92 $this->sysvKey = ftok(__FILE__, $this->options['proj']);
93 }
94
95 /**
96 * @param mixed $key
97 * @return CacheItemInterface
98 */
99 public function getItem($key): CacheItemInterface
100 {
101 $this->loadItems();
102 return current($this->getItems([$key])); // @phpstan-ignore-line
103 }
104
105 /**
106 * @param array<mixed> $keys
107 * @return iterable<CacheItemInterface>
108 */
109 public function getItems(array $keys = []): iterable
110 {
111 $this->loadItems();
112 $items = [];
113 foreach ($keys as $key) {
114 $items[$key] = $this->hasItem($key) ?
115 clone $this->items[$key] :
116 new TypedItem($key);
117 }
118 return $items;
119 }
120
121 /**
122 * {@inheritdoc}
123 */
124 public function hasItem($key): bool
125 {
126 $this->loadItems();
127 return isset($this->items[$key]) && $this->items[$key]->isHit();
128 }
129
130 /**
131 * {@inheritdoc}
132 */
133 public function clear(): bool
134 {
135 $this->items = [];
136 $this->deferredItems = [];
137 return $this->saveCurrentItems();
138 }
139
140 /**
141 * {@inheritdoc}
142 */
143 public function deleteItem($key): bool
144 {
145 return $this->deleteItems([$key]);
146 }
147
148 /**
149 * {@inheritdoc}
150 */
151 public function deleteItems(array $keys): bool
152 {
153 if (!$this->hasLoadedItems) {
154 $this->loadItems();
155 }
156
157 foreach ($keys as $key) {
158 unset($this->items[$key]);
159 }
160 return $this->saveCurrentItems();
161 }
162
163 /**
164 * {@inheritdoc}
165 */
166 public function save(CacheItemInterface $item): bool
167 {
168 if (!$this->hasLoadedItems) {
169 $this->loadItems();
170 }
171
172 $this->items[$item->getKey()] = $item;
173 return $this->saveCurrentItems();
174 }
175
176 /**
177 * {@inheritdoc}
178 */
179 public function saveDeferred(CacheItemInterface $item): bool
180 {
181 $this->deferredItems[$item->getKey()] = $item;
182 return true;
183 }
184
185 /**
186 * {@inheritdoc}
187 */
188 public function commit(): bool
189 {
190 foreach ($this->deferredItems as $item) {
191 if ($this->save($item) === false) {
192 return false;
193 }
194 }
195 $this->deferredItems = [];
196 return true;
197 }
198
199 /**
200 * Save the current items.
201 *
202 * @return bool true when success, false upon failure
203 */
204 private function saveCurrentItems()
205 {
206 $shmid = shm_attach(
207 $this->sysvKey,
208 $this->options['memsize'],
209 $this->options['perm']
210 );
211 if ($shmid !== false) {
212 $ret = shm_put_var(
213 $shmid,
214 $this->options['variableKey'],
215 $this->items
216 );
217 shm_detach($shmid);
218 return $ret;
219 }
220 return false;
221 }
222
223 /**
224 * Load the items from the shared memory.
225 *
226 * @return bool true when success, false upon failure
227 */
228 private function loadItems()
229 {
230 $shmid = shm_attach(
231 $this->sysvKey,
232 $this->options['memsize'],
233 $this->options['perm']
234 );
235 if ($shmid !== false) {
236 $data = @shm_get_var($shmid, $this->options['variableKey']);
237 if (!empty($data)) {
238 $this->items = $data;
239 } else {
240 $this->items = [];
241 }
242 shm_detach($shmid);
243 $this->hasLoadedItems = true;
244 return true;
245 }
246 return false;
247 }
248}
Note: See TracBrowser for help on using the repository browser.