/bitcoin/depends/work/build/x86_64-pc-linux-gnu/libevent/2.1.12-stable-7656baec08e/evbuffer-internal.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu> |
3 | | * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson |
4 | | * |
5 | | * Redistribution and use in source and binary forms, with or without |
6 | | * modification, are permitted provided that the following conditions |
7 | | * are met: |
8 | | * 1. Redistributions of source code must retain the above copyright |
9 | | * notice, this list of conditions and the following disclaimer. |
10 | | * 2. Redistributions in binary form must reproduce the above copyright |
11 | | * notice, this list of conditions and the following disclaimer in the |
12 | | * documentation and/or other materials provided with the distribution. |
13 | | * 3. The name of the author may not be used to endorse or promote products |
14 | | * derived from this software without specific prior written permission. |
15 | | * |
16 | | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
17 | | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
21 | | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
22 | | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
23 | | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | | */ |
27 | | #ifndef EVBUFFER_INTERNAL_H_INCLUDED_ |
28 | | #define EVBUFFER_INTERNAL_H_INCLUDED_ |
29 | | |
30 | | #ifdef __cplusplus |
31 | | extern "C" { |
32 | | #endif |
33 | | |
34 | | #include "event2/event-config.h" |
35 | | #include "evconfig-private.h" |
36 | | #include "event2/util.h" |
37 | | #include "event2/event_struct.h" |
38 | | #include "util-internal.h" |
39 | | #include "defer-internal.h" |
40 | | |
41 | | /* Experimental cb flag: "never deferred." Implementation note: |
42 | | * these callbacks may get an inaccurate view of n_del/n_added in their |
43 | | * arguments. */ |
44 | 0 | #define EVBUFFER_CB_NODEFER 2 |
45 | | |
46 | | #ifdef _WIN32 |
47 | | #include <winsock2.h> |
48 | | #endif |
49 | | #include <sys/queue.h> |
50 | | |
51 | | /* Minimum allocation for a chain. We define this so that we're burning no |
52 | | * more than 5% of each allocation on overhead. It would be nice to lose even |
53 | | * less space, though. */ |
54 | | #if EVENT__SIZEOF_VOID_P < 8 |
55 | | #define MIN_BUFFER_SIZE 512 |
56 | | #else |
57 | 9.42M | #define MIN_BUFFER_SIZE 1024 |
58 | | #endif |
59 | | |
60 | | /** A single evbuffer callback for an evbuffer. This function will be invoked |
61 | | * when bytes are added to or removed from the evbuffer. */ |
62 | | struct evbuffer_cb_entry { |
63 | | /** Structures to implement a doubly-linked queue of callbacks */ |
64 | | LIST_ENTRY(evbuffer_cb_entry) next; |
65 | | /** The callback function to invoke when this callback is called. |
66 | | If EVBUFFER_CB_OBSOLETE is set in flags, the cb_obsolete field is |
67 | | valid; otherwise, cb_func is valid. */ |
68 | | union { |
69 | | evbuffer_cb_func cb_func; |
70 | | evbuffer_cb cb_obsolete; |
71 | | } cb; |
72 | | /** Argument to pass to cb. */ |
73 | | void *cbarg; |
74 | | /** Currently set flags on this callback. */ |
75 | | ev_uint32_t flags; |
76 | | }; |
77 | | |
78 | | struct bufferevent; |
79 | | struct evbuffer_chain; |
80 | | struct evbuffer { |
81 | | /** The first chain in this buffer's linked list of chains. */ |
82 | | struct evbuffer_chain *first; |
83 | | /** The last chain in this buffer's linked list of chains. */ |
84 | | struct evbuffer_chain *last; |
85 | | |
86 | | /** Pointer to the next pointer pointing at the 'last_with_data' chain. |
87 | | * |
88 | | * To unpack: |
89 | | * |
90 | | * The last_with_data chain is the last chain that has any data in it. |
91 | | * If all chains in the buffer are empty, it is the first chain. |
92 | | * If the buffer has no chains, it is NULL. |
93 | | * |
94 | | * The last_with_datap pointer points at _whatever 'next' pointer_ |
95 | | * pointing at the last_with_data chain. If the last_with_data chain |
96 | | * is the first chain, or it is NULL, then the last_with_datap pointer |
97 | | * is &buf->first. |
98 | | */ |
99 | | struct evbuffer_chain **last_with_datap; |
100 | | |
101 | | /** Total amount of bytes stored in all chains.*/ |
102 | | size_t total_len; |
103 | | |
104 | | /** Number of bytes we have added to the buffer since we last tried to |
105 | | * invoke callbacks. */ |
106 | | size_t n_add_for_cb; |
107 | | /** Number of bytes we have removed from the buffer since we last |
108 | | * tried to invoke callbacks. */ |
109 | | size_t n_del_for_cb; |
110 | | |
111 | | #ifndef EVENT__DISABLE_THREAD_SUPPORT |
112 | | /** A lock used to mediate access to this buffer. */ |
113 | | void *lock; |
114 | | #endif |
115 | | /** True iff we should free the lock field when we free this |
116 | | * evbuffer. */ |
117 | | unsigned own_lock : 1; |
118 | | /** True iff we should not allow changes to the front of the buffer |
119 | | * (drains or prepends). */ |
120 | | unsigned freeze_start : 1; |
121 | | /** True iff we should not allow changes to the end of the buffer |
122 | | * (appends) */ |
123 | | unsigned freeze_end : 1; |
124 | | /** True iff this evbuffer's callbacks are not invoked immediately |
125 | | * upon a change in the buffer, but instead are deferred to be invoked |
126 | | * from the event_base's loop. Useful for preventing enormous stack |
127 | | * overflows when we have mutually recursive callbacks, and for |
128 | | * serializing callbacks in a single thread. */ |
129 | | unsigned deferred_cbs : 1; |
130 | | #ifdef _WIN32 |
131 | | /** True iff this buffer is set up for overlapped IO. */ |
132 | | unsigned is_overlapped : 1; |
133 | | #endif |
134 | | /** Zero or more EVBUFFER_FLAG_* bits */ |
135 | | ev_uint32_t flags; |
136 | | |
137 | | /** Used to implement deferred callbacks. */ |
138 | | struct event_base *cb_queue; |
139 | | |
140 | | /** A reference count on this evbuffer. When the reference count |
141 | | * reaches 0, the buffer is destroyed. Manipulated with |
142 | | * evbuffer_incref and evbuffer_decref_and_unlock and |
143 | | * evbuffer_free. */ |
144 | | int refcnt; |
145 | | |
146 | | /** A struct event_callback handle to make all of this buffer's callbacks |
147 | | * invoked from the event loop. */ |
148 | | struct event_callback deferred; |
149 | | |
150 | | /** A doubly-linked-list of callback functions */ |
151 | | LIST_HEAD(evbuffer_cb_queue, evbuffer_cb_entry) callbacks; |
152 | | |
153 | | /** The parent bufferevent object this evbuffer belongs to. |
154 | | * NULL if the evbuffer stands alone. */ |
155 | | struct bufferevent *parent; |
156 | | }; |
157 | | |
158 | | #if EVENT__SIZEOF_OFF_T < EVENT__SIZEOF_SIZE_T |
159 | | typedef ev_ssize_t ev_misalign_t; |
160 | | #define EVBUFFER_CHAIN_MAX ((size_t)EV_SSIZE_MAX) |
161 | | #else |
162 | | typedef ev_off_t ev_misalign_t; |
163 | | #if EVENT__SIZEOF_OFF_T > EVENT__SIZEOF_SIZE_T |
164 | | #define EVBUFFER_CHAIN_MAX EV_SIZE_MAX |
165 | | #else |
166 | 49.5M | #define EVBUFFER_CHAIN_MAX ((size_t)EV_SSIZE_MAX) |
167 | | #endif |
168 | | #endif |
169 | | |
170 | | /** A single item in an evbuffer. */ |
171 | | struct evbuffer_chain { |
172 | | /** points to next buffer in the chain */ |
173 | | struct evbuffer_chain *next; |
174 | | |
175 | | /** total allocation available in the buffer field. */ |
176 | | size_t buffer_len; |
177 | | |
178 | | /** unused space at the beginning of buffer or an offset into a |
179 | | * file for sendfile buffers. */ |
180 | | ev_misalign_t misalign; |
181 | | |
182 | | /** Offset into buffer + misalign at which to start writing. |
183 | | * In other words, the total number of bytes actually stored |
184 | | * in buffer. */ |
185 | | size_t off; |
186 | | |
187 | | /** Set if special handling is required for this chain */ |
188 | | unsigned flags; |
189 | 9.42M | #define EVBUFFER_FILESEGMENT 0x0001 /**< A chain used for a file segment */ |
190 | 7.07M | #define EVBUFFER_SENDFILE 0x0002 /**< a chain used with sendfile */ |
191 | 9.42M | #define EVBUFFER_REFERENCE 0x0004 /**< a chain with a mem reference */ |
192 | 47.1M | #define EVBUFFER_IMMUTABLE 0x0008 /**< read-only chain */ |
193 | | /** a chain that mustn't be reallocated or freed, or have its contents |
194 | | * memmoved, until the chain is un-pinned. */ |
195 | 25.9M | #define EVBUFFER_MEM_PINNED_R 0x0010 |
196 | 16.5M | #define EVBUFFER_MEM_PINNED_W 0x0020 |
197 | 16.5M | #define EVBUFFER_MEM_PINNED_ANY (EVBUFFER_MEM_PINNED_R|EVBUFFER_MEM_PINNED_W) |
198 | | /** a chain that should be freed, but can't be freed until it is |
199 | | * un-pinned. */ |
200 | 0 | #define EVBUFFER_DANGLING 0x0040 |
201 | | /** a chain that is a referenced copy of another chain */ |
202 | 9.42M | #define EVBUFFER_MULTICAST 0x0080 |
203 | | |
204 | | /** number of references to this chain */ |
205 | | int refcnt; |
206 | | |
207 | | /** Usually points to the read-write memory belonging to this |
208 | | * buffer allocated as part of the evbuffer_chain allocation. |
209 | | * For mmap, this can be a read-only buffer and |
210 | | * EVBUFFER_IMMUTABLE will be set in flags. For sendfile, it |
211 | | * may point to NULL. |
212 | | */ |
213 | | unsigned char *buffer; |
214 | | }; |
215 | | |
216 | | /** callback for a reference chain; lets us know what to do with it when |
217 | | * we're done with it. Lives at the end of an evbuffer_chain with the |
218 | | * EVBUFFER_REFERENCE flag set */ |
219 | | struct evbuffer_chain_reference { |
220 | | evbuffer_ref_cleanup_cb cleanupfn; |
221 | | void *extra; |
222 | | }; |
223 | | |
224 | | /** File segment for a file-segment chain. Lives at the end of an |
225 | | * evbuffer_chain with the EVBUFFER_FILESEGMENT flag set. */ |
226 | | struct evbuffer_chain_file_segment { |
227 | | struct evbuffer_file_segment *segment; |
228 | | #ifdef _WIN32 |
229 | | /** If we're using CreateFileMapping, this is the handle to the view. */ |
230 | | HANDLE view_handle; |
231 | | #endif |
232 | | }; |
233 | | |
234 | | /* Declared in event2/buffer.h; defined here. */ |
235 | | struct evbuffer_file_segment { |
236 | | void *lock; /**< lock prevent concurrent access to refcnt */ |
237 | | int refcnt; /**< Reference count for this file segment */ |
238 | | unsigned flags; /**< combination of EVBUF_FS_* flags */ |
239 | | |
240 | | /** What kind of file segment is this? */ |
241 | | unsigned can_sendfile : 1; |
242 | | unsigned is_mapping : 1; |
243 | | |
244 | | /** The fd that we read the data from. */ |
245 | | int fd; |
246 | | /** If we're using mmap, this is the raw mapped memory. */ |
247 | | void *mapping; |
248 | | #ifdef _WIN32 |
249 | | /** If we're using CreateFileMapping, this is the mapping */ |
250 | | HANDLE mapping_handle; |
251 | | #endif |
252 | | /** If we're using mmap or IO, this is the content of the file |
253 | | * segment. */ |
254 | | char *contents; |
255 | | /** Position of this segment within the file. */ |
256 | | ev_off_t file_offset; |
257 | | /** If we're using mmap, this is the offset within 'mapping' where |
258 | | * this data segment begins. */ |
259 | | ev_off_t mmap_offset; |
260 | | /** The length of this segment. */ |
261 | | ev_off_t length; |
262 | | /** Cleanup callback function */ |
263 | | evbuffer_file_segment_cleanup_cb cleanup_cb; |
264 | | /** Argument to be pass to cleanup callback function */ |
265 | | void *cleanup_cb_arg; |
266 | | }; |
267 | | |
268 | | /** Information about the multicast parent of a chain. Lives at the |
269 | | * end of an evbuffer_chain with the EVBUFFER_MULTICAST flag set. */ |
270 | | struct evbuffer_multicast_parent { |
271 | | /** source buffer the multicast parent belongs to */ |
272 | | struct evbuffer *source; |
273 | | /** multicast parent for this chain */ |
274 | | struct evbuffer_chain *parent; |
275 | | }; |
276 | | |
277 | 37.6M | #define EVBUFFER_CHAIN_SIZE sizeof(struct evbuffer_chain) |
278 | | /** Return a pointer to extra data allocated along with an evbuffer. */ |
279 | 9.42M | #define EVBUFFER_CHAIN_EXTRA(t, c) (t *)((struct evbuffer_chain *)(c) + 1) |
280 | | |
281 | | /** Assert that we are holding the lock on an evbuffer */ |
282 | | #define ASSERT_EVBUFFER_LOCKED(buffer) \ |
283 | 99.0M | EVLOCK_ASSERT_LOCKED((buffer)->lock) |
284 | | |
285 | | #define EVBUFFER_LOCK(buffer) \ |
286 | 191M | do { \ |
287 | 191M | EVLOCK_LOCK((buffer)->lock, 0); \ |
288 | 191M | } while (0) |
289 | | #define EVBUFFER_UNLOCK(buffer) \ |
290 | 191M | do { \ |
291 | 191M | EVLOCK_UNLOCK((buffer)->lock, 0); \ |
292 | 191M | } while (0) |
293 | | #define EVBUFFER_LOCK2(buffer1, buffer2) \ |
294 | 7.07M | do { \ |
295 | 7.07M | EVLOCK_LOCK2((buffer1)->lock, (buffer2)->lock, 0, 0); \ |
296 | 7.07M | } while (0) |
297 | | #define EVBUFFER_UNLOCK2(buffer1, buffer2) \ |
298 | 7.07M | do { \ |
299 | 7.07M | EVLOCK_UNLOCK2((buffer1)->lock, (buffer2)->lock, 0, 0); \ |
300 | 7.07M | } while (0) |
301 | | |
302 | | /** Increase the reference count of buf by one. */ |
303 | | void evbuffer_incref_(struct evbuffer *buf); |
304 | | /** Increase the reference count of buf by one and acquire the lock. */ |
305 | | void evbuffer_incref_and_lock_(struct evbuffer *buf); |
306 | | /** Pin a single buffer chain using a given flag. A pinned chunk may not be |
307 | | * moved or freed until it is unpinned. */ |
308 | | void evbuffer_chain_pin_(struct evbuffer_chain *chain, unsigned flag); |
309 | | /** Unpin a single buffer chain using a given flag. */ |
310 | | void evbuffer_chain_unpin_(struct evbuffer_chain *chain, unsigned flag); |
311 | | /** As evbuffer_free, but requires that we hold a lock on the buffer, and |
312 | | * releases the lock before freeing it and the buffer. */ |
313 | | void evbuffer_decref_and_unlock_(struct evbuffer *buffer); |
314 | | |
315 | | /** As evbuffer_expand, but does not guarantee that the newly allocated memory |
316 | | * is contiguous. Instead, it may be split across two or more chunks. */ |
317 | | int evbuffer_expand_fast_(struct evbuffer *, size_t, int); |
318 | | |
319 | | /** Helper: prepares for a readv/WSARecv call by expanding the buffer to |
320 | | * hold enough memory to read 'howmuch' bytes in possibly noncontiguous memory. |
321 | | * Sets up the one or two iovecs in 'vecs' to point to the free memory and its |
322 | | * extent, and *chainp to point to the first chain that we'll try to read into. |
323 | | * Returns the number of vecs used. |
324 | | */ |
325 | | int evbuffer_read_setup_vecs_(struct evbuffer *buf, ev_ssize_t howmuch, |
326 | | struct evbuffer_iovec *vecs, int n_vecs, struct evbuffer_chain ***chainp, |
327 | | int exact); |
328 | | |
329 | | /* Helper macro: copies an evbuffer_iovec in ei to a win32 WSABUF in i. */ |
330 | | #define WSABUF_FROM_EVBUFFER_IOV(i,ei) do { \ |
331 | | (i)->buf = (ei)->iov_base; \ |
332 | | (i)->len = (unsigned long)(ei)->iov_len; \ |
333 | | } while (0) |
334 | | /* XXXX the cast above is safe for now, but not if we allow mmaps on win64. |
335 | | * See note in buffer_iocp's launch_write function */ |
336 | | |
337 | | /** Set the parent bufferevent object for buf to bev */ |
338 | | void evbuffer_set_parent_(struct evbuffer *buf, struct bufferevent *bev); |
339 | | |
340 | | void evbuffer_invoke_callbacks_(struct evbuffer *buf); |
341 | | |
342 | | |
343 | | int evbuffer_get_callbacks_(struct evbuffer *buffer, |
344 | | struct event_callback **cbs, |
345 | | int max_cbs); |
346 | | |
347 | | #ifdef __cplusplus |
348 | | } |
349 | | #endif |
350 | | |
351 | | #endif /* EVBUFFER_INTERNAL_H_INCLUDED_ */ |