2 * libwebsockets - small server side websockets and web server implementation
4 * Copyright (C) 2010-2019 Andy Green <andy@warmcat.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation:
9 * version 2.1 of the License.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * included from libwebsockets.h
25 * lws_dsh (Disordered Shared Heap) is an opaque abstraction supporting a single
26 * linear buffer (overallocated at end of the lws_dsh_t) which may contain
27 * multiple kinds of packets that are retired out of order, and tracked by kind.
29 * Each kind of packet has an lws_dll2 list of its kind of packets and acts as
30 * a FIFO; packets of a particular type are always retired in order. But there
31 * is no requirement about the order types are retired matching the original
34 * Gaps are tracked as just another kind of "packet" list.
36 * "allocations" (including gaps) are prepended by an lws_dsh_object_t.
38 * dsh may themselves be on an lws_dll2_owner list, and under memory pressure
39 * allocate into other buffers on the list.
41 * All management structures exist inside the allocated buffer.
44 typedef struct lws_dsh lws_dsh_t;
47 * lws_dsh_create() - Allocate a DSH buffer
49 * \param owner: the owning list this dsh belongs on, or NULL if standalone
50 * \param buffer_size: the allocation in bytes
51 * \param count_kinds: how many separately-tracked fifos use the buffer
53 * This makes a single heap allocation that includes internal tracking objects
54 * in the buffer. Sub-allocated objects are bound to a "kind" index and
55 * managed via a FIFO for each kind.
57 * Every "kind" of allocation shares the same buffer space.
59 * Multiple buffers may be bound together in an lws_dll2 list, and if an
60 * allocation cannot be satisfied by the local buffer, space can be borrowed
61 * from other dsh in the same list (the local dsh FIFO tracks these "foreign"
62 * allocations as if they were local).
64 * Returns an opaque pointer to the dsh, or NULL if allocation failed.
66 LWS_VISIBLE LWS_EXTERN lws_dsh_t *
67 lws_dsh_create(lws_dll2_owner_t *owner, size_t buffer_size, int count_kinds);
70 * lws_dsh_destroy() - Destroy a DSH buffer
72 * \param pdsh: pointer to the dsh pointer
74 * Deallocates the DSH and sets *pdsh to NULL.
76 * Before destruction, any foreign buffer usage on the part of this dsh are
77 * individually freed. All dsh on the same list are walked and checked if they
78 * have their own foreign allocations on the dsh buffer being destroyed. If so,
79 * it attempts to migrate the allocation to a dsh that is not currently being
80 * destroyed. If all else fails (basically the buffer memory is being shrunk)
81 * unmigratable objects are cleanly destroyed.
83 LWS_VISIBLE LWS_EXTERN void
84 lws_dsh_destroy(lws_dsh_t **pdsh);
87 * lws_dsh_alloc_tail() - make a suballocation inside a dsh
89 * \param dsh: the dsh tracking the allocation
90 * \param kind: the kind of allocation
91 * \param src1: the first source data to copy
92 * \param size1: the size of the first source data
93 * \param src2: the second source data to copy (after the first), or NULL
94 * \param size2: the size of the second source data
96 * Allocates size1 + size2 bytes in a dsh (it prefers the given dsh but will
97 * borrow space from other dsh on the same list if necessary) and copies size1
98 * bytes into it from src1, followed by size2 bytes from src2 if src2 isn't
99 * NULL. The actual suballocation is a bit larger because of alignment and a
100 * prepended management header.
102 * The suballocation is added to the kind-specific FIFO at the tail.
104 LWS_VISIBLE LWS_EXTERN int
105 lws_dsh_alloc_tail(lws_dsh_t *dsh, int kind, const void *src1, size_t size1,
106 const void *src2, size_t size2);
109 * lws_dsh_free() - free a suballocation from the dsh
111 * \param obj: a pointer to a void * that pointed to the allocated payload
113 * This returns the space used by \p obj in the dsh buffer to the free list
114 * of the dsh the allocation came from.
116 LWS_VISIBLE LWS_EXTERN void
117 lws_dsh_free(void **obj);
120 * lws_dsh_get_head() - free a suballocation from the dsh
122 * \param dsh: the dsh tracking the allocation
123 * \param kind: the kind of allocation
124 * \param obj: pointer to a void * to be set to the payload
125 * \param size: set to the size of the allocation
127 * This gets the "next" object in the kind FIFO for the dsh, and returns 0 if
128 * any. If none, returns nonzero.
130 * This is nondestructive of the fifo or the payload. Use lws_dsh_free on
131 * obj to remove the entry from the kind fifo and return the payload to the
134 LWS_VISIBLE LWS_EXTERN int
135 lws_dsh_get_head(lws_dsh_t *dsh, int kind, void **obj, size_t *size);
138 * lws_dsh_describe() - DEBUG BUILDS ONLY dump the dsh to the logs
140 * \param dsh: the dsh to dump
141 * \param desc: text that appears at the top of the dump
143 * Useful information for debugging lws_dsh
145 LWS_VISIBLE LWS_EXTERN void
146 lws_dsh_describe(lws_dsh_t *dsh, const char *desc);