Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"", "gen_ut":1713488468, "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":"17b79f882fb9432c22d2f476f942e49c", "oid":{ "oid": "f28a45246e7ea479718ddba5e80deb355b23f5f3", "alias": [ "refs/heads/main"]},"blobname": "lib/misc/lwsac/lwsac.c", "blob": "/*\n * libwebsockets - small server side websockets and web server implementation\n *\n * Copyright (C) 2010 - 2020 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#include \u0022private-lib-misc-lwsac.h\u0022\n\nvoid\nlws_list_ptr_insert(lws_list_ptr *head, lws_list_ptr *add,\n\t\t lws_list_ptr_sort_func_t sort_func)\n{\n\twhile (sort_func \u0026\u0026 *head) {\n\t\tif (sort_func(add, *head) \u003c\u003d 0)\n\t\t\tbreak;\n\n\t\thead \u003d *head;\n\t}\n\n\t*add \u003d *head;\n\t*head \u003d add;\n}\n\nsize_t\nlwsac_align(size_t length)\n{\n\tsize_t align \u003d sizeof(int *);\n\n\tif (length \u0026 (align - 1))\n\t\tlength +\u003d align - (length \u0026 (align - 1));\n\n\treturn length;\n}\n\nsize_t\nlwsac_sizeof(int first)\n{\n\treturn sizeof(struct lwsac) + (first ? sizeof(struct lwsac_head) : 0);\n}\n\nsize_t\nlwsac_get_tail_pos(struct lwsac *lac)\n{\n\treturn lac-\u003eofs;\n}\n\nstruct lwsac *\nlwsac_get_next(struct lwsac *lac)\n{\n\treturn lac-\u003enext;\n}\n\nint\nlwsac_extend(struct lwsac *head, size_t amount)\n{\n\tstruct lwsac_head *lachead;\n\tstruct lwsac *bf;\n\n\tassert(head);\n\tlachead \u003d (struct lwsac_head *)\u0026head[1];\n\n\tbf \u003d lachead-\u003ecurr;\n\tassert(bf);\n\n\tif (bf-\u003ealloc_size - bf-\u003eofs \u003c lwsac_align(amount))\n\t\treturn 1;\n\n\t/* memset so constant folding never sees uninitialized data */\n\n\tmemset(((uint8_t *)bf) + bf-\u003eofs, 0, lwsac_align(amount));\n\tbf-\u003eofs +\u003d lwsac_align(amount);\n\n\treturn 0;\n}\n\nstatic void *\n_lwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size, char backfill)\n{\n\tstruct lwsac_head *lachead \u003d NULL;\n\tsize_t ofs, alloc, al, hp;\n\tstruct lwsac *bf \u003d *head;\n\n\tif (bf)\n\t\tlachead \u003d (struct lwsac_head *)\u0026bf[1];\n\n\tal \u003d lwsac_align(ensure);\n\n\t/* backfill into earlier chunks if that is allowed */\n\n\tif (backfill)\n\t\t/*\n\t\t * check if anything can take it, from the start\n\t\t */\n\t\twhile (bf) {\n\t\t\tif (bf-\u003ealloc_size - bf-\u003eofs \u003e\u003d ensure)\n\t\t\t\tgoto do_use;\n\n\t\t\tbf \u003d bf-\u003enext;\n\t\t}\n\telse {\n\t\t/*\n\t\t * If there's a current chunk, just check if he can take it\n\t\t */\n\t\tif (lachead \u0026\u0026 lachead-\u003ecurr) {\n\t\t\tbf \u003d lachead-\u003ecurr;\n\t\t\tif (bf-\u003ealloc_size - bf-\u003eofs \u003e\u003d ensure)\n\t\t\t\tgoto do_use;\n\t\t}\n\t}\n\n\t/* nothing can currently take it... so we must allocate */\n\n\thp \u003d sizeof(*bf); /* always need the normal header part... */\n\tif (!*head)\n\t\thp +\u003d sizeof(struct lwsac_head);\n\n\tif (!chunk_size)\n\t\talloc \u003d LWSAC_CHUNK_SIZE + hp;\n\telse\n\t\talloc \u003d chunk_size + hp;\n\n\t/*\n\t * If we get asked for something outside our expectation,\n\t * increase the allocation to meet it\n\t */\n\n\tif (al \u003e\u003d alloc - hp)\n\t\talloc \u003d al + hp;\n\n//\tlwsl_debug(\u0022%s: alloc %d for %d\u005cn\u0022, __func__, (int)alloc, (int)ensure);\n\tbf \u003d malloc(alloc);\n\tif (!bf) {\n\t\tlwsl_err(\u0022%s: OOM trying to alloc %llud\u005cn\u0022, __func__,\n\t\t\t\t(unsigned long long)alloc);\n\t\treturn NULL;\n\t}\n\n\t/*\n\t * belabouring the point... ofs is aligned to the platform's\n\t * generic struct alignment at the start then\n\t */\n\tbf-\u003eofs \u003d sizeof(*bf);\n\n\tif (!*head) {\n\t\t/*\n\t\t * We are the first, head, entry...\n\t\t */\n\t\t*head \u003d bf;\n\t\t/*\n\t\t * ... allocate for the special head block\n\t\t */\n\t\tbf-\u003eofs +\u003d sizeof(*lachead);\n\t\tlachead \u003d (struct lwsac_head *)\u0026bf[1];\n\t\tmemset(lachead, 0, sizeof(*lachead));\n\t} else\n\t\tif (lachead-\u003ecurr)\n\t\t\tlachead-\u003ecurr-\u003enext \u003d bf;\n\n\tlachead-\u003ecurr \u003d bf;\n\tbf-\u003ehead \u003d *head;\n\tbf-\u003enext \u003d NULL;\n\tbf-\u003ealloc_size \u003d alloc;\n\n\tlachead-\u003etotal_alloc_size +\u003d alloc;\n\tlachead-\u003etotal_blocks++;\n\ndo_use:\n\n\tofs \u003d bf-\u003eofs;\n\n\tif (al \u003e ensure)\n\t\t/* zero down the alignment padding part */\n\t\tmemset((char *)bf + ofs + ensure, 0, al - ensure);\n\n\tbf-\u003eofs +\u003d al;\n\tif (bf-\u003eofs \u003e\u003d bf-\u003ealloc_size)\n\t\tbf-\u003eofs \u003d bf-\u003ealloc_size;\n\n\treturn (char *)bf + ofs;\n}\n\nvoid *\nlwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size)\n{\n\treturn _lwsac_use(head, ensure, chunk_size, 0);\n}\n\nvoid *\nlwsac_use_backfill(struct lwsac **head, size_t ensure, size_t chunk_size)\n{\n\treturn _lwsac_use(head, ensure, chunk_size, 1);\n}\n\nuint8_t *\nlwsac_scan_extant(struct lwsac *head, uint8_t *find, size_t len, int nul)\n{\n\twhile (head) {\n\t\tuint8_t *pos \u003d (uint8_t *)\u0026head[1],\n\t\t\t*end \u003d ((uint8_t *)head) + head-\u003eofs - len;\n\n\t\tif (head-\u003eofs - sizeof(*head) \u003e\u003d len)\n\t\t\twhile (pos \u003c end) {\n\t\t\t\tif (*pos \u003d\u003d *find \u0026\u0026 (!nul || !pos[len]) \u0026\u0026\n\t\t\t\t pos[len - 1] \u003d\u003d find[len - 1] \u0026\u0026\n\t\t\t\t !memcmp(pos, find, len))\n\t\t\t\t\t/* found the blob */\n\t\t\t\t\treturn pos;\n\t\t\t\tpos++;\n\t\t\t}\n\n\t\thead \u003d head-\u003enext;\n\t}\n\n\treturn NULL;\n}\n\nuint64_t\nlwsac_total_overhead(struct lwsac *head)\n{\n\tuint64_t overhead \u003d 0;\n\n\twhile (head) {\n\t\toverhead +\u003d (head-\u003ealloc_size - head-\u003eofs) + sizeof(*head);\n\n\t\thead \u003d head-\u003enext;\n\t}\n\n\treturn overhead;\n}\n\nvoid *\nlwsac_use_zero(struct lwsac **head, size_t ensure, size_t chunk_size)\n{\n\tvoid *p \u003d lwsac_use(head, ensure, chunk_size);\n\n\tif (p)\n\t\tmemset(p, 0, ensure);\n\n\treturn p;\n}\n\nvoid\nlwsac_free(struct lwsac **head)\n{\n\tstruct lwsac *it \u003d *head;\n\n\t*head \u003d NULL;\n\t// lwsl_debug(\u0022%s: head %p\u005cn\u0022, __func__, *head);\n\n\twhile (it) {\n\t\tstruct lwsac *tmp \u003d it-\u003enext;\n\n\t\tfree(it);\n\t\tit \u003d tmp;\n\t}\n}\n\nvoid\nlwsac_info(struct lwsac *head)\n{\n#if _LWS_ENABLED_LOGS \u0026 LLL_DEBUG\n\tstruct lwsac_head *lachead;\n\n\tif (!head) {\n\t\tlwsl_debug(\u0022%s: empty\u005cn\u0022, __func__);\n\t\treturn;\n\t}\n\n\tlachead \u003d (struct lwsac_head *)\u0026head[1];\n\n\tlwsl_debug(\u0022%s: lac %p: %dKiB in %d blocks\u005cn\u0022, __func__, head,\n\t\t (int)(lachead-\u003etotal_alloc_size \u003e\u003e 10), lachead-\u003etotal_blocks);\n#endif\n}\n\nuint64_t\nlwsac_total_alloc(struct lwsac *head)\n{\n\tstruct lwsac_head *lachead;\n\n\tif (!head)\n\t\treturn 0;\n\n\tlachead \u003d (struct lwsac_head *)\u0026head[1];\n\treturn lachead-\u003etotal_alloc_size;\n}\n\nvoid\nlwsac_reference(struct lwsac *head)\n{\n\tstruct lwsac_head *lachead \u003d (struct lwsac_head *)\u0026head[1];\n\n\tlachead-\u003erefcount++;\n\tlwsl_debug(\u0022%s: head %p: (det %d) refcount -\u003e %d\u005cn\u0022,\n\t\t __func__, head, lachead-\u003edetached, lachead-\u003erefcount);\n}\n\nvoid\nlwsac_unreference(struct lwsac **head)\n{\n\tstruct lwsac_head *lachead;\n\n\tif (!(*head))\n\t\treturn;\n\n\tlachead \u003d (struct lwsac_head *)\u0026(*head)[1];\n\n\tif (!lachead-\u003erefcount)\n\t\tlwsl_warn(\u0022%s: refcount going below zero\u005cn\u0022, __func__);\n\n\tlachead-\u003erefcount--;\n\n\tlwsl_debug(\u0022%s: head %p: (det %d) refcount -\u003e %d\u005cn\u0022,\n\t\t __func__, *head, lachead-\u003edetached, lachead-\u003erefcount);\n\n\tif (lachead-\u003edetached \u0026\u0026 !lachead-\u003erefcount) {\n\t\tlwsl_debug(\u0022%s: head %p: FREED\u005cn\u0022, __func__, *head);\n\t\tlwsac_free(head);\n\t}\n}\n\nvoid\nlwsac_detach(struct lwsac **head)\n{\n\tstruct lwsac_head *lachead;\n\n\tif (!(*head))\n\t\treturn;\n\n\tlachead \u003d (struct lwsac_head *)\u0026(*head)[1];\n\n\tlachead-\u003edetached \u003d 1;\n\tif (!lachead-\u003erefcount) {\n\t\tlwsl_debug(\u0022%s: head %p: FREED\u005cn\u0022, __func__, *head);\n\t\tlwsac_free(head);\n\t} else\n\t\tlwsl_debug(\u0022%s: head %p: refcount %d: Marked as detached\u005cn\u0022,\n\t\t\t __func__, *head, lachead-\u003erefcount);\n}\n","s":{"c":1713487123,"u": 289}} ],"g": 311,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 0, "si": 0, "db":0, "di":0, "sat":0, "lfc": "7d0a"}