xref: /aosp_15_r20/external/libwebsockets/lib/misc/cache-ttl/lws-cache-ttl.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2010 - 2021 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker  *
16*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker  */
24*1c60b9acSAndroid Build Coastguard Worker 
25*1c60b9acSAndroid Build Coastguard Worker #include <private-lib-core.h>
26*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-misc-cache-ttl.h"
27*1c60b9acSAndroid Build Coastguard Worker 
28*1c60b9acSAndroid Build Coastguard Worker #include <assert.h>
29*1c60b9acSAndroid Build Coastguard Worker 
30*1c60b9acSAndroid Build Coastguard Worker #if defined(write)
31*1c60b9acSAndroid Build Coastguard Worker #undef write
32*1c60b9acSAndroid Build Coastguard Worker #endif
33*1c60b9acSAndroid Build Coastguard Worker 
34*1c60b9acSAndroid Build Coastguard Worker void
lws_cache_clear_matches(lws_dll2_owner_t * results_owner)35*1c60b9acSAndroid Build Coastguard Worker lws_cache_clear_matches(lws_dll2_owner_t *results_owner)
36*1c60b9acSAndroid Build Coastguard Worker {
37*1c60b9acSAndroid Build Coastguard Worker 	lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, results_owner->head) {
38*1c60b9acSAndroid Build Coastguard Worker 		lws_cache_match_t *item = lws_container_of(d, lws_cache_match_t,
39*1c60b9acSAndroid Build Coastguard Worker 							   list);
40*1c60b9acSAndroid Build Coastguard Worker 		lws_dll2_remove(d);
41*1c60b9acSAndroid Build Coastguard Worker 		lws_free(item);
42*1c60b9acSAndroid Build Coastguard Worker 	} lws_end_foreach_dll_safe(d, d1);
43*1c60b9acSAndroid Build Coastguard Worker }
44*1c60b9acSAndroid Build Coastguard Worker 
45*1c60b9acSAndroid Build Coastguard Worker void
lws_cache_schedule(struct lws_cache_ttl_lru * cache,sul_cb_t cb,lws_usec_t e)46*1c60b9acSAndroid Build Coastguard Worker lws_cache_schedule(struct lws_cache_ttl_lru *cache, sul_cb_t cb, lws_usec_t e)
47*1c60b9acSAndroid Build Coastguard Worker {
48*1c60b9acSAndroid Build Coastguard Worker 	lwsl_cache("%s: %s schedule %llu\n", __func__, cache->info.name,
49*1c60b9acSAndroid Build Coastguard Worker 			(unsigned long long)e);
50*1c60b9acSAndroid Build Coastguard Worker 
51*1c60b9acSAndroid Build Coastguard Worker 	lws_sul_schedule(cache->info.cx, cache->info.tsi, &cache->sul, cb,
52*1c60b9acSAndroid Build Coastguard Worker 			 e - lws_now_usecs());
53*1c60b9acSAndroid Build Coastguard Worker }
54*1c60b9acSAndroid Build Coastguard Worker 
55*1c60b9acSAndroid Build Coastguard Worker int
lws_cache_write_through(struct lws_cache_ttl_lru * cache,const char * specific_key,const uint8_t * source,size_t size,lws_usec_t expiry,void ** ppay)56*1c60b9acSAndroid Build Coastguard Worker lws_cache_write_through(struct lws_cache_ttl_lru *cache,
57*1c60b9acSAndroid Build Coastguard Worker 			const char *specific_key, const uint8_t *source,
58*1c60b9acSAndroid Build Coastguard Worker 			size_t size, lws_usec_t expiry, void **ppay)
59*1c60b9acSAndroid Build Coastguard Worker {
60*1c60b9acSAndroid Build Coastguard Worker 	struct lws_cache_ttl_lru *levels[LWS_CACHE_MAX_LEVELS], *c = cache;
61*1c60b9acSAndroid Build Coastguard Worker 	int n = 0, r = 0;
62*1c60b9acSAndroid Build Coastguard Worker 
63*1c60b9acSAndroid Build Coastguard Worker 	lws_cache_item_remove(cache, specific_key);
64*1c60b9acSAndroid Build Coastguard Worker 
65*1c60b9acSAndroid Build Coastguard Worker 	/* starting from L1 */
66*1c60b9acSAndroid Build Coastguard Worker 
67*1c60b9acSAndroid Build Coastguard Worker 	do {
68*1c60b9acSAndroid Build Coastguard Worker 		levels[n++] = c;
69*1c60b9acSAndroid Build Coastguard Worker 		c = c->info.parent;
70*1c60b9acSAndroid Build Coastguard Worker 	} while (c && n < (int)LWS_ARRAY_SIZE(levels));
71*1c60b9acSAndroid Build Coastguard Worker 
72*1c60b9acSAndroid Build Coastguard Worker 	/* starting from outermost cache level */
73*1c60b9acSAndroid Build Coastguard Worker 
74*1c60b9acSAndroid Build Coastguard Worker 	while (n) {
75*1c60b9acSAndroid Build Coastguard Worker 		n--;
76*1c60b9acSAndroid Build Coastguard Worker 		r = levels[n]->info.ops->write(levels[n], specific_key,
77*1c60b9acSAndroid Build Coastguard Worker 						source, size, expiry, ppay);
78*1c60b9acSAndroid Build Coastguard Worker 	}
79*1c60b9acSAndroid Build Coastguard Worker 
80*1c60b9acSAndroid Build Coastguard Worker 	return r;
81*1c60b9acSAndroid Build Coastguard Worker }
82*1c60b9acSAndroid Build Coastguard Worker 
83*1c60b9acSAndroid Build Coastguard Worker /*
84*1c60b9acSAndroid Build Coastguard Worker  * We want to make a list of unique keys that exist at any cache level
85*1c60b9acSAndroid Build Coastguard Worker  * matching a wildcard search key.
86*1c60b9acSAndroid Build Coastguard Worker  *
87*1c60b9acSAndroid Build Coastguard Worker  * If L1 has a cached version though, we will just use that.
88*1c60b9acSAndroid Build Coastguard Worker  */
89*1c60b9acSAndroid Build Coastguard Worker 
90*1c60b9acSAndroid Build Coastguard Worker int
lws_cache_lookup(struct lws_cache_ttl_lru * cache,const char * wildcard_key,const void ** pdata,size_t * psize)91*1c60b9acSAndroid Build Coastguard Worker lws_cache_lookup(struct lws_cache_ttl_lru *cache, const char *wildcard_key,
92*1c60b9acSAndroid Build Coastguard Worker 		 const void **pdata, size_t *psize)
93*1c60b9acSAndroid Build Coastguard Worker {
94*1c60b9acSAndroid Build Coastguard Worker 	struct lws_cache_ttl_lru *l1 = cache;
95*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_owner_t results_owner;
96*1c60b9acSAndroid Build Coastguard Worker 	lws_usec_t expiry = 0;
97*1c60b9acSAndroid Build Coastguard Worker 	char meta_key[128];
98*1c60b9acSAndroid Build Coastguard Worker 	uint8_t *p, *temp;
99*1c60b9acSAndroid Build Coastguard Worker 	size_t sum = 0;
100*1c60b9acSAndroid Build Coastguard Worker 	int n;
101*1c60b9acSAndroid Build Coastguard Worker 
102*1c60b9acSAndroid Build Coastguard Worker 	memset(&results_owner, 0, sizeof(results_owner));
103*1c60b9acSAndroid Build Coastguard Worker 	meta_key[0] = META_ITEM_LEADING;
104*1c60b9acSAndroid Build Coastguard Worker 	lws_strncpy(&meta_key[1], wildcard_key, sizeof(meta_key) - 2);
105*1c60b9acSAndroid Build Coastguard Worker 
106*1c60b9acSAndroid Build Coastguard Worker 	/*
107*1c60b9acSAndroid Build Coastguard Worker 	 * If we have a cached result set in L1 already, return that
108*1c60b9acSAndroid Build Coastguard Worker 	 */
109*1c60b9acSAndroid Build Coastguard Worker 
110*1c60b9acSAndroid Build Coastguard Worker 	if (!l1->info.ops->get(l1, meta_key, pdata, psize))
111*1c60b9acSAndroid Build Coastguard Worker 		return 0;
112*1c60b9acSAndroid Build Coastguard Worker 
113*1c60b9acSAndroid Build Coastguard Worker 	/*
114*1c60b9acSAndroid Build Coastguard Worker 	 * No, we have to do the actual lookup work in the backing store layer
115*1c60b9acSAndroid Build Coastguard Worker 	 * to get results for this...
116*1c60b9acSAndroid Build Coastguard Worker 	 */
117*1c60b9acSAndroid Build Coastguard Worker 
118*1c60b9acSAndroid Build Coastguard Worker 	while (cache->info.parent)
119*1c60b9acSAndroid Build Coastguard Worker 		cache = cache->info.parent;
120*1c60b9acSAndroid Build Coastguard Worker 
121*1c60b9acSAndroid Build Coastguard Worker 	if (cache->info.ops->lookup(cache, wildcard_key, &results_owner)) {
122*1c60b9acSAndroid Build Coastguard Worker 		/* eg, OOM */
123*1c60b9acSAndroid Build Coastguard Worker 
124*1c60b9acSAndroid Build Coastguard Worker 		lwsl_cache("%s: bs lookup fail\n", __func__);
125*1c60b9acSAndroid Build Coastguard Worker 
126*1c60b9acSAndroid Build Coastguard Worker 		lws_cache_clear_matches(&results_owner);
127*1c60b9acSAndroid Build Coastguard Worker 		return 1;
128*1c60b9acSAndroid Build Coastguard Worker 	}
129*1c60b9acSAndroid Build Coastguard Worker 
130*1c60b9acSAndroid Build Coastguard Worker 	/*
131*1c60b9acSAndroid Build Coastguard Worker 	 * Scan the results, we want to know how big a payload it needs in
132*1c60b9acSAndroid Build Coastguard Worker 	 * the cache, and we want to know the earliest expiry of any of the
133*1c60b9acSAndroid Build Coastguard Worker 	 * component parts, so the meta cache entry for these results can be
134*1c60b9acSAndroid Build Coastguard Worker 	 * expired when any of the results would expire.
135*1c60b9acSAndroid Build Coastguard Worker 	 */
136*1c60b9acSAndroid Build Coastguard Worker 
137*1c60b9acSAndroid Build Coastguard Worker 	lws_start_foreach_dll(struct lws_dll2 *, d, results_owner.head) {
138*1c60b9acSAndroid Build Coastguard Worker 		lws_cache_match_t *m = lws_container_of(d, lws_cache_match_t,
139*1c60b9acSAndroid Build Coastguard Worker 							list);
140*1c60b9acSAndroid Build Coastguard Worker 		sum += 8; /* payload size, name length */
141*1c60b9acSAndroid Build Coastguard Worker 		sum += m->tag_size + 1;
142*1c60b9acSAndroid Build Coastguard Worker 
143*1c60b9acSAndroid Build Coastguard Worker 		if (m->expiry && (!expiry || expiry < m->expiry))
144*1c60b9acSAndroid Build Coastguard Worker 			expiry = m->expiry;
145*1c60b9acSAndroid Build Coastguard Worker 
146*1c60b9acSAndroid Build Coastguard Worker 	} lws_end_foreach_dll(d);
147*1c60b9acSAndroid Build Coastguard Worker 
148*1c60b9acSAndroid Build Coastguard Worker 	lwsl_cache("%s: results %d, size %d\n", __func__,
149*1c60b9acSAndroid Build Coastguard Worker 		    (int)results_owner.count, (int)sum);
150*1c60b9acSAndroid Build Coastguard Worker 
151*1c60b9acSAndroid Build Coastguard Worker 	temp = lws_malloc(sum, __func__);
152*1c60b9acSAndroid Build Coastguard Worker 	if (!temp) {
153*1c60b9acSAndroid Build Coastguard Worker 		lws_cache_clear_matches(&results_owner);
154*1c60b9acSAndroid Build Coastguard Worker 		return 1;
155*1c60b9acSAndroid Build Coastguard Worker 	}
156*1c60b9acSAndroid Build Coastguard Worker 
157*1c60b9acSAndroid Build Coastguard Worker 	/*
158*1c60b9acSAndroid Build Coastguard Worker 	 * Fill temp with the serialized results
159*1c60b9acSAndroid Build Coastguard Worker 	 */
160*1c60b9acSAndroid Build Coastguard Worker 
161*1c60b9acSAndroid Build Coastguard Worker 	p = temp;
162*1c60b9acSAndroid Build Coastguard Worker 	lws_start_foreach_dll(struct lws_dll2 *, d, results_owner.head) {
163*1c60b9acSAndroid Build Coastguard Worker 		lws_cache_match_t *m = lws_container_of(d, lws_cache_match_t,
164*1c60b9acSAndroid Build Coastguard Worker 							list);
165*1c60b9acSAndroid Build Coastguard Worker 
166*1c60b9acSAndroid Build Coastguard Worker 		/* we don't copy the payload in, but take note of its size */
167*1c60b9acSAndroid Build Coastguard Worker 		lws_ser_wu32be(p, (uint32_t)m->payload_size);
168*1c60b9acSAndroid Build Coastguard Worker 		p += 4;
169*1c60b9acSAndroid Build Coastguard Worker 		/* length of the tag name (there is an uncounted NUL after) */
170*1c60b9acSAndroid Build Coastguard Worker 		lws_ser_wu32be(p, (uint32_t)m->tag_size);
171*1c60b9acSAndroid Build Coastguard Worker 		p += 4;
172*1c60b9acSAndroid Build Coastguard Worker 
173*1c60b9acSAndroid Build Coastguard Worker 		/* then the tag name, plus the extra NUL */
174*1c60b9acSAndroid Build Coastguard Worker 		memcpy(p, &m[1], m->tag_size + 1);
175*1c60b9acSAndroid Build Coastguard Worker 		p += m->tag_size + 1;
176*1c60b9acSAndroid Build Coastguard Worker 
177*1c60b9acSAndroid Build Coastguard Worker 	} lws_end_foreach_dll(d);
178*1c60b9acSAndroid Build Coastguard Worker 
179*1c60b9acSAndroid Build Coastguard Worker 	lws_cache_clear_matches(&results_owner);
180*1c60b9acSAndroid Build Coastguard Worker 
181*1c60b9acSAndroid Build Coastguard Worker 	/*
182*1c60b9acSAndroid Build Coastguard Worker 	 * Create the right amount of space for an L1 record of these results,
183*1c60b9acSAndroid Build Coastguard Worker 	 * with its expiry set to the earliest of the results, and copy it in
184*1c60b9acSAndroid Build Coastguard Worker 	 * from temp
185*1c60b9acSAndroid Build Coastguard Worker 	 */
186*1c60b9acSAndroid Build Coastguard Worker 
187*1c60b9acSAndroid Build Coastguard Worker 	n = l1->info.ops->write(l1, meta_key, temp, sum, expiry, (void **)&p);
188*1c60b9acSAndroid Build Coastguard Worker 	/* done with temp */
189*1c60b9acSAndroid Build Coastguard Worker 	lws_free(temp);
190*1c60b9acSAndroid Build Coastguard Worker 
191*1c60b9acSAndroid Build Coastguard Worker 	if (n)
192*1c60b9acSAndroid Build Coastguard Worker 		return 1;
193*1c60b9acSAndroid Build Coastguard Worker 
194*1c60b9acSAndroid Build Coastguard Worker 	/* point to the results in L1 */
195*1c60b9acSAndroid Build Coastguard Worker 
196*1c60b9acSAndroid Build Coastguard Worker 	*pdata = p;
197*1c60b9acSAndroid Build Coastguard Worker 	*psize = sum;
198*1c60b9acSAndroid Build Coastguard Worker 
199*1c60b9acSAndroid Build Coastguard Worker 	return 0;
200*1c60b9acSAndroid Build Coastguard Worker }
201*1c60b9acSAndroid Build Coastguard Worker 
202*1c60b9acSAndroid Build Coastguard Worker int
lws_cache_item_get(struct lws_cache_ttl_lru * cache,const char * specific_key,const void ** pdata,size_t * psize)203*1c60b9acSAndroid Build Coastguard Worker lws_cache_item_get(struct lws_cache_ttl_lru *cache, const char *specific_key,
204*1c60b9acSAndroid Build Coastguard Worker 		   const void **pdata, size_t *psize)
205*1c60b9acSAndroid Build Coastguard Worker {
206*1c60b9acSAndroid Build Coastguard Worker 	while (cache) {
207*1c60b9acSAndroid Build Coastguard Worker 		if (!cache->info.ops->get(cache, specific_key, pdata, psize)) {
208*1c60b9acSAndroid Build Coastguard Worker 			lwsl_cache("%s: hit\n", __func__);
209*1c60b9acSAndroid Build Coastguard Worker 			return 0;
210*1c60b9acSAndroid Build Coastguard Worker 		}
211*1c60b9acSAndroid Build Coastguard Worker 
212*1c60b9acSAndroid Build Coastguard Worker 		cache = cache->info.parent;
213*1c60b9acSAndroid Build Coastguard Worker 	}
214*1c60b9acSAndroid Build Coastguard Worker 
215*1c60b9acSAndroid Build Coastguard Worker 	return 1;
216*1c60b9acSAndroid Build Coastguard Worker }
217*1c60b9acSAndroid Build Coastguard Worker 
218*1c60b9acSAndroid Build Coastguard Worker int
lws_cache_expunge(struct lws_cache_ttl_lru * cache)219*1c60b9acSAndroid Build Coastguard Worker lws_cache_expunge(struct lws_cache_ttl_lru *cache)
220*1c60b9acSAndroid Build Coastguard Worker {
221*1c60b9acSAndroid Build Coastguard Worker 	int ret = 0;
222*1c60b9acSAndroid Build Coastguard Worker 
223*1c60b9acSAndroid Build Coastguard Worker 	while (cache) {
224*1c60b9acSAndroid Build Coastguard Worker 		ret |= cache->info.ops->expunge(cache);
225*1c60b9acSAndroid Build Coastguard Worker 
226*1c60b9acSAndroid Build Coastguard Worker 		cache = cache->info.parent;
227*1c60b9acSAndroid Build Coastguard Worker 	}
228*1c60b9acSAndroid Build Coastguard Worker 
229*1c60b9acSAndroid Build Coastguard Worker 	return ret;
230*1c60b9acSAndroid Build Coastguard Worker }
231*1c60b9acSAndroid Build Coastguard Worker 
232*1c60b9acSAndroid Build Coastguard Worker int
lws_cache_item_remove(struct lws_cache_ttl_lru * cache,const char * wildcard_key)233*1c60b9acSAndroid Build Coastguard Worker lws_cache_item_remove(struct lws_cache_ttl_lru *cache, const char *wildcard_key)
234*1c60b9acSAndroid Build Coastguard Worker {
235*1c60b9acSAndroid Build Coastguard Worker 	while (cache) {
236*1c60b9acSAndroid Build Coastguard Worker 		if (cache->info.ops->invalidate(cache, wildcard_key))
237*1c60b9acSAndroid Build Coastguard Worker 			return 1;
238*1c60b9acSAndroid Build Coastguard Worker 
239*1c60b9acSAndroid Build Coastguard Worker 		cache = cache->info.parent;
240*1c60b9acSAndroid Build Coastguard Worker 	}
241*1c60b9acSAndroid Build Coastguard Worker 
242*1c60b9acSAndroid Build Coastguard Worker 	return 0;
243*1c60b9acSAndroid Build Coastguard Worker }
244*1c60b9acSAndroid Build Coastguard Worker 
245*1c60b9acSAndroid Build Coastguard Worker uint64_t
lws_cache_footprint(struct lws_cache_ttl_lru * cache)246*1c60b9acSAndroid Build Coastguard Worker lws_cache_footprint(struct lws_cache_ttl_lru *cache)
247*1c60b9acSAndroid Build Coastguard Worker {
248*1c60b9acSAndroid Build Coastguard Worker 	return cache->current_footprint;
249*1c60b9acSAndroid Build Coastguard Worker }
250*1c60b9acSAndroid Build Coastguard Worker 
251*1c60b9acSAndroid Build Coastguard Worker void
lws_cache_debug_dump(struct lws_cache_ttl_lru * cache)252*1c60b9acSAndroid Build Coastguard Worker lws_cache_debug_dump(struct lws_cache_ttl_lru *cache)
253*1c60b9acSAndroid Build Coastguard Worker {
254*1c60b9acSAndroid Build Coastguard Worker #if defined(_DEBUG)
255*1c60b9acSAndroid Build Coastguard Worker 	if (cache->info.ops->debug_dump)
256*1c60b9acSAndroid Build Coastguard Worker 		cache->info.ops->debug_dump(cache);
257*1c60b9acSAndroid Build Coastguard Worker #endif
258*1c60b9acSAndroid Build Coastguard Worker }
259*1c60b9acSAndroid Build Coastguard Worker 
260*1c60b9acSAndroid Build Coastguard Worker int
lws_cache_results_walk(lws_cache_results_t * walk_ctx)261*1c60b9acSAndroid Build Coastguard Worker lws_cache_results_walk(lws_cache_results_t *walk_ctx)
262*1c60b9acSAndroid Build Coastguard Worker {
263*1c60b9acSAndroid Build Coastguard Worker 	if (!walk_ctx->size)
264*1c60b9acSAndroid Build Coastguard Worker 		return 1;
265*1c60b9acSAndroid Build Coastguard Worker 
266*1c60b9acSAndroid Build Coastguard Worker 	walk_ctx->payload_len = lws_ser_ru32be(walk_ctx->ptr);
267*1c60b9acSAndroid Build Coastguard Worker 	walk_ctx->tag_len = lws_ser_ru32be(walk_ctx->ptr + 4);
268*1c60b9acSAndroid Build Coastguard Worker 	walk_ctx->tag = walk_ctx->ptr + 8;
269*1c60b9acSAndroid Build Coastguard Worker 
270*1c60b9acSAndroid Build Coastguard Worker 	walk_ctx->ptr += walk_ctx->tag_len + 1 + 8;
271*1c60b9acSAndroid Build Coastguard Worker 	walk_ctx->size -= walk_ctx->tag_len + 1 + 8;
272*1c60b9acSAndroid Build Coastguard Worker 
273*1c60b9acSAndroid Build Coastguard Worker 	return 0;
274*1c60b9acSAndroid Build Coastguard Worker }
275*1c60b9acSAndroid Build Coastguard Worker 
276*1c60b9acSAndroid Build Coastguard Worker struct lws_cache_ttl_lru *
lws_cache_create(const struct lws_cache_creation_info * info)277*1c60b9acSAndroid Build Coastguard Worker lws_cache_create(const struct lws_cache_creation_info *info)
278*1c60b9acSAndroid Build Coastguard Worker {
279*1c60b9acSAndroid Build Coastguard Worker 	assert(info);
280*1c60b9acSAndroid Build Coastguard Worker 	assert(info->ops);
281*1c60b9acSAndroid Build Coastguard Worker 	assert(info->name);
282*1c60b9acSAndroid Build Coastguard Worker 	assert(info->ops->create);
283*1c60b9acSAndroid Build Coastguard Worker 
284*1c60b9acSAndroid Build Coastguard Worker 	return info->ops->create(info);
285*1c60b9acSAndroid Build Coastguard Worker }
286*1c60b9acSAndroid Build Coastguard Worker 
287*1c60b9acSAndroid Build Coastguard Worker void
lws_cache_destroy(struct lws_cache_ttl_lru ** _cache)288*1c60b9acSAndroid Build Coastguard Worker lws_cache_destroy(struct lws_cache_ttl_lru **_cache)
289*1c60b9acSAndroid Build Coastguard Worker {
290*1c60b9acSAndroid Build Coastguard Worker 	lws_cache_ttl_lru_t *cache = *_cache;
291*1c60b9acSAndroid Build Coastguard Worker 
292*1c60b9acSAndroid Build Coastguard Worker 	if (!cache)
293*1c60b9acSAndroid Build Coastguard Worker 		return;
294*1c60b9acSAndroid Build Coastguard Worker 
295*1c60b9acSAndroid Build Coastguard Worker 	assert(cache->info.ops->destroy);
296*1c60b9acSAndroid Build Coastguard Worker 
297*1c60b9acSAndroid Build Coastguard Worker 	lws_sul_cancel(&cache->sul);
298*1c60b9acSAndroid Build Coastguard Worker 
299*1c60b9acSAndroid Build Coastguard Worker 	cache->info.ops->destroy(_cache);
300*1c60b9acSAndroid Build Coastguard Worker }
301