| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 | 
							- /*
 
-  * libwebsockets - small server side websockets and web server implementation
 
-  *
 
-  * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
 
-  *
 
-  * 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.
 
-  */
 
- /** \defgroup lwsac lwsac
 
-  *
 
-  * ##Allocated Chunks
 
-  *
 
-  * If you know you will be allocating a large, unknown number of same or
 
-  * differently sized objects, it's certainly possible to do it with libc
 
-  * malloc.  However the allocation cost in time and memory overhead can
 
-  * add up, and deallocation means walking the structure of every object and
 
-  * freeing them in turn.
 
-  *
 
-  * lwsac (LWS Allocated Chunks) allocates chunks intended to be larger
 
-  * than your objects (4000 bytes by default) which you linearly allocate from
 
-  * using lwsac_use().
 
-  *
 
-  * If your next request won't fit in the current chunk, a new chunk is added
 
-  * to the chain of chunks and the allocaton done from there.  If the request
 
-  * is larger than the chunk size, an oversize chunk is created to satisfy it.
 
-  *
 
-  * When you are finished with the allocations, you call lwsac_free() and
 
-  * free all the *chunks*.  So you may have thousands of objects in the chunks,
 
-  * but they are all destroyed with the chunks without having to deallocate them
 
-  * one by one pointlessly.
 
-  */
 
- ///@{
 
- struct lwsac;
 
- typedef unsigned char * lwsac_cached_file_t;
 
- #define lws_list_ptr_container(P,T,M) ((T *)((char *)(P) - offsetof(T, M)))
 
- /*
 
-  * linked-list helper that's commonly useful to manage lists of things
 
-  * allocated using lwsac.
 
-  *
 
-  * These lists point to their corresponding "next" member in the target, NOT
 
-  * the original containing struct.  To get the containing struct, you must use
 
-  * lws_list_ptr_container() to convert.
 
-  *
 
-  * It's like that because it means we no longer have to have the next pointer
 
-  * at the start of the struct, and we can have the same struct on multiple
 
-  * linked-lists with everything held in the struct itself.
 
-  */
 
- typedef void * lws_list_ptr;
 
- /*
 
-  * optional sorting callback called by lws_list_ptr_insert() to sort the right
 
-  * things inside the opqaue struct being sorted / inserted on the list.
 
-  */
 
- typedef int (*lws_list_ptr_sort_func_t)(lws_list_ptr a, lws_list_ptr b);
 
- #define lws_list_ptr_advance(_lp) _lp = *((void **)_lp)
 
- /* sort may be NULL if you don't care about order */
 
- LWS_VISIBLE LWS_EXTERN void
 
- lws_list_ptr_insert(lws_list_ptr *phead, lws_list_ptr *add,
 
- 		    lws_list_ptr_sort_func_t sort);
 
- /**
 
-  * lwsac_use - allocate / use some memory from a lwsac
 
-  *
 
-  * \param head: pointer to the lwsac list object
 
-  * \param ensure: the number of bytes we want to use
 
-  * \param chunk_size: 0, or the size of the chunk to (over)allocate if
 
-  *			what we want won't fit in the current tail chunk.  If
 
-  *			0, the default value of 4000 is used. If ensure is
 
-  *			larger, it is used instead.
 
-  *
 
-  * This also serves to init the lwsac if *head is NULL.  Basically it does
 
-  * whatever is necessary to return you a pointer to ensure bytes of memory
 
-  * reserved for the caller.
 
-  *
 
-  * This always allocates in the current chunk or a new chunk... see the
 
-  * lwsac_use_backfill() variant to try first to find space in earlier chunks.
 
-  *
 
-  * Returns NULL if OOM.
 
-  */
 
- LWS_VISIBLE LWS_EXTERN void *
 
- lwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size);
 
