libwebsockets
Lightweight C library for HTML5 websockets
lwsac

Macros

#define lws_list_ptr_container(P, T, M)   ((T *)((char *)(P) - offsetof(T, M)))
 
#define lws_list_ptr_advance(_lp)   _lp = *((void **)_lp)
 
#define lwsac_use_zeroed   lwsac_use_zero
 

Typedefs

typedef unsigned char * lwsac_cached_file_t
 
typedef void * lws_list_ptr
 
typedef int(* lws_list_ptr_sort_func_t) (lws_list_ptr a, lws_list_ptr b)
 

Functions

LWS_VISIBLE LWS_EXTERN void lws_list_ptr_insert (lws_list_ptr *phead, lws_list_ptr *add, lws_list_ptr_sort_func_t sort)
 
LWS_VISIBLE LWS_EXTERN void * lwsac_use (struct lwsac **head, size_t ensure, size_t chunk_size)
 
LWS_VISIBLE LWS_EXTERN void * lwsac_use_backfill (struct lwsac **head, size_t ensure, size_t chunk_size)
 
LWS_VISIBLE LWS_EXTERN void * lwsac_use_zero (struct lwsac **head, size_t ensure, size_t chunk_size)
 
LWS_VISIBLE LWS_EXTERN void lwsac_free (struct lwsac **head)
 
LWS_VISIBLE LWS_EXTERN void lwsac_detach (struct lwsac **head)
 
LWS_VISIBLE LWS_EXTERN void lwsac_reference (struct lwsac *head)
 
LWS_VISIBLE LWS_EXTERN void lwsac_unreference (struct lwsac **head)
 
LWS_VISIBLE LWS_EXTERN int lwsac_extend (struct lwsac *head, size_t amount)
 
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)
 
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)
 
LWS_VISIBLE LWS_EXTERN uint8_tlwsac_scan_extant (struct lwsac *head, uint8_t *find, size_t len, int nul)
 

Detailed Description

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.

Macro Definition Documentation

◆ lws_list_ptr_container

#define lws_list_ptr_container (   P,
  T,
 
)    ((T *)((char *)(P) - offsetof(T, M)))

#include <include/libwebsockets/lws-lwsac.h>

Definition at line 54 of file lws-lwsac.h.

◆ lws_list_ptr_advance

#define lws_list_ptr_advance (   _lp)    _lp = *((void **)_lp)

#include <include/libwebsockets/lws-lwsac.h>

Definition at line 76 of file lws-lwsac.h.

◆ lwsac_use_zeroed

#define lwsac_use_zeroed   lwsac_use_zero

#include <include/libwebsockets/lws-lwsac.h>

Definition at line 146 of file lws-lwsac.h.

Typedef Documentation

◆ lwsac_cached_file_t

typedef unsigned char* lwsac_cached_file_t

#include <include/libwebsockets/lws-lwsac.h>

Definition at line 51 of file lws-lwsac.h.

◆ lws_list_ptr

typedef void* lws_list_ptr

#include <include/libwebsockets/lws-lwsac.h>

Definition at line 68 of file lws-lwsac.h.

◆ lws_list_ptr_sort_func_t

typedef int(* lws_list_ptr_sort_func_t) (lws_list_ptr a, lws_list_ptr b)

#include <include/libwebsockets/lws-lwsac.h>

Definition at line 74 of file lws-lwsac.h.

Function Documentation

◆ lws_list_ptr_insert()

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()

LWS_VISIBLE LWS_EXTERN void* lwsac_use ( struct lwsac **  head,
size_t  ensure,
size_t  chunk_size 
)

#include <include/libwebsockets/lws-lwsac.h>

lwsac_use - allocate / use some memory from a lwsac

Parameters
headpointer to the lwsac list object
ensurethe number of bytes we want to use
chunk_size0, 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.

◆ lwsac_use_backfill()

LWS_VISIBLE LWS_EXTERN void* lwsac_use_backfill ( struct lwsac **  head,
size_t  ensure,
size_t  chunk_size 
)

#include <include/libwebsockets/lws-lwsac.h>

lwsac_use_backfill - allocate / use some memory from a lwsac

Parameters
headpointer to the lwsac list object
ensurethe number of bytes we want to use
chunk_size0, 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.

