1275970Scy/* 2275970Scy * Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu> 3275970Scy * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 4275970Scy * 5275970Scy * Redistribution and use in source and binary forms, with or without 6275970Scy * modification, are permitted provided that the following conditions 7275970Scy * are met: 8275970Scy * 1. Redistributions of source code must retain the above copyright 9275970Scy * notice, this list of conditions and the following disclaimer. 10275970Scy * 2. Redistributions in binary form must reproduce the above copyright 11275970Scy * notice, this list of conditions and the following disclaimer in the 12275970Scy * documentation and/or other materials provided with the distribution. 13275970Scy * 3. The name of the author may not be used to endorse or promote products 14275970Scy * derived from this software without specific prior written permission. 15275970Scy * 16275970Scy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17275970Scy * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18275970Scy * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19275970Scy * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20275970Scy * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21275970Scy * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22275970Scy * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23275970Scy * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24275970Scy * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25275970Scy * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26275970Scy */ 27275970Scy#ifndef EVBUFFER_INTERNAL_H_INCLUDED_ 28275970Scy#define EVBUFFER_INTERNAL_H_INCLUDED_ 29275970Scy 30275970Scy#ifdef __cplusplus 31275970Scyextern "C" { 32275970Scy#endif 33275970Scy 34275970Scy#include "event2/event-config.h" 35275970Scy#include "evconfig-private.h" 36275970Scy#include "event2/util.h" 37275970Scy#include "event2/event_struct.h" 38275970Scy#include "util-internal.h" 39275970Scy#include "defer-internal.h" 40275970Scy 41275970Scy/* Experimental cb flag: "never deferred." Implementation note: 42275970Scy * these callbacks may get an inaccurate view of n_del/n_added in their 43275970Scy * arguments. */ 44275970Scy#define EVBUFFER_CB_NODEFER 2 45275970Scy 46275970Scy#ifdef _WIN32 47275970Scy#include <winsock2.h> 48275970Scy#endif 49275970Scy#include <sys/queue.h> 50275970Scy 51275970Scy/* Minimum allocation for a chain. We define this so that we're burning no 52275970Scy * more than 5% of each allocation on overhead. It would be nice to lose even 53275970Scy * less space, though. */ 54275970Scy#if EVENT__SIZEOF_VOID_P < 8 55275970Scy#define MIN_BUFFER_SIZE 512 56275970Scy#else 57275970Scy#define MIN_BUFFER_SIZE 1024 58275970Scy#endif 59275970Scy 60275970Scy/** A single evbuffer callback for an evbuffer. This function will be invoked 61275970Scy * when bytes are added to or removed from the evbuffer. */ 62275970Scystruct evbuffer_cb_entry { 63275970Scy /** Structures to implement a doubly-linked queue of callbacks */ 64275970Scy LIST_ENTRY(evbuffer_cb_entry) next; 65275970Scy /** The callback function to invoke when this callback is called. 66275970Scy If EVBUFFER_CB_OBSOLETE is set in flags, the cb_obsolete field is 67275970Scy valid; otherwise, cb_func is valid. */ 68275970Scy union { 69275970Scy evbuffer_cb_func cb_func; 70275970Scy evbuffer_cb cb_obsolete; 71275970Scy } cb; 72275970Scy /** Argument to pass to cb. */ 73275970Scy void *cbarg; 74275970Scy /** Currently set flags on this callback. */ 75275970Scy ev_uint32_t flags; 76275970Scy}; 77275970Scy 78275970Scystruct bufferevent; 79275970Scystruct evbuffer_chain; 80275970Scystruct evbuffer { 81275970Scy /** The first chain in this buffer's linked list of chains. */ 82275970Scy struct evbuffer_chain *first; 83275970Scy /** The last chain in this buffer's linked list of chains. */ 84275970Scy struct evbuffer_chain *last; 85275970Scy 86275970Scy /** Pointer to the next pointer pointing at the 'last_with_data' chain. 87275970Scy * 88275970Scy * To unpack: 89275970Scy * 90275970Scy * The last_with_data chain is the last chain that has any data in it. 91275970Scy * If all chains in the buffer are empty, it is the first chain. 92275970Scy * If the buffer has no chains, it is NULL. 93275970Scy * 94275970Scy * The last_with_datap pointer points at _whatever 'next' pointer_ 95275970Scy * points at the last_with_datap chain. If the last_with_data chain 96275970Scy * is the first chain, or it is NULL, then the last_with_datap pointer 97275970Scy * is &buf->first. 98275970Scy */ 99275970Scy struct evbuffer_chain **last_with_datap; 100275970Scy 101275970Scy /** Total amount of bytes stored in all chains.*/ 102275970Scy size_t total_len; 103275970Scy 104275970Scy /** Number of bytes we have added to the buffer since we last tried to 105275970Scy * invoke callbacks. */ 106275970Scy size_t n_add_for_cb; 107275970Scy /** Number of bytes we have removed from the buffer since we last 108275970Scy * tried to invoke callbacks. */ 109275970Scy size_t n_del_for_cb; 110275970Scy 111275970Scy#ifndef EVENT__DISABLE_THREAD_SUPPORT 112275970Scy /** A lock used to mediate access to this buffer. */ 113275970Scy void *lock; 114275970Scy#endif 115275970Scy /** True iff we should free the lock field when we free this 116275970Scy * evbuffer. */ 117275970Scy unsigned own_lock : 1; 118275970Scy /** True iff we should not allow changes to the front of the buffer 119275970Scy * (drains or prepends). */ 120275970Scy unsigned freeze_start : 1; 121275970Scy /** True iff we should not allow changes to the end of the buffer 122275970Scy * (appends) */ 123275970Scy unsigned freeze_end : 1; 124275970Scy /** True iff this evbuffer's callbacks are not invoked immediately 125275970Scy * upon a change in the buffer, but instead are deferred to be invoked 126275970Scy * from the event_base's loop. Useful for preventing enormous stack 127275970Scy * overflows when we have mutually recursive callbacks, and for 128275970Scy * serializing callbacks in a single thread. */ 129275970Scy unsigned deferred_cbs : 1; 130275970Scy#ifdef _WIN32 131275970Scy /** True iff this buffer is set up for overlapped IO. */ 132275970Scy unsigned is_overlapped : 1; 133275970Scy#endif 134275970Scy /** Zero or more EVBUFFER_FLAG_* bits */ 135275970Scy ev_uint32_t flags; 136275970Scy 137275970Scy /** Used to implement deferred callbacks. */ 138275970Scy struct event_base *cb_queue; 139275970Scy 140275970Scy /** A reference count on this evbuffer. When the reference count 141275970Scy * reaches 0, the buffer is destroyed. Manipulated with 142275970Scy * evbuffer_incref and evbuffer_decref_and_unlock and 143275970Scy * evbuffer_free. */ 144275970Scy int refcnt; 145275970Scy 146275970Scy /** A struct event_callback handle to make all of this buffer's callbacks 147275970Scy * invoked from the event loop. */ 148275970Scy struct event_callback deferred; 149275970Scy 150275970Scy /** A doubly-linked-list of callback functions */ 151275970Scy LIST_HEAD(evbuffer_cb_queue, evbuffer_cb_entry) callbacks; 152275970Scy 153275970Scy /** The parent bufferevent object this evbuffer belongs to. 154275970Scy * NULL if the evbuffer stands alone. */ 155275970Scy struct bufferevent *parent; 156275970Scy}; 157275970Scy 158282408Scy#if EVENT__SIZEOF_OFF_T < EVENT__SIZEOF_SIZE_T 159282408Scytypedef ev_ssize_t ev_misalign_t; 160282408Scy#define EVBUFFER_CHAIN_MAX ((size_t)EV_SSIZE_MAX) 161282408Scy#else 162282408Scytypedef ev_off_t ev_misalign_t; 163282408Scy#if EVENT__SIZEOF_OFF_T > EVENT__SIZEOF_SIZE_T 164282408Scy#define EVBUFFER_CHAIN_MAX EV_SIZE_MAX 165282408Scy#else 166282408Scy#define EVBUFFER_CHAIN_MAX ((size_t)EV_SSIZE_MAX) 167282408Scy#endif 168282408Scy#endif 169282408Scy 170275970Scy/** A single item in an evbuffer. */ 171275970Scystruct evbuffer_chain { 172275970Scy /** points to next buffer in the chain */ 173275970Scy struct evbuffer_chain *next; 174275970Scy 175275970Scy /** total allocation available in the buffer field. */ 176275970Scy size_t buffer_len; 177275970Scy 178275970Scy /** unused space at the beginning of buffer or an offset into a 179275970Scy * file for sendfile buffers. */ 180282408Scy ev_misalign_t misalign; 181275970Scy 182275970Scy /** Offset into buffer + misalign at which to start writing. 183275970Scy * In other words, the total number of bytes actually stored 184275970Scy * in buffer. */ 185275970Scy size_t off; 186275970Scy 187275970Scy /** Set if special handling is required for this chain */ 188275970Scy unsigned flags; 189275970Scy#define EVBUFFER_FILESEGMENT 0x0001 /**< A chain used for a file segment */ 190275970Scy#define EVBUFFER_SENDFILE 0x0002 /**< a chain used with sendfile */ 191275970Scy#define EVBUFFER_REFERENCE 0x0004 /**< a chain with a mem reference */ 192275970Scy#define EVBUFFER_IMMUTABLE 0x0008 /**< read-only chain */ 193275970Scy /** a chain that mustn't be reallocated or freed, or have its contents 194275970Scy * memmoved, until the chain is un-pinned. */ 195275970Scy#define EVBUFFER_MEM_PINNED_R 0x0010 196275970Scy#define EVBUFFER_MEM_PINNED_W 0x0020 197275970Scy#define EVBUFFER_MEM_PINNED_ANY (EVBUFFER_MEM_PINNED_R|EVBUFFER_MEM_PINNED_W) 198275970Scy /** a chain that should be freed, but can't be freed until it is 199275970Scy * un-pinned. */ 200275970Scy#define EVBUFFER_DANGLING 0x0040 201275970Scy /** a chain that is a referenced copy of another chain */ 202275970Scy#define EVBUFFER_MULTICAST 0x0080 203275970Scy 204275970Scy /** number of references to this chain */ 205275970Scy int refcnt; 206275970Scy 207275970Scy /** Usually points to the read-write memory belonging to this 208275970Scy * buffer allocated as part of the evbuffer_chain allocation. 209275970Scy * For mmap, this can be a read-only buffer and 210275970Scy * EVBUFFER_IMMUTABLE will be set in flags. For sendfile, it 211275970Scy * may point to NULL. 212275970Scy */ 213275970Scy unsigned char *buffer; 214275970Scy}; 215275970Scy 216275970Scy/** callback for a reference chain; lets us know what to do with it when 217275970Scy * we're done with it. Lives at the end of an evbuffer_chain with the 218275970Scy * EVBUFFER_REFERENCE flag set */ 219275970Scystruct evbuffer_chain_reference { 220275970Scy evbuffer_ref_cleanup_cb cleanupfn; 221275970Scy void *extra; 222275970Scy}; 223275970Scy 224275970Scy/** File segment for a file-segment chain. Lives at the end of an 225275970Scy * evbuffer_chain with the EVBUFFER_FILESEGMENT flag set. */ 226275970Scystruct evbuffer_chain_file_segment { 227275970Scy struct evbuffer_file_segment *segment; 228275970Scy#ifdef _WIN32 229275970Scy /** If we're using CreateFileMapping, this is the handle to the view. */ 230275970Scy HANDLE view_handle; 231275970Scy#endif 232275970Scy}; 233275970Scy 234275970Scy/* Declared in event2/buffer.h; defined here. */ 235275970Scystruct evbuffer_file_segment { 236275970Scy void *lock; /**< lock prevent concurrent access to refcnt */ 237275970Scy int refcnt; /**< Reference count for this file segment */ 238275970Scy unsigned flags; /**< combination of EVBUF_FS_* flags */ 239275970Scy 240275970Scy /** What kind of file segment is this? */ 241275970Scy unsigned can_sendfile : 1; 242275970Scy unsigned is_mapping : 1; 243275970Scy 244275970Scy /** The fd that we read the data from. */ 245275970Scy int fd; 246275970Scy /** If we're using mmap, this is the raw mapped memory. */ 247275970Scy void *mapping; 248275970Scy#ifdef _WIN32 249275970Scy /** If we're using CreateFileMapping, this is the mapping */ 250275970Scy HANDLE mapping_handle; 251275970Scy#endif 252275970Scy /** If we're using mmap or IO, this is the content of the file 253275970Scy * segment. */ 254275970Scy char *contents; 255275970Scy /** Position of this segment within the file. */ 256275970Scy ev_off_t file_offset; 257275970Scy /** If we're using mmap, this is the offset within 'mapping' where 258275970Scy * this data segment begins. */ 259275970Scy ev_off_t mmap_offset; 260275970Scy /** The length of this segment. */ 261275970Scy ev_off_t length; 262275970Scy /** Cleanup callback function */ 263275970Scy evbuffer_file_segment_cleanup_cb cleanup_cb; 264275970Scy /** Argument to be pass to cleanup callback function */ 265275970Scy void *cleanup_cb_arg; 266275970Scy}; 267275970Scy 268275970Scy/** Information about the multicast parent of a chain. Lives at the 269275970Scy * end of an evbuffer_chain with the EVBUFFER_MULTICAST flag set. */ 270275970Scystruct evbuffer_multicast_parent { 271275970Scy /** source buffer the multicast parent belongs to */ 272275970Scy struct evbuffer *source; 273275970Scy /** multicast parent for this chain */ 274275970Scy struct evbuffer_chain *parent; 275275970Scy}; 276275970Scy 277275970Scy#define EVBUFFER_CHAIN_SIZE sizeof(struct evbuffer_chain) 278275970Scy/** Return a pointer to extra data allocated along with an evbuffer. */ 279275970Scy#define EVBUFFER_CHAIN_EXTRA(t, c) (t *)((struct evbuffer_chain *)(c) + 1) 280275970Scy 281275970Scy/** Assert that we are holding the lock on an evbuffer */ 282275970Scy#define ASSERT_EVBUFFER_LOCKED(buffer) \ 283275970Scy EVLOCK_ASSERT_LOCKED((buffer)->lock) 284275970Scy 285275970Scy#define EVBUFFER_LOCK(buffer) \ 286275970Scy do { \ 287275970Scy EVLOCK_LOCK((buffer)->lock, 0); \ 288275970Scy } while (0) 289275970Scy#define EVBUFFER_UNLOCK(buffer) \ 290275970Scy do { \ 291275970Scy EVLOCK_UNLOCK((buffer)->lock, 0); \ 292275970Scy } while (0) 293275970Scy#define EVBUFFER_LOCK2(buffer1, buffer2) \ 294275970Scy do { \ 295275970Scy EVLOCK_LOCK2((buffer1)->lock, (buffer2)->lock, 0, 0); \ 296275970Scy } while (0) 297275970Scy#define EVBUFFER_UNLOCK2(buffer1, buffer2) \ 298275970Scy do { \ 299275970Scy EVLOCK_UNLOCK2((buffer1)->lock, (buffer2)->lock, 0, 0); \ 300275970Scy } while (0) 301275970Scy 302275970Scy/** Increase the reference count of buf by one. */ 303275970Scyvoid evbuffer_incref_(struct evbuffer *buf); 304275970Scy/** Increase the reference count of buf by one and acquire the lock. */ 305275970Scyvoid evbuffer_incref_and_lock_(struct evbuffer *buf); 306275970Scy/** Pin a single buffer chain using a given flag. A pinned chunk may not be 307275970Scy * moved or freed until it is unpinned. */ 308275970Scyvoid evbuffer_chain_pin_(struct evbuffer_chain *chain, unsigned flag); 309275970Scy/** Unpin a single buffer chain using a given flag. */ 310275970Scyvoid evbuffer_chain_unpin_(struct evbuffer_chain *chain, unsigned flag); 311275970Scy/** As evbuffer_free, but requires that we hold a lock on the buffer, and 312275970Scy * releases the lock before freeing it and the buffer. */ 313275970Scyvoid evbuffer_decref_and_unlock_(struct evbuffer *buffer); 314275970Scy 315275970Scy/** As evbuffer_expand, but does not guarantee that the newly allocated memory 316275970Scy * is contiguous. Instead, it may be split across two or more chunks. */ 317275970Scyint evbuffer_expand_fast_(struct evbuffer *, size_t, int); 318275970Scy 319275970Scy/** Helper: prepares for a readv/WSARecv call by expanding the buffer to 320275970Scy * hold enough memory to read 'howmuch' bytes in possibly noncontiguous memory. 321275970Scy * Sets up the one or two iovecs in 'vecs' to point to the free memory and its 322275970Scy * extent, and *chainp to point to the first chain that we'll try to read into. 323275970Scy * Returns the number of vecs used. 324275970Scy */ 325275970Scyint evbuffer_read_setup_vecs_(struct evbuffer *buf, ev_ssize_t howmuch, 326275970Scy struct evbuffer_iovec *vecs, int n_vecs, struct evbuffer_chain ***chainp, 327275970Scy int exact); 328275970Scy 329275970Scy/* Helper macro: copies an evbuffer_iovec in ei to a win32 WSABUF in i. */ 330275970Scy#define WSABUF_FROM_EVBUFFER_IOV(i,ei) do { \ 331275970Scy (i)->buf = (ei)->iov_base; \ 332275970Scy (i)->len = (unsigned long)(ei)->iov_len; \ 333275970Scy } while (0) 334275970Scy/* XXXX the cast above is safe for now, but not if we allow mmaps on win64. 335275970Scy * See note in buffer_iocp's launch_write function */ 336275970Scy 337275970Scy/** Set the parent bufferevent object for buf to bev */ 338275970Scyvoid evbuffer_set_parent_(struct evbuffer *buf, struct bufferevent *bev); 339275970Scy 340275970Scyvoid evbuffer_invoke_callbacks_(struct evbuffer *buf); 341275970Scy 342275970Scy 343275970Scyint evbuffer_get_callbacks_(struct evbuffer *buffer, 344275970Scy struct event_callback **cbs, 345275970Scy int max_cbs); 346275970Scy 347275970Scy#ifdef __cplusplus 348275970Scy} 349275970Scy#endif 350275970Scy 351275970Scy#endif /* EVBUFFER_INTERNAL_H_INCLUDED_ */ 352