- /**
 
-  * lwsac_use_backfill - allocate / use some memory from a lwsac
 
-  *
 
-  * \param head: pointer to the lwsac list object
 
-  * \param ensure: the number of bytes we want to use
 
-  * \param chunk_size: 0, or the size of the chunk to (over)allocate if
 
-  *			what we want won't fit in the current tail chunk.  If
 
-  *			0, the default value of 4000 is used. If ensure is
 
-  *			larger, it is used instead.
 
-  *
 
-  * This also serves to init the lwsac if *head is NULL.  Basically it does
 
-  * whatever is necessary to return you a pointer to ensure bytes of memory
 
-  * reserved for the caller.
 
-  *
 
-  * Also checks if earlier blocks have enough remaining space to take the
 
-  * allocation before making a new allocation.
 
-  *
 
-  * Returns NULL if OOM.
 
-  */
 
- LWS_VISIBLE LWS_EXTERN void *
 
- lwsac_use_backfill(struct lwsac **head, size_t ensure, size_t chunk_size);
 
- /**
 
-  * lwsac_use - allocate / use some memory from a lwsac
 
-  *
 
-  * \param head: pointer to the lwsac list object
 
-  * \param ensure: the number of bytes we want to use, which must be zeroed
 
-  * \param chunk_size: 0, or the size of the chunk to (over)allocate if
 
-  *			what we want won't fit in the current tail chunk.  If
 
-  *			0, the default value of 4000 is used. If ensure is
 
-  *			larger, it is used instead.
 
-  *
 
-  * Same as lwsac_use(), but \p ensure bytes of memory at the return address
 
-  * are zero'd before returning.
 
-  *
 
-  * Returns NULL if OOM.
 
-  */
 
- LWS_VISIBLE LWS_EXTERN void *
 
- lwsac_use_zero(struct lwsac **head, size_t ensure, size_t chunk_size);
 
- #define lwsac_use_zeroed lwsac_use_zero
 
- /**
 
-  * lwsac_free - deallocate all chunks in the lwsac and set head NULL
 
-  *
 
-  * \param head: pointer to the lwsac list object
 
-  *
 
-  * This deallocates all chunks in the lwsac, then sets *head to NULL.  All
 
-  * lwsac_use() pointers are invalidated in one hit without individual frees.
 
-  */
 
- LWS_VISIBLE LWS_EXTERN void
 
- lwsac_free(struct lwsac **head);
 
- /*
 
-  * Optional helpers useful for where consumers may need to defer destruction
 
-  * until all consumers are finished with the lwsac
 
-  */
 
- /**
 
-  * lwsac_detach() - destroy an lwsac unless somebody else is referencing it
 
-  *
 
-  * \param head: pointer to the lwsac list object
 
-  *
 
-  * The creator of the lwsac can all this instead of lwsac_free() when it itself
 
-  * has finished with the lwsac, but other code may be consuming it.
 
-  *
 
-  * If there are no other references, the lwsac is destroyed, *head is set to
 
-  * NULL and that's the end; however if something else has called
 
-  * lwsac_reference() on the lwsac, it simply returns.  When lws_unreference()
 
-  * is called and no references are left, it will be destroyed then.
 
-  */
 
- LWS_VISIBLE LWS_EXTERN void
 
- lwsac_detach(struct lwsac **head);
 
- /**
 
-  * lwsac_reference() - increase the lwsac reference count
 
-  *
 
-  * \param head: pointer to the lwsac list object
 
-  *
 
-  * Increment the reference count on the lwsac to defer destruction.
 
-  */
 
- LWS_VISIBLE LWS_EXTERN void
 
- lwsac_reference(struct lwsac *head);
 
- /**
 
-  * lwsac_unreference() - decrease the lwsac reference count
 
-  *
 
-  * \param head: pointer to the lwsac list object
 
-  *
 
-  * Decrement the reference count on the lwsac... if it reached 0 on a detached
 
-  * lwsac then the lwsac is immediately destroyed and *head set to NULL.
 
-  */
 
- LWS_VISIBLE LWS_EXTERN void
 
