Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"", "gen_ut":1713590275, "reponame":"libwebsockets", "desc":"libwebsockets lightweight C networking library", "owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://libwebsockets.org/repo/libwebsockets", "f":3, "items": [ {"schema":"libjg2-1", "cid":"c3791f01c8b25d172539e5e73ecaec2b", "oid":{ "oid": "f28a45246e7ea479718ddba5e80deb355b23f5f3", "alias": [ "refs/heads/main"]},"blobname": "lib/core/lws_dll2.c", "blob": "/*\n * libwebsockets - small server side websockets and web server implementation\n *\n * Copyright (C) 2010 - 2019 Andy Green \u003candy@warmcat.com\u003e\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \u0022Software\u0022), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \u0022AS IS\u0022, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n#include \u0022private-lib-core.h\u0022\n\n#ifdef LWS_HAVE_SYS_TYPES_H\n#include \u003csys/types.h\u003e\n#endif\n\nint\nlws_dll2_is_detached(const struct lws_dll2 *d)\n{\n\tif (d-\u003eowner)\n\t\treturn 0;\n\n\tif (d-\u003enext || d-\u003eprev) {\n\t\tlwsl_err(\u0022%s: dll2 %p: detached but next %p, prev %p\u005cn\u0022,\n\t\t\t\t__func__, d, d-\u003enext, d-\u003eprev);\n\t\t/*\n\t\t * New lws_dll2 objects and removed lws_dll2 objects\n\t\t * have .owner, .next and .prev all set to NULL, so we\n\t\t * can just check .owner to see if we are detached.\n\t\t *\n\t\t * We assert here if we encounter an lws_dll2 in the illegal\n\t\t * state of NULL .owner, but non-NULL in .next or .prev,\n\t\t * it's evidence of corruption, use-after-free, threads\n\t\t * contending on accessing without locking etc.\n\t\t */\n\t\tassert(0);\n\t}\n\n\treturn 1;\n}\n\nint\nlws_dll2_foreach_safe(struct lws_dll2_owner *owner, void *user,\n\t\t int (*cb)(struct lws_dll2 *d, void *user))\n{\n\tlws_start_foreach_dll_safe(struct lws_dll2 *, p, tp, owner-\u003ehead) {\n\t\tif (cb(p, user))\n\t\t\treturn 1;\n\t} lws_end_foreach_dll_safe(p, tp);\n\n\treturn 0;\n}\n\nvoid\nlws_dll2_add_head(struct lws_dll2 *d, struct lws_dll2_owner *owner)\n{\n\tif (!lws_dll2_is_detached(d)) {\n\t\tassert(0); /* only wholly detached things can be added */\n\t\treturn;\n\t}\n\n\t/* our next guy is current first guy, if any */\n\tif (owner-\u003ehead !\u003d d)\n\t\td-\u003enext \u003d owner-\u003ehead;\n\n\t/* if there is a next guy, set his prev ptr to our next ptr */\n\tif (d-\u003enext)\n\t\td-\u003enext-\u003eprev \u003d d;\n\t/* there is nobody previous to us, we are the head */\n\td-\u003eprev \u003d NULL;\n\n\t/* set the first guy to be us */\n\towner-\u003ehead \u003d d;\n\n\tif (!owner-\u003etail)\n\t\towner-\u003etail \u003d d;\n\n\td-\u003eowner \u003d owner;\n\towner-\u003ecount++;\n}\n\n/*\n * add us to the list that 'after' is in, just before him\n */\n\nvoid\nlws_dll2_add_before(struct lws_dll2 *d, struct lws_dll2 *after)\n{\n\tlws_dll2_owner_t *owner \u003d after-\u003eowner;\n\n\tif (!lws_dll2_is_detached(d)) {\n\t\tassert(0); /* only wholly detached things can be added */\n\t\treturn;\n\t}\n\n\tif (lws_dll2_is_detached(after)) {\n\t\tassert(0); /* can't add after something detached */\n\t\treturn;\n\t}\n\n\td-\u003eowner \u003d owner;\n\n\t/* we need to point forward to after */\n\n\td-\u003enext \u003d after;\n\n\t/* we need to point back to after-\u003eprev */\n\n\td-\u003eprev \u003d after-\u003eprev;\n\n\t/* guy that used to point to after, needs to point to us */\n\n\tif (after-\u003eprev)\n\t\tafter-\u003eprev-\u003enext \u003d d;\n\telse\n\t\towner-\u003ehead \u003d d;\n\n\t/* then after needs to point back to us */\n\n\tafter-\u003eprev \u003d d;\n\n\towner-\u003ecount++;\n}\n\n/* add us to the list that prev is in, just after him\n *\n * (Prev) [ \u003c-\u003e (Next) ]\n * (Prev) \u003c-\u003e (ins) [ \u003c-\u003e (Next) ]\n *\n * use lws_dll2_add_head() instead if prev would be NULL\n * */\nvoid\nlws_dll2_add_insert(struct lws_dll2 *d, struct lws_dll2 *prev)\n{\n\tlws_dll2_owner_t *owner \u003d prev-\u003eowner;\n\n\tif (!lws_dll2_is_detached(d)) {\n\t\tassert(0); /* only wholly detached things can be added */\n\t\treturn;\n\t}\n\n\tif (lws_dll2_is_detached(prev)) {\n\t\tassert(0); /* can't add after something detached */\n\t\treturn;\n\t}\n\n\td-\u003eowner \u003d owner;\n\n\td-\u003enext \u003d prev-\u003enext;\n\td-\u003eprev \u003d prev;\n\tif (prev-\u003enext)\n\t\t(prev-\u003enext)-\u003eprev \u003d d;\n\tprev-\u003enext \u003d d;\n\n\tif (!d-\u003enext)\n\t\towner-\u003etail \u003d d;\n\n\towner-\u003ecount++;\n}\n\nvoid\nlws_dll2_add_tail(struct lws_dll2 *d, struct lws_dll2_owner *owner)\n{\n\tif (!lws_dll2_is_detached(d)) {\n\t\tassert(0); /* only wholly detached things can be added */\n\t\treturn;\n\t}\n\n\t/* our previous guy is current last guy */\n\td-\u003eprev \u003d owner-\u003etail;\n\t/* if there is a prev guy, set his next ptr to our prev ptr */\n\tif (d-\u003eprev)\n\t\td-\u003eprev-\u003enext \u003d d;\n\t/* our next ptr is NULL */\n\td-\u003enext \u003d NULL;\n\t/* set the last guy to be us */\n\towner-\u003etail \u003d d;\n\n\t/* list head is also us if we're the first */\n\tif (!owner-\u003ehead)\n\t\towner-\u003ehead \u003d d;\n\n\td-\u003eowner \u003d owner;\n\towner-\u003ecount++;\n}\n\nvoid\nlws_dll2_remove(struct lws_dll2 *d)\n{\n\tif (lws_dll2_is_detached(d))\n\t\treturn;\n\n\t/* if we have a next guy, set his prev to our prev */\n\tif (d-\u003enext)\n\t\td-\u003enext-\u003eprev \u003d d-\u003eprev;\n\n\t/* if we have a previous guy, set his next to our next */\n\tif (d-\u003eprev)\n\t\td-\u003eprev-\u003enext \u003d d-\u003enext;\n\n\t/* if we have phead, track the tail and head if it points to us... */\n\n\tif (d-\u003eowner-\u003etail \u003d\u003d d)\n\t\td-\u003eowner-\u003etail \u003d d-\u003eprev;\n\n\tif (d-\u003eowner-\u003ehead \u003d\u003d d)\n\t\td-\u003eowner-\u003ehead \u003d d-\u003enext;\n\n\td-\u003eowner-\u003ecount--;\n\n\t/* we're out of the list, we should not point anywhere any more */\n\td-\u003eowner \u003d NULL;\n\td-\u003eprev \u003d NULL;\n\td-\u003enext \u003d NULL;\n}\n\nvoid\nlws_dll2_clear(struct lws_dll2 *d)\n{\n\td-\u003eowner \u003d NULL;\n\td-\u003eprev \u003d NULL;\n\td-\u003enext \u003d NULL;\n}\n\nvoid\nlws_dll2_owner_clear(struct lws_dll2_owner *d)\n{\n\td-\u003ehead \u003d NULL;\n\td-\u003etail \u003d NULL;\n\td-\u003ecount \u003d 0;\n}\n\nvoid\nlws_dll2_add_sorted_priv(lws_dll2_t *d, lws_dll2_owner_t *own, void *priv,\n\t\t\t int (*compare3)(void *priv, const lws_dll2_t *d,\n\t\t\t\t\tconst lws_dll2_t *i))\n{\n\tlws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,\n\t\t\t\t lws_dll2_get_head(own)) {\n\t\tassert(p !\u003d d);\n\n\t\tif (compare3(priv, p, d) \u003e\u003d 0) {\n\t\t\t/* drop us in before this guy */\n\t\t\tlws_dll2_add_before(d, p);\n\n\t\t\treturn;\n\t\t}\n\t} lws_end_foreach_dll_safe(p, tp);\n\n\t/*\n\t * Either nobody on the list yet to compare him to, or he's the\n\t * furthest away timeout... stick him at the tail end\n\t */\n\n\tlws_dll2_add_tail(d, own);\n}\n\nvoid\nlws_dll2_add_sorted(lws_dll2_t *d, lws_dll2_owner_t *own,\n\t\t int (*compare)(const lws_dll2_t *d, const lws_dll2_t *i))\n{\n\tlws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,\n\t\t\t\t lws_dll2_get_head(own)) {\n\t\tassert(p !\u003d d);\n\n\t\tif (compare(p, d) \u003e\u003d 0) {\n\t\t\t/* drop us in before this guy */\n\t\t\tlws_dll2_add_before(d, p);\n\n\t\t\treturn;\n\t\t}\n\t} lws_end_foreach_dll_safe(p, tp);\n\n\t/*\n\t * Either nobody on the list yet to compare him to, or he's the\n\t * furthest away timeout... stick him at the tail end\n\t */\n\n\tlws_dll2_add_tail(d, own);\n}\n\nvoid *\n_lws_dll2_search_sz_pl(lws_dll2_owner_t *own, const char *name, size_t namelen,\n\t\t size_t dll2_ofs, size_t ptr_ofs)\n{\n\tlws_start_foreach_dll(struct lws_dll2 *, p, lws_dll2_get_head(own)) {\n\t\tuint8_t *ref \u003d ((uint8_t *)p) - dll2_ofs;\n\t\t/*\n\t\t * We have to read the const char * at the computed place and\n\t\t * the string is where that points\n\t\t */\n\t\tconst char *str \u003d *((const char **)(ref + ptr_ofs));\n\n\t\tif (str \u0026\u0026 !strncmp(str, name, namelen) \u0026\u0026 !str[namelen])\n\t\t\treturn (void *)ref;\n\t} lws_end_foreach_dll(p);\n\n\treturn NULL;\n}\n\n#if defined(_DEBUG)\n\nvoid\nlws_dll2_describe(lws_dll2_owner_t *owner, const char *desc)\n{\n#if _LWS_ENABLED_LOGS \u0026 LLL_INFO\n\tint n \u003d 1;\n\n\tlwsl_info(\u0022%s: %s: owner %p: count %d, head %p, tail %p\u005cn\u0022,\n\t\t __func__, desc, owner, (int)owner-\u003ecount, owner-\u003ehead, owner-\u003etail);\n\n\tlws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,\n\t\t\t\t lws_dll2_get_head(owner)) {\n\t\tlwsl_info(\u0022%s: %d: %p: owner %p, prev %p, next %p\u005cn\u0022,\n\t\t\t __func__, n++, p, p-\u003eowner, p-\u003eprev, p-\u003enext);\n\t} lws_end_foreach_dll_safe(p, tp);\n#endif\n}\n\n#endif\n","s":{"c":1713590275,"u": 271}} ],"g": 1091,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 1, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}