◆ lwsac_use_zero()

LWS_VISIBLE LWS_EXTERN void* lwsac_use_zero ( struct lwsac **  head,
size_t  ensure,
size_t  chunk_size 
)

#include <include/libwebsockets/lws-lwsac.h>

lwsac_use - allocate / use some memory from a lwsac

Parameters
headpointer to the lwsac list object
ensurethe number of bytes we want to use, which must be zeroed
chunk_size0, 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 ensure bytes of memory at the return address are zero'd before returning.

Returns NULL if OOM.

◆ lwsac_free()

LWS_VISIBLE LWS_EXTERN void lwsac_free ( struct lwsac **  head)

#include <include/libwebsockets/lws-lwsac.h>

lwsac_free - deallocate all chunks in the lwsac and set head NULL

Parameters
headpointer 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.

◆ lwsac_detach()

LWS_VISIBLE LWS_EXTERN void lwsac_detach ( struct lwsac **  head)

#include <include/libwebsockets/lws-lwsac.h>

lwsac_detach() - destroy an lwsac unless somebody else is referencing it

Parameters
headpointer 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.

◆ lwsac_reference()

LWS_VISIBLE LWS_EXTERN void lwsac_reference ( struct lwsac *  head)

#include <include/libwebsockets/lws-lwsac.h>

lwsac_reference() - increase the lwsac reference count

Parameters
headpointer to the lwsac list object

Increment the reference count on the lwsac to defer destruction.

◆ lwsac_unreference()

LWS_VISIBLE LWS_EXTERN void lwsac_unreference ( struct lwsac **  head)

#include <include/libwebsockets/lws-lwsac.h>

lwsac_unreference() - decrease the lwsac reference count

Parameters
headpointer 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.

◆ lwsac_extend()

LWS_VISIBLE LWS_EXTERN int lwsac_extend ( struct lwsac *  head,
size_t  amount 
)

#include <include/libwebsockets/lws-lwsac.h>

lwsac_extend() - try to increase the size of the last block

Parameters
headpointer to the lwsac list object
amountamount 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

◆ lwsac_use_cached_file_start()

LWS_VISIBLE LWS_EXTERN void lwsac_use_cached_file_start ( lwsac_cached_file_t  cache)

◆ lwsac_use_cached_file_end()

LWS_VISIBLE LWS_EXTERN void lwsac_use_cached_file_end ( lwsac_cached_file_t cache)

◆ lwsac_use_cached_file_detach()

LWS_VISIBLE LWS_EXTERN void lwsac_use_cached_file_detach ( lwsac_cached_file_t cache)

◆ lwsac_cached_file()

LWS_VISIBLE LWS_EXTERN int lwsac_cached_file ( const char *  filepath,
lwsac_cached_file_t cache,
size_t *  len 
)

◆ lwsac_sizeof()

LWS_VISIBLE LWS_EXTERN size_t lwsac_sizeof ( int  first)

◆ lwsac_get_tail_pos()

LWS_VISIBLE LWS_EXTERN size_t lwsac_get_tail_pos ( struct lwsac *  lac)

◆ lwsac_get_next()

LWS_VISIBLE LWS_EXTERN struct lwsac* lwsac_get_next ( struct lwsac *  lac)

◆ lwsac_align()

LWS_VISIBLE LWS_EXTERN size_t lwsac_align ( size_t  length)

◆ lwsac_info()

LWS_VISIBLE LWS_EXTERN void lwsac_info ( struct lwsac *  head)

◆ lwsac_total_alloc()

LWS_VISIBLE LWS_EXTERN uint64_t lwsac_total_alloc ( struct lwsac *  head)

◆ lwsac_total_overhead()

LWS_VISIBLE LWS_EXTERN uint64_t lwsac_total_overhead ( struct lwsac *  head)

◆ lwsac_scan_extant()

LWS_VISIBLE LWS_EXTERN uint8_t* lwsac_scan_extant ( struct lwsac *  head,
uint8_t find,
size_t  len,
int  nul 
)

#include <include/libwebsockets/lws-lwsac.h>

lwsac_scan_extant() - returns existing copy of blob, or NULL

Parameters
headthe lwsac to scan
findthe blob to look for
lenthe length of the blob to look for
nulnonzero 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.