- lwsac_unreference(struct lwsac **head);
 
- /**
 
-  * lwsac_extend() - try to increase the size of the last block
 
-  *
 
-  * \param head: pointer to the lwsac list object
 
-  * \param amount: amount to try to increase usage for
 
-  *
 
-  * This will either increase the usage reservation of the last allocated block
 
-  * by amount and return 0, or fail and return 1.
 
-  *
 
-  * This is very cheap to call and is designed to optimize usage after a static
 
-  * struct for vari-sized additional content which may flow into an additional
 
-  * block in a new chunk if necessary, but wants to make the most of the space
 
-  * in front of it first to try to avoid gaps and the new chunk if it can.
 
-  *
 
-  * The additional area if the call succeeds will have been memset to 0.
 
-  *
 
-  * To use it, the following must be true:
 
-  *
 
-  * - only the last lwsac use can be extended
 
-  *
 
-  * - if another use happens inbetween the use and extend, it will break
 
-  *
 
-  * - the use cannot have been using backfill
 
-  *
 
-  * - a user object must be tracking the current allocated size of the last use
 
-  *   (lwsac doesn't know it) and increment by amount if the extend call succeeds
 
-  *
 
-  * Despite these restrictions this can be an important optimization for some
 
-  * cases
 
-  */
 
- LWS_VISIBLE LWS_EXTERN int
 
- lwsac_extend(struct lwsac *head, size_t amount);
 
- /* helpers to keep a file cached in memory */
 
- LWS_VISIBLE LWS_EXTERN void
 
- lwsac_use_cached_file_start(lwsac_cached_file_t cache);
 
- LWS_VISIBLE LWS_EXTERN void
 
- lwsac_use_cached_file_end(lwsac_cached_file_t *cache);
 
- LWS_VISIBLE LWS_EXTERN void
 
- lwsac_use_cached_file_detach(lwsac_cached_file_t *cache);
 
- LWS_VISIBLE LWS_EXTERN int
 
- lwsac_cached_file(const char *filepath, lwsac_cached_file_t *cache,
 
- 		  size_t *len);
 
- /* more advanced helpers */
 
- /* offset from lac to start of payload, first = 1 = first lac in chain */
 
- LWS_VISIBLE LWS_EXTERN size_t
 
- lwsac_sizeof(int first);
 
- LWS_VISIBLE LWS_EXTERN size_t
 
- lwsac_get_tail_pos(struct lwsac *lac);
 
- LWS_VISIBLE LWS_EXTERN struct lwsac *
 
- lwsac_get_next(struct lwsac *lac);
 
- LWS_VISIBLE LWS_EXTERN size_t
 
- lwsac_align(size_t length);
 
- LWS_VISIBLE LWS_EXTERN void
 
- lwsac_info(struct lwsac *head);
 
- LWS_VISIBLE LWS_EXTERN uint64_t
 
- lwsac_total_alloc(struct lwsac *head);
 
- LWS_VISIBLE LWS_EXTERN uint64_t
 
- lwsac_total_overhead(struct lwsac *head);
 
- /**
 
-  * lwsac_scan_extant() - returns existing copy of blob, or NULL
 
-  *
 
-  * \param head: the lwsac to scan
 
-  * \param find: the blob to look for
 
-  * \param len: the length of the blob to look for
 
-  * \param nul: nonzero if the next byte must be NUL
 
-  *
 
-  * Helper that looks through a whole lwsac for a given binary blob already
 
-  * present.  Used in the case that lwsac contents are const once written, and
 
-  * strings or blobs may be repeated in the input: this allows the earlier
 
-  * copy to be pointed to by subsequent references without repeating the string
 
-  * or blob redundantly.
 
-  */
 
- LWS_VISIBLE LWS_EXTERN uint8_t *
 
- lwsac_scan_extant(struct lwsac *head, uint8_t *find, size_t len, int nul);
 
- ///@}
 
 
  |