| /* | 
 |  * Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu> | 
 |  * All rights reserved. | 
 |  * | 
 |  * Redistribution and use in source and binary forms, with or without | 
 |  * modification, are permitted provided that the following conditions | 
 |  * are met: | 
 |  * 1. Redistributions of source code must retain the above copyright | 
 |  *    notice, this list of conditions and the following disclaimer. | 
 |  * 2. Redistributions in binary form must reproduce the above copyright | 
 |  *    notice, this list of conditions and the following disclaimer in the | 
 |  *    documentation and/or other materials provided with the distribution. | 
 |  * 3. The name of the author may not be used to endorse or promote products | 
 |  *    derived from this software without specific prior written permission. | 
 |  * | 
 |  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 
 |  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
 |  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 
 |  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 
 |  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 
 |  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
 |  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
 |  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
 |  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
 |  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
 |  */ | 
 | #ifndef _EVENT_H_ | 
 | #define _EVENT_H_ | 
 |  | 
 | /** @mainpage | 
 |  | 
 |   @section intro Introduction | 
 |  | 
 |   libevent is an event notification library for developing scalable network | 
 |   servers.  The libevent API provides a mechanism to execute a callback | 
 |   function when a specific event occurs on a file descriptor or after a | 
 |   timeout has been reached. Furthermore, libevent also support callbacks due | 
 |   to signals or regular timeouts. | 
 |  | 
 |   libevent is meant to replace the event loop found in event driven network | 
 |   servers. An application just needs to call event_dispatch() and then add or | 
 |   remove events dynamically without having to change the event loop. | 
 |  | 
 |   Currently, libevent supports /dev/poll, kqueue(2), select(2), poll(2) and | 
 |   epoll(4). It also has experimental support for real-time signals. The | 
 |   internal event mechanism is completely independent of the exposed event API, | 
 |   and a simple update of libevent can provide new functionality without having | 
 |   to redesign the applications. As a result, Libevent allows for portable | 
 |   application development and provides the most scalable event notification | 
 |   mechanism available on an operating system. Libevent can also be used for | 
 |   multi-threaded aplications; see Steven Grimm's explanation. Libevent should | 
 |   compile on Linux, *BSD, Mac OS X, Solaris and Windows. | 
 |  | 
 |   @section usage Standard usage | 
 |  | 
 |   Every program that uses libevent must include the <event.h> header, and pass | 
 |   the -levent flag to the linker.  Before using any of the functions in the | 
 |   library, you must call event_init() or event_base_new() to perform one-time | 
 |   initialization of the libevent library. | 
 |  | 
 |   @section event Event notification | 
 |  | 
 |   For each file descriptor that you wish to monitor, you must declare an event | 
 |   structure and call event_set() to initialize the members of the structure. | 
 |   To enable notification, you add the structure to the list of monitored | 
 |   events by calling event_add().  The event structure must remain allocated as | 
 |   long as it is active, so it should be allocated on the heap. Finally, you | 
 |   call event_dispatch() to loop and dispatch events. | 
 |  | 
 |   @section bufferevent I/O Buffers | 
 |  | 
 |   libevent provides an abstraction on top of the regular event callbacks. This | 
 |   abstraction is called a buffered event. A buffered event provides input and | 
 |   output buffers that get filled and drained automatically. The user of a | 
 |   buffered event no longer deals directly with the I/O, but instead is reading | 
 |   from input and writing to output buffers. | 
 |  | 
 |   Once initialized via bufferevent_new(), the bufferevent structure can be | 
 |   used repeatedly with bufferevent_enable() and bufferevent_disable(). | 
 |   Instead of reading and writing directly to a socket, you would call | 
 |   bufferevent_read() and bufferevent_write(). | 
 |  | 
 |   When read enabled the bufferevent will try to read from the file descriptor | 
 |   and call the read callback. The write callback is executed whenever the | 
 |   output buffer is drained below the write low watermark, which is 0 by | 
 |   default. | 
 |  | 
 |   @section timers Timers | 
 |  | 
 |   libevent can also be used to create timers that invoke a callback after a | 
 |   certain amount of time has expired. The evtimer_set() function prepares an | 
 |   event struct to be used as a timer. To activate the timer, call | 
 |   evtimer_add(). Timers can be deactivated by calling evtimer_del(). | 
 |  | 
 |   @section timeouts Timeouts | 
 |  | 
 |   In addition to simple timers, libevent can assign timeout events to file | 
 |   descriptors that are triggered whenever a certain amount of time has passed | 
 |   with no activity on a file descriptor.  The timeout_set() function | 
 |   initializes an event struct for use as a timeout. Once initialized, the | 
 |   event must be activated by using timeout_add().  To cancel the timeout, call | 
 |   timeout_del(). | 
 |  | 
 |   @section evdns Asynchronous DNS resolution | 
 |  | 
 |   libevent provides an asynchronous DNS resolver that should be used instead | 
 |   of the standard DNS resolver functions.  These functions can be imported by | 
 |   including the <evdns.h> header in your program. Before using any of the | 
 |   resolver functions, you must call evdns_init() to initialize the library. To | 
 |   convert a hostname to an IP address, you call the evdns_resolve_ipv4() | 
 |   function.  To perform a reverse lookup, you would call the | 
 |   evdns_resolve_reverse() function.  All of these functions use callbacks to | 
 |   avoid blocking while the lookup is performed. | 
 |  | 
 |   @section evhttp Event-driven HTTP servers | 
 |  | 
 |   libevent provides a very simple event-driven HTTP server that can be | 
 |   embedded in your program and used to service HTTP requests. | 
 |  | 
 |   To use this capability, you need to include the <evhttp.h> header in your | 
 |   program.  You create the server by calling evhttp_new(). Add addresses and | 
 |   ports to listen on with evhttp_bind_socket(). You then register one or more | 
 |   callbacks to handle incoming requests.  Each URI can be assigned a callback | 
 |   via the evhttp_set_cb() function.  A generic callback function can also be | 
 |   registered via evhttp_set_gencb(); this callback will be invoked if no other | 
 |   callbacks have been registered for a given URI. | 
 |  | 
 |   @section evrpc A framework for RPC servers and clients | 
 |   | 
 |   libevents provides a framework for creating RPC servers and clients.  It | 
 |   takes care of marshaling and unmarshaling all data structures. | 
 |  | 
 |   @section api API Reference | 
 |  | 
 |   To browse the complete documentation of the libevent API, click on any of | 
 |   the following links. | 
 |  | 
 |   event.h | 
 |   The primary libevent header | 
 |  | 
 |   evdns.h | 
 |   Asynchronous DNS resolution | 
 |  | 
 |   evhttp.h | 
 |   An embedded libevent-based HTTP server | 
 |  | 
 |   evrpc.h | 
 |   A framework for creating RPC servers and clients | 
 |  | 
 |  */ | 
 |  | 
 | /** @file event.h | 
 |  | 
 |   A library for writing event-driven network servers | 
 |  | 
 |  */ | 
 |  | 
 | #ifdef __cplusplus | 
 | extern "C" { | 
 | #endif | 
 |  | 
 | #include "event-config.h" | 
 | #ifdef _EVENT_HAVE_SYS_TYPES_H | 
 | #include <sys/types.h> | 
 | #endif | 
 | #ifdef _EVENT_HAVE_SYS_TIME_H | 
 | #include <sys/time.h> | 
 | #endif | 
 | #ifdef _EVENT_HAVE_STDINT_H | 
 | #include <stdint.h> | 
 | #endif | 
 | #include <stdarg.h> | 
 |  | 
 | /* For int types. */ | 
 | #include "evutil.h" | 
 |  | 
 | #ifdef WIN32 | 
 | #define WIN32_LEAN_AND_MEAN | 
 | #include <windows.h> | 
 | #undef WIN32_LEAN_AND_MEAN | 
 | typedef unsigned char u_char; | 
 | typedef unsigned short u_short; | 
 | #endif | 
 |  | 
 | #define EVLIST_TIMEOUT	0x01 | 
 | #define EVLIST_INSERTED	0x02 | 
 | #define EVLIST_SIGNAL	0x04 | 
 | #define EVLIST_ACTIVE	0x08 | 
 | #define EVLIST_INTERNAL	0x10 | 
 | #define EVLIST_INIT	0x80 | 
 |  | 
 | /* EVLIST_X_ Private space: 0x1000-0xf000 */ | 
 | #define EVLIST_ALL	(0xf000 | 0x9f) | 
 |  | 
 | #define EV_TIMEOUT	0x01 | 
 | #define EV_READ		0x02 | 
 | #define EV_WRITE	0x04 | 
 | #define EV_SIGNAL	0x08 | 
 | #define EV_PERSIST	0x10	/* Persistant event */ | 
 |  | 
 | /* Fix so that ppl dont have to run with <sys/queue.h> */ | 
 | #ifndef TAILQ_ENTRY | 
 | #define _EVENT_DEFINED_TQENTRY | 
 | #define TAILQ_ENTRY(type)						\ | 
 | struct {								\ | 
 | 	struct type *tqe_next;	/* next element */			\ | 
 | 	struct type **tqe_prev;	/* address of previous next element */	\ | 
 | } | 
 | #endif /* !TAILQ_ENTRY */ | 
 |  | 
 | struct event_base; | 
 | #ifndef EVENT_NO_STRUCT | 
 | struct event { | 
 | 	TAILQ_ENTRY (event) ev_next; | 
 | 	TAILQ_ENTRY (event) ev_active_next; | 
 | 	TAILQ_ENTRY (event) ev_signal_next; | 
 | 	unsigned int min_heap_idx;	/* for managing timeouts */ | 
 |  | 
 | 	struct event_base *ev_base; | 
 |  | 
 | 	int ev_fd; | 
 | 	short ev_events; | 
 | 	short ev_ncalls; | 
 | 	short *ev_pncalls;	/* Allows deletes in callback */ | 
 |  | 
 | 	struct timeval ev_timeout; | 
 |  | 
 | 	int ev_pri;		/* smaller numbers are higher priority */ | 
 |  | 
 | 	void (*ev_callback)(int, short, void *arg); | 
 | 	void *ev_arg; | 
 |  | 
 | 	int ev_res;		/* result passed to event callback */ | 
 | 	int ev_flags; | 
 | }; | 
 | #else | 
 | struct event; | 
 | #endif | 
 |  | 
 | #define EVENT_SIGNAL(ev)	(int)(ev)->ev_fd | 
 | #define EVENT_FD(ev)		(int)(ev)->ev_fd | 
 |  | 
 | /* | 
 |  * Key-Value pairs.  Can be used for HTTP headers but also for | 
 |  * query argument parsing. | 
 |  */ | 
 | struct evkeyval { | 
 | 	TAILQ_ENTRY(evkeyval) next; | 
 |  | 
 | 	char *key; | 
 | 	char *value; | 
 | }; | 
 |  | 
 | #ifdef _EVENT_DEFINED_TQENTRY | 
 | #undef TAILQ_ENTRY | 
 | struct event_list; | 
 | struct evkeyvalq; | 
 | #undef _EVENT_DEFINED_TQENTRY | 
 | #else | 
 | TAILQ_HEAD (event_list, event); | 
 | TAILQ_HEAD (evkeyvalq, evkeyval); | 
 | #endif /* _EVENT_DEFINED_TQENTRY */ | 
 |  | 
 | /** | 
 |   Initialize the event API. | 
 |  | 
 |   Use event_base_new() to initialize a new event base, but does not set | 
 |   the current_base global.   If using only event_base_new(), each event | 
 |   added must have an event base set with event_base_set() | 
 |  | 
 |   @see event_base_set(), event_base_free(), event_init() | 
 |  */ | 
 | struct event_base *event_base_new(void); | 
 |  | 
 | /** | 
 |   Initialize the event API. | 
 |  | 
 |   The event API needs to be initialized with event_init() before it can be | 
 |   used.  Sets the current_base global representing the default base for | 
 |   events that have no base associated with them. | 
 |  | 
 |   @see event_base_set(), event_base_new() | 
 |  */ | 
 | struct event_base *event_init(void); | 
 |  | 
 | /** | 
 |   Reinitialized the event base after a fork | 
 |  | 
 |   Some event mechanisms do not survive across fork.   The event base needs | 
 |   to be reinitialized with the event_reinit() function. | 
 |  | 
 |   @param base the event base that needs to be re-initialized | 
 |   @return 0 if successful, or -1 if some events could not be re-added. | 
 |   @see event_base_new(), event_init() | 
 | */ | 
 | int event_reinit(struct event_base *base); | 
 |  | 
 | /** | 
 |   Loop to process events. | 
 |  | 
 |   In order to process events, an application needs to call | 
 |   event_dispatch().  This function only returns on error, and should | 
 |   replace the event core of the application program. | 
 |  | 
 |   @see event_base_dispatch() | 
 |  */ | 
 | int event_dispatch(void); | 
 |  | 
 |  | 
 | /** | 
 |   Threadsafe event dispatching loop. | 
 |  | 
 |   @param eb the event_base structure returned by event_init() | 
 |   @see event_init(), event_dispatch() | 
 |  */ | 
 | int event_base_dispatch(struct event_base *); | 
 |  | 
 |  | 
 | /** | 
 |  Get the kernel event notification mechanism used by libevent. | 
 |   | 
 |  @param eb the event_base structure returned by event_base_new() | 
 |  @return a string identifying the kernel event mechanism (kqueue, epoll, etc.) | 
 |  */ | 
 | const char *event_base_get_method(struct event_base *); | 
 |          | 
 |          | 
 | /** | 
 |   Deallocate all memory associated with an event_base, and free the base. | 
 |  | 
 |   Note that this function will not close any fds or free any memory passed | 
 |   to event_set as the argument to callback. | 
 |  | 
 |   @param eb an event_base to be freed | 
 |  */ | 
 | void event_base_free(struct event_base *); | 
 |  | 
 |  | 
 | #define _EVENT_LOG_DEBUG 0 | 
 | #define _EVENT_LOG_MSG   1 | 
 | #define _EVENT_LOG_WARN  2 | 
 | #define _EVENT_LOG_ERR   3 | 
 | typedef void (*event_log_cb)(int severity, const char *msg); | 
 | /** | 
 |   Redirect libevent's log messages. | 
 |  | 
 |   @param cb a function taking two arguments: an integer severity between | 
 |      _EVENT_LOG_DEBUG and _EVENT_LOG_ERR, and a string.  If cb is NULL, | 
 | 	 then the default log is used. | 
 |   */ | 
 | void event_set_log_callback(event_log_cb cb); | 
 |  | 
 | /** | 
 |   Associate a different event base with an event. | 
 |  | 
 |   @param eb the event base | 
 |   @param ev the event | 
 |  */ | 
 | int event_base_set(struct event_base *, struct event *); | 
 |  | 
 | /** | 
 |  event_loop() flags | 
 |  */ | 
 | /*@{*/ | 
 | #define EVLOOP_ONCE	0x01	/**< Block at most once. */ | 
 | #define EVLOOP_NONBLOCK	0x02	/**< Do not block. */ | 
 | /*@}*/ | 
 |  | 
 | /** | 
 |   Handle events. | 
 |  | 
 |   This is a more flexible version of event_dispatch(). | 
 |  | 
 |   @param flags any combination of EVLOOP_ONCE | EVLOOP_NONBLOCK | 
 |   @return 0 if successful, -1 if an error occurred, or 1 if no events were | 
 |     registered. | 
 |   @see event_loopexit(), event_base_loop() | 
 | */ | 
 | int event_loop(int); | 
 |  | 
 | /** | 
 |   Handle events (threadsafe version). | 
 |  | 
 |   This is a more flexible version of event_base_dispatch(). | 
 |  | 
 |   @param eb the event_base structure returned by event_init() | 
 |   @param flags any combination of EVLOOP_ONCE | EVLOOP_NONBLOCK | 
 |   @return 0 if successful, -1 if an error occurred, or 1 if no events were | 
 |     registered. | 
 |   @see event_loopexit(), event_base_loop() | 
 |   */ | 
 | int event_base_loop(struct event_base *, int); | 
 |  | 
 | /** | 
 |   Exit the event loop after the specified time. | 
 |  | 
 |   The next event_loop() iteration after the given timer expires will | 
 |   complete normally (handling all queued events) then exit without | 
 |   blocking for events again. | 
 |  | 
 |   Subsequent invocations of event_loop() will proceed normally. | 
 |  | 
 |   @param tv the amount of time after which the loop should terminate. | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see event_loop(), event_base_loop(), event_base_loopexit() | 
 |   */ | 
 | int event_loopexit(const struct timeval *); | 
 |  | 
 |  | 
 | /** | 
 |   Exit the event loop after the specified time (threadsafe variant). | 
 |  | 
 |   The next event_base_loop() iteration after the given timer expires will | 
 |   complete normally (handling all queued events) then exit without | 
 |   blocking for events again. | 
 |  | 
 |   Subsequent invocations of event_base_loop() will proceed normally. | 
 |  | 
 |   @param eb the event_base structure returned by event_init() | 
 |   @param tv the amount of time after which the loop should terminate. | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see event_loopexit() | 
 |  */ | 
 | int event_base_loopexit(struct event_base *, const struct timeval *); | 
 |  | 
 | /** | 
 |   Abort the active event_loop() immediately. | 
 |  | 
 |   event_loop() will abort the loop after the next event is completed; | 
 |   event_loopbreak() is typically invoked from this event's callback. | 
 |   This behavior is analogous to the "break;" statement. | 
 |  | 
 |   Subsequent invocations of event_loop() will proceed normally. | 
 |  | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see event_base_loopbreak(), event_loopexit() | 
 |  */ | 
 | int event_loopbreak(void); | 
 |  | 
 | /** | 
 |   Abort the active event_base_loop() immediately. | 
 |  | 
 |   event_base_loop() will abort the loop after the next event is completed; | 
 |   event_base_loopbreak() is typically invoked from this event's callback. | 
 |   This behavior is analogous to the "break;" statement. | 
 |  | 
 |   Subsequent invocations of event_loop() will proceed normally. | 
 |  | 
 |   @param eb the event_base structure returned by event_init() | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see event_base_loopexit | 
 |  */ | 
 | int event_base_loopbreak(struct event_base *); | 
 |  | 
 |  | 
 | /** | 
 |   Add a timer event. | 
 |  | 
 |   @param ev the event struct | 
 |   @param tv timeval struct | 
 |  */ | 
 | #define evtimer_add(ev, tv)		event_add(ev, tv) | 
 |  | 
 |  | 
 | /** | 
 |   Define a timer event. | 
 |  | 
 |   @param ev event struct to be modified | 
 |   @param cb callback function | 
 |   @param arg argument that will be passed to the callback function | 
 |  */ | 
 | #define evtimer_set(ev, cb, arg)	event_set(ev, -1, 0, cb, arg) | 
 |  | 
 |  | 
 | /** | 
 |  * Delete a timer event. | 
 |  * | 
 |  * @param ev the event struct to be disabled | 
 |  */ | 
 | #define evtimer_del(ev)			event_del(ev) | 
 | #define evtimer_pending(ev, tv)		event_pending(ev, EV_TIMEOUT, tv) | 
 | #define evtimer_initialized(ev)		((ev)->ev_flags & EVLIST_INIT) | 
 |  | 
 | /** | 
 |  * Add a timeout event. | 
 |  * | 
 |  * @param ev the event struct to be disabled | 
 |  * @param tv the timeout value, in seconds | 
 |  */ | 
 | #define timeout_add(ev, tv)		event_add(ev, tv) | 
 |  | 
 |  | 
 | /** | 
 |  * Define a timeout event. | 
 |  * | 
 |  * @param ev the event struct to be defined | 
 |  * @param cb the callback to be invoked when the timeout expires | 
 |  * @param arg the argument to be passed to the callback | 
 |  */ | 
 | #define timeout_set(ev, cb, arg)	event_set(ev, -1, 0, cb, arg) | 
 |  | 
 |  | 
 | /** | 
 |  * Disable a timeout event. | 
 |  * | 
 |  * @param ev the timeout event to be disabled | 
 |  */ | 
 | #define timeout_del(ev)			event_del(ev) | 
 |  | 
 | #define timeout_pending(ev, tv)		event_pending(ev, EV_TIMEOUT, tv) | 
 | #define timeout_initialized(ev)		((ev)->ev_flags & EVLIST_INIT) | 
 |  | 
 | #define signal_add(ev, tv)		event_add(ev, tv) | 
 | #define signal_set(ev, x, cb, arg)	\ | 
 | 	event_set(ev, x, EV_SIGNAL|EV_PERSIST, cb, arg) | 
 | #define signal_del(ev)			event_del(ev) | 
 | #define signal_pending(ev, tv)		event_pending(ev, EV_SIGNAL, tv) | 
 | #define signal_initialized(ev)		((ev)->ev_flags & EVLIST_INIT) | 
 |  | 
 | /** | 
 |   Prepare an event structure to be added. | 
 |  | 
 |   The function event_set() prepares the event structure ev to be used in | 
 |   future calls to event_add() and event_del().  The event will be prepared to | 
 |   call the function specified by the fn argument with an int argument | 
 |   indicating the file descriptor, a short argument indicating the type of | 
 |   event, and a void * argument given in the arg argument.  The fd indicates | 
 |   the file descriptor that should be monitored for events.  The events can be | 
 |   either EV_READ, EV_WRITE, or both.  Indicating that an application can read | 
 |   or write from the file descriptor respectively without blocking. | 
 |  | 
 |   The function fn will be called with the file descriptor that triggered the | 
 |   event and the type of event which will be either EV_TIMEOUT, EV_SIGNAL, | 
 |   EV_READ, or EV_WRITE.  The additional flag EV_PERSIST makes an event_add() | 
 |   persistent until event_del() has been called. | 
 |  | 
 |   @param ev an event struct to be modified | 
 |   @param fd the file descriptor to be monitored | 
 |   @param event desired events to monitor; can be EV_READ and/or EV_WRITE | 
 |   @param fn callback function to be invoked when the event occurs | 
 |   @param arg an argument to be passed to the callback function | 
 |  | 
 |   @see event_add(), event_del(), event_once() | 
 |  | 
 |  */ | 
 | void event_set(struct event *, int, short, void (*)(int, short, void *), void *); | 
 |  | 
 | /** | 
 |   Schedule a one-time event to occur. | 
 |  | 
 |   The function event_once() is similar to event_set().  However, it schedules | 
 |   a callback to be called exactly once and does not require the caller to | 
 |   prepare an event structure. | 
 |  | 
 |   @param fd a file descriptor to monitor | 
 |   @param events event(s) to monitor; can be any of EV_TIMEOUT | EV_READ | | 
 |          EV_WRITE | 
 |   @param callback callback function to be invoked when the event occurs | 
 |   @param arg an argument to be passed to the callback function | 
 |   @param timeout the maximum amount of time to wait for the event, or NULL | 
 |          to wait forever | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see event_set() | 
 |  | 
 |  */ | 
 | int event_once(int, short, void (*)(int, short, void *), void *, | 
 |     const struct timeval *); | 
 |  | 
 |  | 
 | /** | 
 |   Schedule a one-time event (threadsafe variant) | 
 |  | 
 |   The function event_base_once() is similar to event_set().  However, it | 
 |   schedules a callback to be called exactly once and does not require the | 
 |   caller to prepare an event structure. | 
 |  | 
 |   @param base an event_base returned by event_init() | 
 |   @param fd a file descriptor to monitor | 
 |   @param events event(s) to monitor; can be any of EV_TIMEOUT | EV_READ | | 
 |          EV_WRITE | 
 |   @param callback callback function to be invoked when the event occurs | 
 |   @param arg an argument to be passed to the callback function | 
 |   @param timeout the maximum amount of time to wait for the event, or NULL | 
 |          to wait forever | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see event_once() | 
 |  */ | 
 | int event_base_once(struct event_base *base, int fd, short events, | 
 |     void (*callback)(int, short, void *), void *arg, | 
 |     const struct timeval *timeout); | 
 |  | 
 |  | 
 | /** | 
 |   Add an event to the set of monitored events. | 
 |  | 
 |   The function event_add() schedules the execution of the ev event when the | 
 |   event specified in event_set() occurs or in at least the time specified in | 
 |   the tv.  If tv is NULL, no timeout occurs and the function will only be | 
 |   called if a matching event occurs on the file descriptor.  The event in the | 
 |   ev argument must be already initialized by event_set() and may not be used | 
 |   in calls to event_set() until it has timed out or been removed with | 
 |   event_del().  If the event in the ev argument already has a scheduled | 
 |   timeout, the old timeout will be replaced by the new one. | 
 |  | 
 |   @param ev an event struct initialized via event_set() | 
 |   @param timeout the maximum amount of time to wait for the event, or NULL | 
 |          to wait forever | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see event_del(), event_set() | 
 |   */ | 
 | int event_add(struct event *ev, const struct timeval *timeout); | 
 |  | 
 |  | 
 | /** | 
 |   Remove an event from the set of monitored events. | 
 |  | 
 |   The function event_del() will cancel the event in the argument ev.  If the | 
 |   event has already executed or has never been added the call will have no | 
 |   effect. | 
 |  | 
 |   @param ev an event struct to be removed from the working set | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see event_add() | 
 |  */ | 
 | int event_del(struct event *); | 
 |  | 
 | void event_active(struct event *, int, short); | 
 |  | 
 |  | 
 | /** | 
 |   Checks if a specific event is pending or scheduled. | 
 |  | 
 |   @param ev an event struct previously passed to event_add() | 
 |   @param event the requested event type; any of EV_TIMEOUT|EV_READ| | 
 |          EV_WRITE|EV_SIGNAL | 
 |   @param tv an alternate timeout (FIXME - is this true?) | 
 |  | 
 |   @return 1 if the event is pending, or 0 if the event has not occurred | 
 |  | 
 |  */ | 
 | int event_pending(struct event *ev, short event, struct timeval *tv); | 
 |  | 
 |  | 
 | /** | 
 |   Test if an event structure has been initialized. | 
 |  | 
 |   The event_initialized() macro can be used to check if an event has been | 
 |   initialized. | 
 |  | 
 |   @param ev an event structure to be tested | 
 |   @return 1 if the structure has been initialized, or 0 if it has not been | 
 |           initialized | 
 |  */ | 
 | #ifdef WIN32 | 
 | #define event_initialized(ev)		((ev)->ev_flags & EVLIST_INIT && (ev)->ev_fd != (int)INVALID_HANDLE_VALUE) | 
 | #else | 
 | #define event_initialized(ev)		((ev)->ev_flags & EVLIST_INIT) | 
 | #endif | 
 |  | 
 |  | 
 | /** | 
 |   Get the libevent version number. | 
 |  | 
 |   @return a string containing the version number of libevent | 
 |  */ | 
 | const char *event_get_version(void); | 
 |  | 
 |  | 
 | /** | 
 |   Get the kernel event notification mechanism used by libevent. | 
 |  | 
 |   @return a string identifying the kernel event mechanism (kqueue, epoll, etc.) | 
 |  */ | 
 | const char *event_get_method(void); | 
 |  | 
 |  | 
 | /** | 
 |   Set the number of different event priorities. | 
 |  | 
 |   By default libevent schedules all active events with the same priority. | 
 |   However, some time it is desirable to process some events with a higher | 
 |   priority than others.  For that reason, libevent supports strict priority | 
 |   queues.  Active events with a lower priority are always processed before | 
 |   events with a higher priority. | 
 |  | 
 |   The number of different priorities can be set initially with the | 
 |   event_priority_init() function.  This function should be called before the | 
 |   first call to event_dispatch().  The event_priority_set() function can be | 
 |   used to assign a priority to an event.  By default, libevent assigns the | 
 |   middle priority to all events unless their priority is explicitly set. | 
 |  | 
 |   @param npriorities the maximum number of priorities | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see event_base_priority_init(), event_priority_set() | 
 |  | 
 |  */ | 
 | int	event_priority_init(int); | 
 |  | 
 |  | 
 | /** | 
 |   Set the number of different event priorities (threadsafe variant). | 
 |  | 
 |   See the description of event_priority_init() for more information. | 
 |  | 
 |   @param eb the event_base structure returned by event_init() | 
 |   @param npriorities the maximum number of priorities | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see event_priority_init(), event_priority_set() | 
 |  */ | 
 | int	event_base_priority_init(struct event_base *, int); | 
 |  | 
 |  | 
 | /** | 
 |   Assign a priority to an event. | 
 |  | 
 |   @param ev an event struct | 
 |   @param priority the new priority to be assigned | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see event_priority_init() | 
 |   */ | 
 | int	event_priority_set(struct event *, int); | 
 |  | 
 |  | 
 | /* These functions deal with buffering input and output */ | 
 |  | 
 | struct evbuffer { | 
 | 	u_char *buffer; | 
 | 	u_char *orig_buffer; | 
 |  | 
 | 	size_t misalign; | 
 | 	size_t totallen; | 
 | 	size_t off; | 
 |  | 
 | 	void (*cb)(struct evbuffer *, size_t, size_t, void *); | 
 | 	void *cbarg; | 
 | }; | 
 |  | 
 | /* Just for error reporting - use other constants otherwise */ | 
 | #define EVBUFFER_READ		0x01 | 
 | #define EVBUFFER_WRITE		0x02 | 
 | #define EVBUFFER_EOF		0x10 | 
 | #define EVBUFFER_ERROR		0x20 | 
 | #define EVBUFFER_TIMEOUT	0x40 | 
 |  | 
 | struct bufferevent; | 
 | typedef void (*evbuffercb)(struct bufferevent *, void *); | 
 | typedef void (*everrorcb)(struct bufferevent *, short what, void *); | 
 |  | 
 | struct event_watermark { | 
 | 	size_t low; | 
 | 	size_t high; | 
 | }; | 
 |  | 
 | #ifndef EVENT_NO_STRUCT | 
 | struct bufferevent { | 
 | 	struct event_base *ev_base; | 
 |  | 
 | 	struct event ev_read; | 
 | 	struct event ev_write; | 
 |  | 
 | 	struct evbuffer *input; | 
 | 	struct evbuffer *output; | 
 |  | 
 | 	struct event_watermark wm_read; | 
 | 	struct event_watermark wm_write; | 
 |  | 
 | 	evbuffercb readcb; | 
 | 	evbuffercb writecb; | 
 | 	everrorcb errorcb; | 
 | 	void *cbarg; | 
 |  | 
 | 	int timeout_read;	/* in seconds */ | 
 | 	int timeout_write;	/* in seconds */ | 
 |  | 
 | 	short enabled;	/* events that are currently enabled */ | 
 | }; | 
 | #endif | 
 |  | 
 | /** | 
 |   Create a new bufferevent. | 
 |  | 
 |   libevent provides an abstraction on top of the regular event callbacks. | 
 |   This abstraction is called a buffered event.  A buffered event provides | 
 |   input and output buffers that get filled and drained automatically.  The | 
 |   user of a buffered event no longer deals directly with the I/O, but | 
 |   instead is reading from input and writing to output buffers. | 
 |  | 
 |   Once initialized, the bufferevent structure can be used repeatedly with | 
 |   bufferevent_enable() and bufferevent_disable(). | 
 |  | 
 |   When read enabled the bufferevent will try to read from the file descriptor | 
 |   and call the read callback.  The write callback is executed whenever the | 
 |   output buffer is drained below the write low watermark, which is 0 by | 
 |   default. | 
 |  | 
 |   If multiple bases are in use, bufferevent_base_set() must be called before | 
 |   enabling the bufferevent for the first time. | 
 |  | 
 |   @param fd the file descriptor from which data is read and written to. | 
 |   		This file descriptor is not allowed to be a pipe(2). | 
 |   @param readcb callback to invoke when there is data to be read, or NULL if | 
 |          no callback is desired | 
 |   @param writecb callback to invoke when the file descriptor is ready for | 
 |          writing, or NULL if no callback is desired | 
 |   @param errorcb callback to invoke when there is an error on the file | 
 |          descriptor | 
 |   @param cbarg an argument that will be supplied to each of the callbacks | 
 |          (readcb, writecb, and errorcb) | 
 |   @return a pointer to a newly allocated bufferevent struct, or NULL if an | 
 |           error occurred | 
 |   @see bufferevent_base_set(), bufferevent_free() | 
 |   */ | 
 | struct bufferevent *bufferevent_new(int fd, | 
 |     evbuffercb readcb, evbuffercb writecb, everrorcb errorcb, void *cbarg); | 
 |  | 
 |  | 
 | /** | 
 |   Assign a bufferevent to a specific event_base. | 
 |  | 
 |   @param base an event_base returned by event_init() | 
 |   @param bufev a bufferevent struct returned by bufferevent_new() | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see bufferevent_new() | 
 |  */ | 
 | int bufferevent_base_set(struct event_base *base, struct bufferevent *bufev); | 
 |  | 
 |  | 
 | /** | 
 |   Assign a priority to a bufferevent. | 
 |  | 
 |   @param bufev a bufferevent struct | 
 |   @param pri the priority to be assigned | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   */ | 
 | int bufferevent_priority_set(struct bufferevent *bufev, int pri); | 
 |  | 
 |  | 
 | /** | 
 |   Deallocate the storage associated with a bufferevent structure. | 
 |  | 
 |   @param bufev the bufferevent structure to be freed. | 
 |   */ | 
 | void bufferevent_free(struct bufferevent *bufev); | 
 |  | 
 |  | 
 | /** | 
 |   Changes the callbacks for a bufferevent. | 
 |  | 
 |   @param bufev the bufferevent object for which to change callbacks | 
 |   @param readcb callback to invoke when there is data to be read, or NULL if | 
 |          no callback is desired | 
 |   @param writecb callback to invoke when the file descriptor is ready for | 
 |          writing, or NULL if no callback is desired | 
 |   @param errorcb callback to invoke when there is an error on the file | 
 |          descriptor | 
 |   @param cbarg an argument that will be supplied to each of the callbacks | 
 |          (readcb, writecb, and errorcb) | 
 |   @see bufferevent_new() | 
 |   */ | 
 | void bufferevent_setcb(struct bufferevent *bufev, | 
 |     evbuffercb readcb, evbuffercb writecb, everrorcb errorcb, void *cbarg); | 
 |  | 
 | /** | 
 |   Changes the file descriptor on which the bufferevent operates. | 
 |  | 
 |   @param bufev the bufferevent object for which to change the file descriptor | 
 |   @param fd the file descriptor to operate on | 
 | */ | 
 | void bufferevent_setfd(struct bufferevent *bufev, int fd); | 
 |  | 
 | /** | 
 |   Write data to a bufferevent buffer. | 
 |  | 
 |   The bufferevent_write() function can be used to write data to the file | 
 |   descriptor.  The data is appended to the output buffer and written to the | 
 |   descriptor automatically as it becomes available for writing. | 
 |  | 
 |   @param bufev the bufferevent to be written to | 
 |   @param data a pointer to the data to be written | 
 |   @param size the length of the data, in bytes | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see bufferevent_write_buffer() | 
 |   */ | 
 | int bufferevent_write(struct bufferevent *bufev, | 
 |     const void *data, size_t size); | 
 |  | 
 |  | 
 | /** | 
 |   Write data from an evbuffer to a bufferevent buffer.  The evbuffer is | 
 |   being drained as a result. | 
 |  | 
 |   @param bufev the bufferevent to be written to | 
 |   @param buf the evbuffer to be written | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see bufferevent_write() | 
 |  */ | 
 | int bufferevent_write_buffer(struct bufferevent *bufev, struct evbuffer *buf); | 
 |  | 
 |  | 
 | /** | 
 |   Read data from a bufferevent buffer. | 
 |  | 
 |   The bufferevent_read() function is used to read data from the input buffer. | 
 |  | 
 |   @param bufev the bufferevent to be read from | 
 |   @param data pointer to a buffer that will store the data | 
 |   @param size the size of the data buffer, in bytes | 
 |   @return the amount of data read, in bytes. | 
 |  */ | 
 | size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size); | 
 |  | 
 | /** | 
 |   Enable a bufferevent. | 
 |  | 
 |   @param bufev the bufferevent to be enabled | 
 |   @param event any combination of EV_READ | EV_WRITE. | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see bufferevent_disable() | 
 |  */ | 
 | int bufferevent_enable(struct bufferevent *bufev, short event); | 
 |  | 
 |  | 
 | /** | 
 |   Disable a bufferevent. | 
 |  | 
 |   @param bufev the bufferevent to be disabled | 
 |   @param event any combination of EV_READ | EV_WRITE. | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |   @see bufferevent_enable() | 
 |  */ | 
 | int bufferevent_disable(struct bufferevent *bufev, short event); | 
 |  | 
 |  | 
 | /** | 
 |   Set the read and write timeout for a buffered event. | 
 |  | 
 |   @param bufev the bufferevent to be modified | 
 |   @param timeout_read the read timeout | 
 |   @param timeout_write the write timeout | 
 |  */ | 
 | void bufferevent_settimeout(struct bufferevent *bufev, | 
 |     int timeout_read, int timeout_write); | 
 |  | 
 |  | 
 | /** | 
 |   Sets the watermarks for read and write events. | 
 |  | 
 |   On input, a bufferevent does not invoke the user read callback unless | 
 |   there is at least low watermark data in the buffer.   If the read buffer | 
 |   is beyond the high watermark, the buffevent stops reading from the network. | 
 |  | 
 |   On output, the user write callback is invoked whenever the buffered data | 
 |   falls below the low watermark. | 
 |  | 
 |   @param bufev the bufferevent to be modified | 
 |   @param events EV_READ, EV_WRITE or both | 
 |   @param lowmark the lower watermark to set | 
 |   @param highmark the high watermark to set | 
 | */ | 
 |  | 
 | void bufferevent_setwatermark(struct bufferevent *bufev, short events, | 
 |     size_t lowmark, size_t highmark); | 
 |  | 
 | #define EVBUFFER_LENGTH(x)	(x)->off | 
 | #define EVBUFFER_DATA(x)	(x)->buffer | 
 | #define EVBUFFER_INPUT(x)	(x)->input | 
 | #define EVBUFFER_OUTPUT(x)	(x)->output | 
 |  | 
 |  | 
 | /** | 
 |   Allocate storage for a new evbuffer. | 
 |  | 
 |   @return a pointer to a newly allocated evbuffer struct, or NULL if an error | 
 |           occurred | 
 |  */ | 
 | struct evbuffer *evbuffer_new(void); | 
 |  | 
 |  | 
 | /** | 
 |   Deallocate storage for an evbuffer. | 
 |  | 
 |   @param pointer to the evbuffer to be freed | 
 |  */ | 
 | void evbuffer_free(struct evbuffer *); | 
 |  | 
 |  | 
 | /** | 
 |   Expands the available space in an event buffer. | 
 |  | 
 |   Expands the available space in the event buffer to at least datlen | 
 |  | 
 |   @param buf the event buffer to be expanded | 
 |   @param datlen the new minimum length requirement | 
 |   @return 0 if successful, or -1 if an error occurred | 
 | */ | 
 | int evbuffer_expand(struct evbuffer *, size_t); | 
 |  | 
 |  | 
 | /** | 
 |   Append data to the end of an evbuffer. | 
 |  | 
 |   @param buf the event buffer to be appended to | 
 |   @param data pointer to the beginning of the data buffer | 
 |   @param datlen the number of bytes to be copied from the data buffer | 
 |  */ | 
 | int evbuffer_add(struct evbuffer *, const void *, size_t); | 
 |  | 
 |  | 
 |  | 
 | /** | 
 |   Read data from an event buffer and drain the bytes read. | 
 |  | 
 |   @param buf the event buffer to be read from | 
 |   @param data the destination buffer to store the result | 
 |   @param datlen the maximum size of the destination buffer | 
 |   @return the number of bytes read | 
 |  */ | 
 | int evbuffer_remove(struct evbuffer *, void *, size_t); | 
 |  | 
 |  | 
 | /** | 
 |  * Read a single line from an event buffer. | 
 |  * | 
 |  * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'. | 
 |  * The returned buffer needs to be freed by the caller. | 
 |  * | 
 |  * @param buffer the evbuffer to read from | 
 |  * @return pointer to a single line, or NULL if an error occurred | 
 |  */ | 
 | char *evbuffer_readline(struct evbuffer *); | 
 |  | 
 |  | 
 | /** Used to tell evbuffer_readln what kind of line-ending to look for. | 
 |  */ | 
 | enum evbuffer_eol_style { | 
 | 	/** Any sequence of CR and LF characters is acceptable as an EOL. */ | 
 | 	EVBUFFER_EOL_ANY, | 
 | 	/** An EOL is an LF, optionally preceded by a CR.  This style is | 
 | 	 * most useful for implementing text-based internet protocols. */ | 
 | 	EVBUFFER_EOL_CRLF, | 
 | 	/** An EOL is a CR followed by an LF. */ | 
 | 	EVBUFFER_EOL_CRLF_STRICT, | 
 | 	/** An EOL is a LF. */ | 
 |         EVBUFFER_EOL_LF | 
 | }; | 
 |  | 
 | /** | 
 |  * Read a single line from an event buffer. | 
 |  * | 
 |  * Reads a line terminated by an EOL as determined by the evbuffer_eol_style | 
 |  * argument.  Returns a newly allocated nul-terminated string; the caller must | 
 |  * free the returned value.  The EOL is not included in the returned string. | 
 |  * | 
 |  * @param buffer the evbuffer to read from | 
 |  * @param n_read_out if non-NULL, points to a size_t that is set to the | 
 |  *       number of characters in the returned string.  This is useful for | 
 |  *       strings that can contain NUL characters. | 
 |  * @param eol_style the style of line-ending to use. | 
 |  * @return pointer to a single line, or NULL if an error occurred | 
 |  */ | 
 | char *evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out, | 
 |     enum evbuffer_eol_style eol_style); | 
 |  | 
 |  | 
 | /** | 
 |   Move data from one evbuffer into another evbuffer. | 
 |  | 
 |   This is a destructive add.  The data from one buffer moves into | 
 |   the other buffer. The destination buffer is expanded as needed. | 
 |  | 
 |   @param outbuf the output buffer | 
 |   @param inbuf the input buffer | 
 |   @return 0 if successful, or -1 if an error occurred | 
 |  */ | 
 | int evbuffer_add_buffer(struct evbuffer *, struct evbuffer *); | 
 |  | 
 |  | 
 | /** | 
 |   Append a formatted string to the end of an evbuffer. | 
 |  | 
 |   @param buf the evbuffer that will be appended to | 
 |   @param fmt a format string | 
 |   @param ... arguments that will be passed to printf(3) | 
 |   @return The number of bytes added if successful, or -1 if an error occurred. | 
 |  */ | 
 | int evbuffer_add_printf(struct evbuffer *, const char *fmt, ...) | 
 | #ifdef __GNUC__ | 
 |   __attribute__((format(printf, 2, 3))) | 
 | #endif | 
 | ; | 
 |  | 
 |  | 
 | /** | 
 |   Append a va_list formatted string to the end of an evbuffer. | 
 |  | 
 |   @param buf the evbuffer that will be appended to | 
 |   @param fmt a format string | 
 |   @param ap a varargs va_list argument array that will be passed to vprintf(3) | 
 |   @return The number of bytes added if successful, or -1 if an error occurred. | 
 |  */ | 
 | int evbuffer_add_vprintf(struct evbuffer *, const char *fmt, va_list ap); | 
 |  | 
 |  | 
 | /** | 
 |   Remove a specified number of bytes data from the beginning of an evbuffer. | 
 |  | 
 |   @param buf the evbuffer to be drained | 
 |   @param len the number of bytes to drain from the beginning of the buffer | 
 |  */ | 
 | void evbuffer_drain(struct evbuffer *, size_t); | 
 |  | 
 |  | 
 | /** | 
 |   Write the contents of an evbuffer to a file descriptor. | 
 |  | 
 |   The evbuffer will be drained after the bytes have been successfully written. | 
 |  | 
 |   @param buffer the evbuffer to be written and drained | 
 |   @param fd the file descriptor to be written to | 
 |   @return the number of bytes written, or -1 if an error occurred | 
 |   @see evbuffer_read() | 
 |  */ | 
 | int evbuffer_write(struct evbuffer *, int); | 
 |  | 
 |  | 
 | /** | 
 |   Read from a file descriptor and store the result in an evbuffer. | 
 |  | 
 |   @param buf the evbuffer to store the result | 
 |   @param fd the file descriptor to read from | 
 |   @param howmuch the number of bytes to be read | 
 |   @return the number of bytes read, or -1 if an error occurred | 
 |   @see evbuffer_write() | 
 |  */ | 
 | int evbuffer_read(struct evbuffer *, int, int); | 
 |  | 
 |  | 
 | /** | 
 |   Find a string within an evbuffer. | 
 |  | 
 |   @param buffer the evbuffer to be searched | 
 |   @param what the string to be searched for | 
 |   @param len the length of the search string | 
 |   @return a pointer to the beginning of the search string, or NULL if the search failed. | 
 |  */ | 
 | u_char *evbuffer_find(struct evbuffer *, const u_char *, size_t); | 
 |  | 
 | /** | 
 |   Set a callback to invoke when the evbuffer is modified. | 
 |  | 
 |   @param buffer the evbuffer to be monitored | 
 |   @param cb the callback function to invoke when the evbuffer is modified | 
 |   @param cbarg an argument to be provided to the callback function | 
 |  */ | 
 | void evbuffer_setcb(struct evbuffer *, void (*)(struct evbuffer *, size_t, size_t, void *), void *); | 
 |  | 
 | /* | 
 |  * Marshaling tagged data - We assume that all tags are inserted in their | 
 |  * numeric order - so that unknown tags will always be higher than the | 
 |  * known ones - and we can just ignore the end of an event buffer. | 
 |  */ | 
 |  | 
 | void evtag_init(void); | 
 |  | 
 | void evtag_marshal(struct evbuffer *evbuf, ev_uint32_t tag, const void *data, | 
 |     ev_uint32_t len); | 
 |  | 
 | /** | 
 |   Encode an integer and store it in an evbuffer. | 
 |  | 
 |   We encode integer's by nibbles; the first nibble contains the number | 
 |   of significant nibbles - 1;  this allows us to encode up to 64-bit | 
 |   integers.  This function is byte-order independent. | 
 |  | 
 |   @param evbuf evbuffer to store the encoded number | 
 |   @param number a 32-bit integer | 
 |  */ | 
 | void encode_int(struct evbuffer *evbuf, ev_uint32_t number); | 
 |  | 
 | void evtag_marshal_int(struct evbuffer *evbuf, ev_uint32_t tag, | 
 |     ev_uint32_t integer); | 
 |  | 
 | void evtag_marshal_string(struct evbuffer *buf, ev_uint32_t tag, | 
 |     const char *string); | 
 |  | 
 | void evtag_marshal_timeval(struct evbuffer *evbuf, ev_uint32_t tag, | 
 |     struct timeval *tv); | 
 |  | 
 | int evtag_unmarshal(struct evbuffer *src, ev_uint32_t *ptag, | 
 |     struct evbuffer *dst); | 
 | int evtag_peek(struct evbuffer *evbuf, ev_uint32_t *ptag); | 
 | int evtag_peek_length(struct evbuffer *evbuf, ev_uint32_t *plength); | 
 | int evtag_payload_length(struct evbuffer *evbuf, ev_uint32_t *plength); | 
 | int evtag_consume(struct evbuffer *evbuf); | 
 |  | 
 | int evtag_unmarshal_int(struct evbuffer *evbuf, ev_uint32_t need_tag, | 
 |     ev_uint32_t *pinteger); | 
 |  | 
 | int evtag_unmarshal_fixed(struct evbuffer *src, ev_uint32_t need_tag, | 
 |     void *data, size_t len); | 
 |  | 
 | int evtag_unmarshal_string(struct evbuffer *evbuf, ev_uint32_t need_tag, | 
 |     char **pstring); | 
 |  | 
 | int evtag_unmarshal_timeval(struct evbuffer *evbuf, ev_uint32_t need_tag, | 
 |     struct timeval *ptv); | 
 |  | 
 | #ifdef __cplusplus | 
 | } | 
 | #endif | 
 |  | 
 | #endif /* _EVENT_H_ */ |