libwebsockets
Lightweight C library for HTML5 websockets
Loading...
Searching...
No Matches
lws-dll2.h
Go to the documentation of this file.
1/*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
31
48#define lws_start_foreach_ll(type, it, start)\
49{ \
50 type it = start; \
51 while (it) { \
52 int _c_##it = 0, _b_##it = 0; \
53 for (; !_c_##it; _c_##it = 1) {
54
68
69#define lws_end_foreach_ll(it, nxt) \
70 _b_##it = 1; \
71 } \
72 if (!_b_##it) break; \
73 it = it->nxt; \
74 } \
75}
76
96#define lws_start_foreach_ll_safe(type, it, start, nxt)\
97{ \
98 type next_##it; \
99 for (type it = start; it && ((next_##it = it->nxt), 1); it = next_##it) {
100
114
115#define lws_end_foreach_ll_safe(it) \
116 } \
117}
118
139#define lws_start_foreach_llp(type, it, start)\
140{ \
141 type it = &(start); \
142 while (*(it)) { \
143 int _c_##it = 0, _b_##it = 0; \
144 for (; !_c_##it; _c_##it = 1) {
145
146#define lws_start_foreach_llp_safe(type, it, start, nxt)\
147{ \
148 type next; \
149 for (type it = &(start); *(it) && ((next = &((*(it))->nxt)), 1); it = next) {
150
164
165#define lws_end_foreach_llp(it, nxt) \
166 _b_##it = 1; \
167 } \
168 if (!_b_##it) break; \
169 it = &(*(it))->nxt; \
170 } \
171}
172
173#define lws_end_foreach_llp_safe(it) \
174 } \
175}
176
177#define lws_ll_fwd_insert(\
178 ___new_object, /* pointer to new object */ \
179 ___m_list, /* member for next list object ptr */ \
180 ___list_head /* list head */ \
181 ) {\
182 ___new_object->___m_list = ___list_head; \
183 ___list_head = ___new_object; \
184 }
185
186#define lws_ll_fwd_remove(\
187 ___type, /* type of listed object */ \
188 ___m_list, /* member for next list object ptr */ \
189 ___target, /* object to remove from list */ \
190 ___list_head /* list head */ \
191 ) { \
192 lws_start_foreach_llp(___type **, ___ppss, ___list_head) { \
193 if (*___ppss == ___target) { \
194 *___ppss = ___target->___m_list; \
195 break; \
196 } \
197 } lws_end_foreach_llp(___ppss, ___m_list); \
198 }
199
200/*
201 * The legacy singly-linked-list macros are banned inside libwebsockets,
202 * permanently.
203 * --------------------------------------------------------------------
204 *
205 * dll2 owners bring the member count, an owner backpointer per node and the
206 * runtime _safe iterator guard; hand-rolled next-chains have been behind a
207 * number of iterator-lifetime bugs here. All list usage inside the library,
208 * including self-contained datastructure internals like lwsac chunks, the
209 * fts trie and dht tables, is on a one-time conversion to
210 * lws_dll2_owner_t + lws_dll2_t; when the last one is converted the total
211 * ban below is armed by setting LWS_DLL2_ARM_TOTAL_BAN to 1.
212 *
213 * When armed, the ban is enforced at compile time by poisoning the macros
214 * when building the library itself: LWS_BUILDING_STATIC / LWS_BUILDING_SHARED
215 * are PRIVATE to the libwebsockets compile targets, so they are defined when
216 * compiling the library sources and nothing else -- plugins, minimal examples
217 * and user code keep full access to the legacy macros for their own use,
218 * indefinitely.
219 *
220 * Any use inside the library then fails at the use site with the poison
221 * identifier naming the reason.
222 */
223
224/* conversion complete: the total ban is armed */
225#define LWS_DLL2_ARM_TOTAL_BAN 1
226
227#if LWS_DLL2_ARM_TOTAL_BAN && \
228 (defined(LWS_BUILDING_STATIC) || defined(LWS_BUILDING_SHARED))
229
230#undef lws_start_foreach_ll
231#undef lws_end_foreach_ll
232#undef lws_start_foreach_ll_safe
233#undef lws_end_foreach_ll_safe
234#undef lws_start_foreach_llp
235#undef lws_end_foreach_llp
236#undef lws_start_foreach_llp_safe
237#undef lws_end_foreach_llp_safe
238#undef lws_ll_fwd_insert
239#undef lws_ll_fwd_remove
240
241#define lws_start_foreach_ll(...) \
242 LWS_LIB_MAY_NOT_USE_LEGACY_LIST_MACROS_see_lws_dll2_h
243#define lws_end_foreach_ll(...) \
244 LWS_LIB_MAY_NOT_USE_LEGACY_LIST_MACROS_see_lws_dll2_h
245#define lws_start_foreach_ll_safe(...) \
246 LWS_LIB_MAY_NOT_USE_LEGACY_LIST_MACROS_see_lws_dll2_h
247#define lws_end_foreach_ll_safe(...) \
248 LWS_LIB_MAY_NOT_USE_LEGACY_LIST_MACROS_see_lws_dll2_h
249#define lws_start_foreach_llp(...) \
250 LWS_LIB_MAY_NOT_USE_LEGACY_LIST_MACROS_see_lws_dll2_h
251#define lws_end_foreach_llp(...) \
252 LWS_LIB_MAY_NOT_USE_LEGACY_LIST_MACROS_see_lws_dll2_h
253#define lws_start_foreach_llp_safe(...) \
254 LWS_LIB_MAY_NOT_USE_LEGACY_LIST_MACROS_see_lws_dll2_h
255#define lws_end_foreach_llp_safe(...) \
256 LWS_LIB_MAY_NOT_USE_LEGACY_LIST_MACROS_see_lws_dll2_h
257#define lws_ll_fwd_insert(...) \
258 LWS_LIB_MAY_NOT_USE_LEGACY_LIST_MACROS_see_lws_dll2_h
259#define lws_ll_fwd_remove(...) \
260 LWS_LIB_MAY_NOT_USE_LEGACY_LIST_MACROS_see_lws_dll2_h
261#endif
262
263
264/*
265 * doubly linked-list
266 */
267
268/*
269 * lws_dll2_owner / lws_dll2 : more capable version of lws_dll. Differences:
270 *
271 * - there's an explicit lws_dll2_owner struct which holds head, tail and
272 * count of members.
273 *
274 * - list members all hold a pointer to their owner. So user code does not
275 * have to track anything about exactly what lws_dll2_owner list the object
276 * is a member of.
277 *
278 * - you can use lws_dll unless you want the member count or the ability to
279 * not track exactly which list it's on.
280 *
281 * - layout is compatible with lws_dll (but lws_dll apis will not update the
282 * new stuff)
283 */
284
285
286struct lws_dll2;
287struct lws_dll2_owner;
288
289typedef struct lws_dll2 {
290 struct lws_dll2 *prev;
291 struct lws_dll2 *next;
294
295typedef struct lws_dll2_owner {
296 struct lws_dll2 *tail;
297 struct lws_dll2 *head;
298
300
301 /*
302 * Monotonic "generation" of the list contents: bumped by every add*
303 * and remove, and reset to 0 by lws_dll2_owner_clear() (which also
304 * serves as the owner initializer and so writes it without reading).
305 * The _safe iterator helpers use it to cheaply notice that the list
306 * changed during the loop body, so they can validate their cached
307 * next pointer is still a list member before using it. Since an
308 * iterable owner must have had at least one add, a live iterator's
309 * cached generation is never 0 and the clear reset is still always
310 * detectable. Never compare generations for ordering across
311 * different owners, only inequality on the same owner.
312 */
315
318
319static LWS_INLINE struct lws_dll2_owner *
320lws_dll2_owner(const struct lws_dll2 *d) { return d ? d->owner : NULL; }
321
322static LWS_INLINE struct lws_dll2 *
323lws_dll2_get_head(const struct lws_dll2_owner *owner) { return owner ? owner->head : NULL; }
324
325static LWS_INLINE struct lws_dll2 *
326lws_dll2_get_tail(const struct lws_dll2_owner *owner) { return owner ? owner->tail : NULL; }
327
328/*
329 * Read-only accessors for list state, in the same NULL-tolerant style as
330 * lws_dll2_get_head() / lws_dll2_get_tail(): a NULL owner or node gives 0 /
331 * NULL, a detached node has no next or prev. User code should use these
332 * rather than reach into the struct members directly, so the members and
333 * their invariants stay the business of lws_dll2.c alone.
334 */
335
336static LWS_INLINE uint32_t
337lws_dll2_count(const struct lws_dll2_owner *owner)
338{
339 return owner ? owner->count : 0;
340}
341
342static LWS_INLINE int
343lws_dll2_is_empty(const struct lws_dll2_owner *owner)
344{
345 return !lws_dll2_count(owner);
346}
347
348static LWS_INLINE struct lws_dll2 *
349lws_dll2_get_next(const struct lws_dll2 *d) { return d ? d->next : NULL; }
350
351static LWS_INLINE struct lws_dll2 *
352lws_dll2_get_prev(const struct lws_dll2 *d) { return d ? d->prev : NULL; }
353
356
359
362
363typedef int (*lws_dll2_foreach_cb_t)(struct lws_dll2 *d, void *user);
364
368
371
374
376lws_dll2_add_before(struct lws_dll2 *d, struct lws_dll2 *after);
377
380
383 int (*compare)(const lws_dll2_t *d, const lws_dll2_t *i));
384
387 int (*compare3)(void *priv, const lws_dll2_t *d,
388 const lws_dll2_t *i));
389
390/*
391 * Returns nonzero if d is currently a member of owner's list. Only compares
392 * pointers walking the live list members; never dereferences d itself, so it
393 * is safe to call with a candidate pointer that may have been freed, exactly
394 * for validating cached iterator state.
395 */
398
399/*
400 * Guarded advance for the _safe iterator macros: validates that cand (the
401 * cached next node) is still a member of ow's list if anything mutated the
402 * list (ow->generation != *gen) since it was cached. If cand went away, it
403 * asserts (unless lws_dll2_guard_quiet) and recovers by restarting from the
404 * live head, so even release builds stop walking into freed nodes. Returns
405 * the node the iterator should advance to.
406 *
407 * Notice there is deliberately no "current node" parameter to resume from
408 * its successor: the supported usage is that the loop body may remove and
409 * free the current node itself, so by the time this runs that pointer may
410 * refer to freed memory. Passing it here (even without dereferencing it)
411 * is exactly the use-after-free pattern static analysis must reject. The
412 * consequence is that recovery revisits still-listed nodes before the
413 * invalidation point; _safe loop bodies must tolerate being re-run for
414 * nodes they already saw (act by predicate, not one-shot).
415 */
418 struct lws_dll2 *cand);
419
420/*
421 * Guarded backwards advance for the _safe_back iterator macros: identical
422 * contract to _lws_dll2_safe_next(), except the cached node it validates is
423 * the one towards the head, and invalidation recovers by restarting from the
424 * live tail.
425 */
428 struct lws_dll2 *cand);
429
430/*
431 * Set to nonzero by tests (or apps that must not die) to make the _safe
432 * iterator guard log + recover from cached-next invalidation instead of
433 * asserting. The default, 0, asserts loudly at the exact point of the
434 * misuse, which is what you want during development.
435 *
436 * Deliberately mutable runtime state, not a const table entry.
437 */
439
441_lws_dll2_search_sz_pl(lws_dll2_owner_t *own, const char *name, size_t namelen,
442 size_t dll2_ofs, size_t ptr_ofs);
443
444/*
445 * Searches objects in an owner list linearly and returns one with a given
446 * member C-string matching a supplied length-provided string if it exists, else
447 * NULL.
448 */
449
450#define lws_dll2_search_sz_pl(own, name, namelen, type, membd2list, membptr) \
451 ((type *)_lws_dll2_search_sz_pl(own, name, namelen, \
452 offsetof(type, membd2list), \
453 offsetof(type, membptr)))
454
455static LWS_INLINE void *
456_lws_dll2_owner_container(const struct lws_dll2 *d, size_t owner_ofs)
457{
458 return d && d->owner ?
459 (void *)((char *)d->owner - owner_ofs) : NULL;
460}
461
462/*
463 * lws_dll2_owner_container(): get the object containing the owner the node
464 * is attached to
465 *
466 * \param d: lws_dll2_t * member of some listed object
467 * \param type: type of the object that embeds the lws_dll2_owner_t
468 * \param membowner: member name of the lws_dll2_owner_t inside type
469 *
470 * Returns the object whose owner member the node is attached to, or NULL if
471 * the node is detached (or NULL). This is the dll2-native way to express
472 * the lws_container_of(d->owner, type, membowner) idiom. The node
473 * expression is evaluated exactly once.
474 */
475
476#define lws_dll2_owner_container(___d, ___type, ___membowner) \
477 ((___type *)_lws_dll2_owner_container(___d, \
478 offsetof(___type, ___membowner)))
479
480#if defined(_DEBUG)
481void
482lws_dll2_describe(struct lws_dll2_owner *owner, const char *desc);
483#else
484#define lws_dll2_describe(x, y)
485#endif
486
487/*
488 * these are safe against the current container object getting deleted,
489 * since they hold his next in a temp and go to that next. ___tmp is
490 * the temp.
491 *
492 * Additionally the iterator is guarded at runtime: if the loop body
493 * removes (and possibly frees) some *other* member of the list, e.g. the
494 * cached next node itself, the guarded advance validates the cached next
495 * against the live list (by pointer identity only, it is never
496 * dereferenced) and, if it went away, asserts with a clear reason and
497 * recovers by restarting from the live head, instead of walking into
498 * freed memory and failing far away with no clue why. The fast path when
499 * nothing mutated the list is a single 32-bit compare per iteration.
500 *
501 * NOTE: ___start must be side-effect-free since it is evaluated once into
502 * a temporary.
503 *
504 * NOTE: the recovery path restarts from the live head, which can revisit
505 * earlier nodes still on the list; loop bodies must be idempotent under
506 * being re-run for a node they already saw.
507 */
508
509#define lws_start_foreach_dll_safe(___type, ___it, ___tmp, ___start) \
510{ \
511 ___type ___tmp; \
512 struct lws_dll2 *___st_##___it = (___start); \
513 struct lws_dll2_owner *___ow_##___it = \
514 ___st_##___it ? ___st_##___it->owner : NULL; \
515 uint32_t ___gen_##___it = ___ow_##___it ? \
516 ___ow_##___it->generation : 0; \
517 for (___type ___it = ___st_##___it; \
518 ___it && (((___tmp) = (___it)->next), 1); \
519 ___it = _lws_dll2_safe_next(___ow_##___it, &___gen_##___it, \
520 ___tmp)) {
521
522#define lws_end_foreach_dll_safe(___it, ___tmp) \
523 } \
524}
525
526#define lws_start_foreach_dll(___type, ___it, ___start) \
527{ \
528 for (___type ___it = (___start); ___it; ___it = (___it)->next) {
529
530#define lws_end_foreach_dll(___it) \
531 } \
532}
533
534/*
535 * These are the same as the two iterators above, but walk the list
536 * backwards: ___start is normally the owner's tail, eg
537 * lws_dll2_get_tail(owner), and the walk advances along ->prev until it
538 * reaches the head. As with the forwards iterators, the plain version is
539 * for loops that do not touch the list membership during the body.
540 */
541
542#define lws_start_foreach_dll_back(___type, ___it, ___start) \
543{ \
544 for (___type ___it = (___start); ___it; ___it = (___it)->prev) {
545
546#define lws_end_foreach_dll_back(___it) \
547 } \
548}
549
550/*
551 * This is the _safe version of the backwards iterator: the cached previous
552 * node is validated against the live list using the same generation-count
553 * guard as the forwards _safe iterator, with a single 32-bit compare per
554 * iteration when nothing has mutated the list. If the loop body removed
555 * (and possibly freed) the cached previous node, it asserts with a clear
556 * reason and recovers by restarting from the live tail, so loop bodies
557 * must be idempotent under being re-run for nodes they already saw.
558 *
559 * NOTE: ___start must be side-effect-free since it is evaluated once into
560 * a temporary.
561 */
562
563#define lws_start_foreach_dll_safe_back(___type, ___it, ___tmp, ___start) \
564{ \
565 ___type ___tmp; \
566 struct lws_dll2 *___st_##___it = (___start); \
567 struct lws_dll2_owner *___ow_##___it = \
568 ___st_##___it ? ___st_##___it->owner : NULL; \
569 uint32_t ___gen_##___it = ___ow_##___it ? \
570 ___ow_##___it->generation : 0; \
571 for (___type ___it = ___st_##___it; \
572 ___it && (((___tmp) = (___it)->prev), 1); \
573 ___it = _lws_dll2_safe_prev(___ow_##___it, &___gen_##___it, \
574 ___tmp)) {
575
576#define lws_end_foreach_dll_safe_back(___it, ___tmp) \
577 } \
578}
579
581
struct lws_dll2 * tail
Definition lws-dll2.h:296
struct lws_dll2 * next
Definition lws-dll2.h:291
struct lws_dll2_owner * owner
Definition lws-dll2.h:292
struct lws_dll2 * prev
Definition lws-dll2.h:290
uint32_t generation
Definition lws-dll2.h:313
struct lws_dll2 * head
Definition lws-dll2.h:297
uint32_t count
Definition lws-dll2.h:299
struct lws_dll2 lws_dll2_t
LWS_VISIBLE LWS_EXTERN void lws_dll2_add_tail(struct lws_dll2 *d, struct lws_dll2_owner *owner)
LWS_VISIBLE LWS_EXTERN struct lws_dll2 * _lws_dll2_safe_next(struct lws_dll2_owner *ow, uint32_t *gen, struct lws_dll2 *cand)
LWS_VISIBLE LWS_EXTERN void lws_dll2_owner_clear(struct lws_dll2_owner *d)
LWS_VISIBLE LWS_EXTERN struct lws_dll2 * _lws_dll2_safe_prev(struct lws_dll2_owner *ow, uint32_t *gen, struct lws_dll2 *cand)
LWS_VISIBLE LWS_EXTERN void lws_dll2_add_sorted_priv(lws_dll2_t *d, lws_dll2_owner_t *own, void *priv, int(*compare3)(void *priv, const lws_dll2_t *d, const lws_dll2_t *i))
LWS_VISIBLE LWS_EXTERN int lws_dll2_is_in_list(struct lws_dll2_owner *owner, struct lws_dll2 *d)
#define lws_dll2_describe(x, y)
Definition lws-dll2.h:484
LWS_VISIBLE LWS_EXTERN void lws_dll2_add_sorted(lws_dll2_t *d, lws_dll2_owner_t *own, int(*compare)(const lws_dll2_t *d, const lws_dll2_t *i))
struct lws_dll2_owner lws_dll2_owner_t
LWS_VISIBLE LWS_EXTERN void lws_dll2_add_insert(struct lws_dll2 *d, struct lws_dll2 *prev)
LWS_VISIBLE LWS_EXTERN void * _lws_dll2_search_sz_pl(lws_dll2_owner_t *own, const char *name, size_t namelen, size_t dll2_ofs, size_t ptr_ofs)
LWS_VISIBLE LWS_EXTERN void lws_dll2_add_before(struct lws_dll2 *d, struct lws_dll2 *after)
int(* lws_dll2_foreach_cb_t)(struct lws_dll2 *d, void *user)
Definition lws-dll2.h:363
LWS_VISIBLE LWS_EXTERN int lws_dll2_is_detached(const struct lws_dll2 *d)
LWS_VISIBLE LWS_EXTERN void lws_dll2_remove(struct lws_dll2 *d)
LWS_VISIBLE LWS_EXTERN_FOR_DATA int lws_dll2_guard_quiet
Definition lws-dll2.h:438
LWS_VISIBLE LWS_EXTERN void lws_dll2_clear(struct lws_dll2 *d)
LWS_VISIBLE LWS_EXTERN int lws_dll2_foreach_safe(struct lws_dll2_owner *owner, void *user, lws_dll2_foreach_cb_t cb)
LWS_VISIBLE LWS_EXTERN void lws_dll2_add_head(struct lws_dll2 *d, struct lws_dll2_owner *owner)
#define LWS_EXTERN_FOR_DATA
unsigned int uint32_t
#define LWS_INLINE
#define LWS_EXTERN
#define LWS_VISIBLE