Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"en-US,en;q\u003d0.5", "gen_ut":1618125454, "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":"e297a6b7b6af32901e3e6ebc17067406", "oid":{ "oid": "24abd699f6a01315c4f5e0e216249ce21d54aabe", "alias": [ "refs/heads/main","refs/heads/master"]},"blobname": "include/libwebsockets/lws-lwsac.h", "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/** \u005cdefgroup lwsac lwsac\n *\n * ##Allocated Chunks\n *\n * If you know you will be allocating a large, unknown number of same or\n * differently sized objects, it's certainly possible to do it with libc\n * malloc. However the allocation cost in time and memory overhead can\n * add up, and deallocation means walking the structure of every object and\n * freeing them in turn.\n *\n * lwsac (LWS Allocated Chunks) allocates chunks intended to be larger\n * than your objects (4000 bytes by default) which you linearly allocate from\n * using lwsac_use().\n *\n * If your next request won't fit in the current chunk, a new chunk is added\n * to the chain of chunks and the allocaton done from there. If the request\n * is larger than the chunk size, an oversize chunk is created to satisfy it.\n *\n * When you are finished with the allocations, you call lwsac_free() and\n * free all the *chunks*. So you may have thousands of objects in the chunks,\n * but they are all destroyed with the chunks without having to deallocate them\n * one by one pointlessly.\n */\n///@{\n\nstruct lwsac;\ntypedef unsigned char * lwsac_cached_file_t;\n\n\n#define lws_list_ptr_container(P,T,M) ((T *)((char *)(P) - offsetof(T, M)))\n\n/*\n * linked-list helper that's commonly useful to manage lists of things\n * allocated using lwsac.\n *\n * These lists point to their corresponding \u0022next\u0022 member in the target, NOT\n * the original containing struct. To get the containing struct, you must use\n * lws_list_ptr_container() to convert.\n *\n * It's like that because it means we no longer have to have the next pointer\n * at the start of the struct, and we can have the same struct on multiple\n * linked-lists with everything held in the struct itself.\n */\ntypedef void * lws_list_ptr;\n\n/*\n * optional sorting callback called by lws_list_ptr_insert() to sort the right\n * things inside the opqaue struct being sorted / inserted on the list.\n */\ntypedef int (*lws_list_ptr_sort_func_t)(lws_list_ptr a, lws_list_ptr b);\n\n#define lws_list_ptr_advance(_lp) _lp \u003d *((void **)_lp)\n\n/* sort may be NULL if you don't care about order */\nLWS_VISIBLE LWS_EXTERN void\nlws_list_ptr_insert(lws_list_ptr *phead, lws_list_ptr *add,\n\t\t lws_list_ptr_sort_func_t sort);\n\n\n/**\n * lwsac_use - allocate / use some memory from a lwsac\n *\n * \u005cparam head: pointer to the lwsac list object\n * \u005cparam ensure: the number of bytes we want to use\n * \u005cparam chunk_size: 0, or the size of the chunk to (over)allocate if\n *\t\t\twhat we want won't fit in the current tail chunk. If\n *\t\t\t0, the default value of 4000 is used. If ensure is\n *\t\t\tlarger, it is used instead.\n *\n * This also serves to init the lwsac if *head is NULL. Basically it does\n * whatever is necessary to return you a pointer to ensure bytes of memory\n * reserved for the caller.\n *\n * This always allocates in the current chunk or a new chunk... see the\n * lwsac_use_backfill() variant to try first to find space in earlier chunks.\n *\n * Returns NULL if OOM.\n */\nLWS_VISIBLE LWS_EXTERN void *\nlwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size);\n\n/**\n * lwsac_use_backfill - allocate / use some memory from a lwsac\n *\n * \u005cparam head: pointer to the lwsac list object\n * \u005cparam ensure: the number of bytes we want to use\n * \u005cparam chunk_size: 0, or the size of the chunk to (over)allocate if\n *\t\t\twhat we want won't fit in the current tail chunk. If\n *\t\t\t0, the default value of 4000 is used. If ensure is\n *\t\t\tlarger, it is used instead.\n *\n * This also serves to init the lwsac if *head is NULL. Basically it does\n * whatever is necessary to return you a pointer to ensure bytes of memory\n * reserved for the caller.\n *\n * Also checks if earlier blocks have enough remaining space to take the\n * allocation before making a new allocation.\n *\n * Returns NULL if OOM.\n */\nLWS_VISIBLE LWS_EXTERN void *\nlwsac_use_backfill(struct lwsac **head, size_t ensure, size_t chunk_size);\n\n/**\n * lwsac_use - allocate / use some memory from a lwsac\n *\n * \u005cparam head: pointer to the lwsac list object\n * \u005cparam ensure: the number of bytes we want to use, which must be zeroed\n * \u005cparam chunk_size: 0, or the size of the chunk to (over)allocate if\n *\t\t\twhat we want won't fit in the current tail chunk. If\n *\t\t\t0, the default value of 4000 is used. If ensure is\n *\t\t\tlarger, it is used instead.\n *\n * Same as lwsac_use(), but \u005cp ensure bytes of memory at the return address\n * are zero'd before returning.\n *\n * Returns NULL if OOM.\n */\nLWS_VISIBLE LWS_EXTERN void *\nlwsac_use_zero(struct lwsac **head, size_t ensure, size_t chunk_size);\n\n#define lwsac_use_zeroed lwsac_use_zero\n\n/**\n * lwsac_free - deallocate all chunks in the lwsac and set head NULL\n *\n * \u005cparam head: pointer to the lwsac list object\n *\n * This deallocates all chunks in the lwsac, then sets *head to NULL. All\n * lwsac_use() pointers are invalidated in one hit without individual frees.\n */\nLWS_VISIBLE LWS_EXTERN void\nlwsac_free(struct lwsac **head);\n\n/*\n * Optional helpers useful for where consumers may need to defer destruction\n * until all consumers are finished with the lwsac\n */\n\n/**\n * lwsac_detach() - destroy an lwsac unless somebody else is referencing it\n *\n * \u005cparam head: pointer to the lwsac list object\n *\n * The creator of the lwsac can all this instead of lwsac_free() when it itself\n * has finished with the lwsac, but other code may be consuming it.\n *\n * If there are no other references, the lwsac is destroyed, *head is set to\n * NULL and that's the end; however if something else has called\n * lwsac_reference() on the lwsac, it simply returns. When lws_unreference()\n * is called and no references are left, it will be destroyed then.\n */\nLWS_VISIBLE LWS_EXTERN void\nlwsac_detach(struct lwsac **head);\n\n/**\n * lwsac_reference() - increase the lwsac reference count\n *\n * \u005cparam head: pointer to the lwsac list object\n *\n * Increment the reference count on the lwsac to defer destruction.\n */\nLWS_VISIBLE LWS_EXTERN void\nlwsac_reference(struct lwsac *head);\n\n/**\n * lwsac_unreference() - decrease the lwsac reference count\n *\n * \u005cparam head: pointer to the lwsac list object\n *\n * Decrement the reference count on the lwsac... if it reached 0 on a detached\n * lwsac then the lwsac is immediately destroyed and *head set to NULL.\n */\nLWS_VISIBLE LWS_EXTERN void\nlwsac_unreference(struct lwsac **head);\n\n/**\n * lwsac_extend() - try to increase the size of the last block\n *\n * \u005cparam head: pointer to the lwsac list object\n * \u005cparam amount: amount to try to increase usage for\n *\n * This will either increase the usage reservation of the last allocated block\n * by amount and return 0, or fail and return 1.\n *\n * This is very cheap to call and is designed to optimize usage after a static\n * struct for vari-sized additional content which may flow into an additional\n * block in a new chunk if necessary, but wants to make the most of the space\n * in front of it first to try to avoid gaps and the new chunk if it can.\n *\n * The additional area if the call succeeds will have been memset to 0.\n *\n * To use it, the following must be true:\n *\n * - only the last lwsac use can be extended\n *\n * - if another use happens inbetween the use and extend, it will break\n *\n * - the use cannot have been using backfill\n *\n * - a user object must be tracking the current allocated size of the last use\n * (lwsac doesn't know it) and increment by amount if the extend call succeeds\n *\n * Despite these restrictions this can be an important optimization for some\n * cases\n */\nLWS_VISIBLE LWS_EXTERN int\nlwsac_extend(struct lwsac *head, size_t amount);\n\n/* helpers to keep a file cached in memory */\n\nLWS_VISIBLE LWS_EXTERN void\nlwsac_use_cached_file_start(lwsac_cached_file_t cache);\n\nLWS_VISIBLE LWS_EXTERN void\nlwsac_use_cached_file_end(lwsac_cached_file_t *cache);\n\nLWS_VISIBLE LWS_EXTERN void\nlwsac_use_cached_file_detach(lwsac_cached_file_t *cache);\n\nLWS_VISIBLE LWS_EXTERN int\nlwsac_cached_file(const char *filepath, lwsac_cached_file_t *cache,\n\t\t size_t *len);\n\n/* more advanced helpers */\n\n/* offset from lac to start of payload, first \u003d 1 \u003d first lac in chain */\nLWS_VISIBLE LWS_EXTERN size_t\nlwsac_sizeof(int first);\n\nLWS_VISIBLE LWS_EXTERN size_t\nlwsac_get_tail_pos(struct lwsac *lac);\n\nLWS_VISIBLE LWS_EXTERN struct lwsac *\nlwsac_get_next(struct lwsac *lac);\n\nLWS_VISIBLE LWS_EXTERN size_t\nlwsac_align(size_t length);\n\nLWS_VISIBLE LWS_EXTERN void\nlwsac_info(struct lwsac *head);\n\nLWS_VISIBLE LWS_EXTERN uint64_t\nlwsac_total_alloc(struct lwsac *head);\n\nLWS_VISIBLE LWS_EXTERN uint64_t\nlwsac_total_overhead(struct lwsac *head);\n\n/**\n * lwsac_scan_extant() - returns existing copy of blob, or NULL\n *\n * \u005cparam head: the lwsac to scan\n * \u005cparam find: the blob to look for\n * \u005cparam len: the length of the blob to look for\n * \u005cparam nul: nonzero if the next byte must be NUL\n *\n * Helper that looks through a whole lwsac for a given binary blob already\n * present. Used in the case that lwsac contents are const once written, and\n * strings or blobs may be repeated in the input: this allows the earlier\n * copy to be pointed to by subsequent references without repeating the string\n * or blob redundantly.\n */\nLWS_VISIBLE LWS_EXTERN uint8_t *\nlwsac_scan_extant(struct lwsac *head, uint8_t *find, size_t len, int nul);\n\n///@}\n","s":{"c":1618125454,"u": 526}} ],"g": 4059,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 1, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}