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