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