| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- /*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
- #include "private-lib-core.h"
- #ifdef LWS_HAVE_SYS_TYPES_H
- #include <sys/types.h>
- #endif
- int
- lws_dll2_foreach_safe(struct lws_dll2_owner *owner, void *user,
- int (*cb)(struct lws_dll2 *d, void *user))
- {
- lws_start_foreach_dll_safe(struct lws_dll2 *, p, tp, owner->head) {
- if (cb(p, user))
- return 1;
- } lws_end_foreach_dll_safe(p, tp);
- return 0;
- }
- void
- lws_dll2_add_head(struct lws_dll2 *d, struct lws_dll2_owner *owner)
- {
- if (!lws_dll2_is_detached(d)) {
- assert(0); /* only wholly detached things can be added */
- return;
- }
- /* our next guy is current first guy, if any */
- if (owner->head != d)
- d->next = owner->head;
- /* if there is a next guy, set his prev ptr to our next ptr */
- if (d->next)
- d->next->prev = d;
- /* there is nobody previous to us, we are the head */
- d->prev = NULL;
- /* set the first guy to be us */
- owner->head = d;
- if (!owner->tail)
- owner->tail = d;
- d->owner = owner;
- owner->count++;
- }
- /*
- * add us to the list that 'after' is in, just before him
- */
- void
- lws_dll2_add_before(struct lws_dll2 *d, struct lws_dll2 *after)
- {
- lws_dll2_owner_t *owner = after->owner;
- if (!lws_dll2_is_detached(d)) {
- assert(0); /* only wholly detached things can be added */
- return;
- }
- if (lws_dll2_is_detached(after)) {
- assert(0); /* can't add after something detached */
- return;
- }
- d->owner = owner;
- /* we need to point forward to after */
- d->next = after;
- /* we need to point back to after->prev */
- d->prev = after->prev;
- /* guy that used to point to after, needs to point to us */
- if (after->prev)
- after->prev->next = d;
- else
- owner->head = d;
- /* then after needs to point back to us */
- after->prev = d;
- owner->count++;
- }
- void
- lws_dll2_add_tail(struct lws_dll2 *d, struct lws_dll2_owner *owner)
- {
- if (!lws_dll2_is_detached(d)) {
- assert(0); /* only wholly detached things can be added */
- return;
- }
- /* our previous guy is current last guy */
- d->prev = owner->tail;
- /* if there is a prev guy, set his next ptr to our prev ptr */
- if (d->prev)
- d->prev->next = d;
- /* our next ptr is NULL */
- d->next = NULL;
- /* set the last guy to be us */
- owner->tail = d;
- /* list head is also us if we're the first */
- if (!owner->head)
- owner->head = d;
- d->owner = owner;
- owner->count++;
- }
- void
- lws_dll2_remove(struct lws_dll2 *d)
- {
- if (lws_dll2_is_detached(d))
- return;
- /* if we have a next guy, set his prev to our prev */
- if (d->next)
- d->next->prev = d->prev;
- /* if we have a previous guy, set his next to our next */
- if (d->prev)
- d->prev->next = d->next;
- /* if we have phead, track the tail and head if it points to us... */
- if (d->owner->tail == d)
- d->owner->tail = d->prev;
- if (d->owner->head == d)
- d->owner->head = d->next;
- d->owner->count--;
- /* we're out of the list, we should not point anywhere any more */
- d->owner = NULL;
- d->prev = NULL;
- d->next = NULL;
- }
- void
- lws_dll2_clear(struct lws_dll2 *d)
- {
- d->owner = NULL;
- d->prev = NULL;
- d->next = NULL;
- }
- void
- lws_dll2_owner_clear(struct lws_dll2_owner *d)
- {
- d->head = NULL;
- d->tail = NULL;
- d->count = 0;
- }
- 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))
- {
- lws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,
- lws_dll2_get_head(own)) {
- assert(p != d);
- if (compare(p, d) >= 0) {
- /* drop us in before this guy */
- lws_dll2_add_before(d, p);
- // lws_dll2_describe(own, "post-insert");
- return;
- }
- } lws_end_foreach_dll_safe(p, tp);
- /*
- * Either nobody on the list yet to compare him to, or he's the
- * furthest away timeout... stick him at the tail end
- */
- lws_dll2_add_tail(d, own);
- }
- 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_start_foreach_dll(struct lws_dll2 *, p, lws_dll2_get_head(own)) {
- uint8_t *ref = ((uint8_t *)p) - dll2_ofs;
- /*
- * We have to read the const char * at the computed place and
- * the string is where that points
- */
- const char *str = *((const char **)(ref + ptr_ofs));
- if (str && !strncmp(str, name, namelen) && !str[namelen])
- return (void *)ref;
- } lws_end_foreach_dll(p);
- return NULL;
- }
- #if defined(_DEBUG)
- void
- lws_dll2_describe(lws_dll2_owner_t *owner, const char *desc)
- {
- #if _LWS_ENABLED_LOGS & LLL_INFO
- int n = 1;
- lwsl_info("%s: %s: owner %p: count %d, head %p, tail %p\n",
- __func__, desc, owner, (int)owner->count, owner->head, owner->tail);
- lws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,
- lws_dll2_get_head(owner)) {
- lwsl_info("%s: %d: %p: owner %p, prev %p, next %p\n",
- __func__, n++, p, p->owner, p->prev, p->next);
- } lws_end_foreach_dll_safe(p, tp);
- #endif
- }
- #endif
|