1171169Smlaier/* 2171169Smlaier * Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu> 3171169Smlaier * All rights reserved. 4171169Smlaier * 5171169Smlaier * Redistribution and use in source and binary forms, with or without 6171169Smlaier * modification, are permitted provided that the following conditions 7171169Smlaier * are met: 8171169Smlaier * 1. Redistributions of source code must retain the above copyright 9171169Smlaier * notice, this list of conditions and the following disclaimer. 10171169Smlaier * 2. Redistributions in binary form must reproduce the above copyright 11171169Smlaier * notice, this list of conditions and the following disclaimer in the 12171169Smlaier * documentation and/or other materials provided with the distribution. 13171169Smlaier * 3. The name of the author may not be used to endorse or promote products 14171169Smlaier * derived from this software without specific prior written permission. 15171169Smlaier * 16171169Smlaier * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17171169Smlaier * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18171169Smlaier * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19171169Smlaier * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20171169Smlaier * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21171169Smlaier * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22171169Smlaier * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23171169Smlaier * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24171169Smlaier * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25171169Smlaier * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26171169Smlaier */ 27171169Smlaier#ifndef _EVENT_H_ 28171169Smlaier#define _EVENT_H_ 29171169Smlaier 30171169Smlaier#ifdef __cplusplus 31171169Smlaierextern "C" { 32171169Smlaier#endif 33171169Smlaier 34171169Smlaier#include <stdarg.h> 35171169Smlaier 36171169Smlaier#ifdef WIN32 37171169Smlaier#define WIN32_LEAN_AND_MEAN 38171169Smlaier#include <windows.h> 39171169Smlaier#undef WIN32_LEAN_AND_MEAN 40171169Smlaiertypedef unsigned char u_char; 41171169Smlaiertypedef unsigned short u_short; 42171169Smlaier#endif 43171169Smlaier 44171169Smlaier#define EVLIST_TIMEOUT 0x01 45171169Smlaier#define EVLIST_INSERTED 0x02 46171169Smlaier#define EVLIST_SIGNAL 0x04 47171169Smlaier#define EVLIST_ACTIVE 0x08 48171169Smlaier#define EVLIST_INTERNAL 0x10 49171169Smlaier#define EVLIST_INIT 0x80 50171169Smlaier 51171169Smlaier/* EVLIST_X_ Private space: 0x1000-0xf000 */ 52171169Smlaier#define EVLIST_ALL (0xf000 | 0x9f) 53171169Smlaier 54171169Smlaier#define EV_TIMEOUT 0x01 55171169Smlaier#define EV_READ 0x02 56171169Smlaier#define EV_WRITE 0x04 57171169Smlaier#define EV_SIGNAL 0x08 58171169Smlaier#define EV_PERSIST 0x10 /* Persistant event */ 59171169Smlaier 60171169Smlaier/* Fix so that ppl dont have to run with <sys/queue.h> */ 61171169Smlaier#ifndef TAILQ_ENTRY 62171169Smlaier#define _EVENT_DEFINED_TQENTRY 63171169Smlaier#define TAILQ_ENTRY(type) \ 64171169Smlaierstruct { \ 65171169Smlaier struct type *tqe_next; /* next element */ \ 66171169Smlaier struct type **tqe_prev; /* address of previous next element */ \ 67171169Smlaier} 68171169Smlaier#endif /* !TAILQ_ENTRY */ 69171169Smlaier#ifndef RB_ENTRY 70171169Smlaier#define _EVENT_DEFINED_RBENTRY 71171169Smlaier#define RB_ENTRY(type) \ 72171169Smlaierstruct { \ 73171169Smlaier struct type *rbe_left; /* left element */ \ 74171169Smlaier struct type *rbe_right; /* right element */ \ 75171169Smlaier struct type *rbe_parent; /* parent element */ \ 76171169Smlaier int rbe_color; /* node color */ \ 77171169Smlaier} 78171169Smlaier#endif /* !RB_ENTRY */ 79171169Smlaier 80171169Smlaierstruct event_base; 81171169Smlaierstruct event { 82171169Smlaier TAILQ_ENTRY (event) ev_next; 83171169Smlaier TAILQ_ENTRY (event) ev_active_next; 84171169Smlaier TAILQ_ENTRY (event) ev_signal_next; 85171169Smlaier RB_ENTRY (event) ev_timeout_node; 86171169Smlaier 87171169Smlaier struct event_base *ev_base; 88171169Smlaier int ev_fd; 89171169Smlaier short ev_events; 90171169Smlaier short ev_ncalls; 91171169Smlaier short *ev_pncalls; /* Allows deletes in callback */ 92171169Smlaier 93171169Smlaier struct timeval ev_timeout; 94171169Smlaier 95171169Smlaier int ev_pri; /* smaller numbers are higher priority */ 96171169Smlaier 97171169Smlaier void (*ev_callback)(int, short, void *arg); 98171169Smlaier void *ev_arg; 99171169Smlaier 100171169Smlaier int ev_res; /* result passed to event callback */ 101171169Smlaier int ev_flags; 102171169Smlaier}; 103171169Smlaier 104171169Smlaier#define EVENT_SIGNAL(ev) (int)(ev)->ev_fd 105171169Smlaier#define EVENT_FD(ev) (int)(ev)->ev_fd 106171169Smlaier 107171169Smlaier/* 108171169Smlaier * Key-Value pairs. Can be used for HTTP headers but also for 109171169Smlaier * query argument parsing. 110171169Smlaier */ 111171169Smlaierstruct evkeyval { 112171169Smlaier TAILQ_ENTRY(evkeyval) next; 113171169Smlaier 114171169Smlaier char *key; 115171169Smlaier char *value; 116171169Smlaier}; 117171169Smlaier 118171169Smlaier#ifdef _EVENT_DEFINED_TQENTRY 119171169Smlaier#undef TAILQ_ENTRY 120171169Smlaierstruct event_list; 121171169Smlaierstruct evkeyvalq; 122171169Smlaier#undef _EVENT_DEFINED_TQENTRY 123171169Smlaier#else 124171169SmlaierTAILQ_HEAD (event_list, event); 125171169SmlaierTAILQ_HEAD (evkeyvalq, evkeyval); 126171169Smlaier#endif /* _EVENT_DEFINED_TQENTRY */ 127171169Smlaier#ifdef _EVENT_DEFINED_RBENTRY 128171169Smlaier#undef RB_ENTRY 129171169Smlaier#undef _EVENT_DEFINED_RBENTRY 130171169Smlaier#endif /* _EVENT_DEFINED_RBENTRY */ 131171169Smlaier 132171169Smlaierstruct eventop { 133171169Smlaier char *name; 134171169Smlaier void *(*init)(void); 135171169Smlaier int (*add)(void *, struct event *); 136171169Smlaier int (*del)(void *, struct event *); 137171169Smlaier int (*recalc)(struct event_base *, void *, int); 138171169Smlaier int (*dispatch)(struct event_base *, void *, struct timeval *); 139171169Smlaier void (*dealloc)(void *); 140171169Smlaier}; 141171169Smlaier 142171169Smlaier#define TIMEOUT_DEFAULT {5, 0} 143171169Smlaier 144171169Smlaiervoid *event_init(void); 145171169Smlaierint event_dispatch(void); 146171169Smlaierint event_base_dispatch(struct event_base *); 147171169Smlaiervoid event_base_free(struct event_base *); 148171169Smlaier 149171169Smlaier#define _EVENT_LOG_DEBUG 0 150171169Smlaier#define _EVENT_LOG_MSG 1 151171169Smlaier#define _EVENT_LOG_WARN 2 152171169Smlaier#define _EVENT_LOG_ERR 3 153171169Smlaiertypedef void (*event_log_cb)(int severity, const char *msg); 154171169Smlaiervoid event_set_log_callback(event_log_cb cb); 155171169Smlaier 156171169Smlaier/* Associate a different event base with an event */ 157171169Smlaierint event_base_set(struct event_base *, struct event *); 158171169Smlaier 159171169Smlaier#define EVLOOP_ONCE 0x01 160171169Smlaier#define EVLOOP_NONBLOCK 0x02 161171169Smlaierint event_loop(int); 162171169Smlaierint event_base_loop(struct event_base *, int); 163171169Smlaierint event_loopexit(struct timeval *); /* Causes the loop to exit */ 164171169Smlaierint event_base_loopexit(struct event_base *, struct timeval *); 165171169Smlaier 166171169Smlaier#define evtimer_add(ev, tv) event_add(ev, tv) 167171169Smlaier#define evtimer_set(ev, cb, arg) event_set(ev, -1, 0, cb, arg) 168171169Smlaier#define evtimer_del(ev) event_del(ev) 169171169Smlaier#define evtimer_pending(ev, tv) event_pending(ev, EV_TIMEOUT, tv) 170171169Smlaier#define evtimer_initialized(ev) ((ev)->ev_flags & EVLIST_INIT) 171171169Smlaier 172171169Smlaier#define timeout_add(ev, tv) event_add(ev, tv) 173171169Smlaier#define timeout_set(ev, cb, arg) event_set(ev, -1, 0, cb, arg) 174171169Smlaier#define timeout_del(ev) event_del(ev) 175171169Smlaier#define timeout_pending(ev, tv) event_pending(ev, EV_TIMEOUT, tv) 176171169Smlaier#define timeout_initialized(ev) ((ev)->ev_flags & EVLIST_INIT) 177171169Smlaier 178171169Smlaier#define signal_add(ev, tv) event_add(ev, tv) 179171169Smlaier#define signal_set(ev, x, cb, arg) \ 180171169Smlaier event_set(ev, x, EV_SIGNAL|EV_PERSIST, cb, arg) 181171169Smlaier#define signal_del(ev) event_del(ev) 182171169Smlaier#define signal_pending(ev, tv) event_pending(ev, EV_SIGNAL, tv) 183171169Smlaier#define signal_initialized(ev) ((ev)->ev_flags & EVLIST_INIT) 184171169Smlaier 185171169Smlaiervoid event_set(struct event *, int, short, void (*)(int, short, void *), void *); 186171169Smlaierint event_once(int, short, void (*)(int, short, void *), void *, struct timeval *); 187171169Smlaier 188171169Smlaierint event_add(struct event *, struct timeval *); 189171169Smlaierint event_del(struct event *); 190171169Smlaiervoid event_active(struct event *, int, short); 191171169Smlaier 192171169Smlaierint event_pending(struct event *, short, struct timeval *); 193171169Smlaier 194171169Smlaier#ifdef WIN32 195171169Smlaier#define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT && (ev)->ev_fd != (int)INVALID_HANDLE_VALUE) 196171169Smlaier#else 197171169Smlaier#define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT) 198171169Smlaier#endif 199171169Smlaier 200171169Smlaier/* Some simple debugging functions */ 201171169Smlaierconst char *event_get_version(void); 202171169Smlaierconst char *event_get_method(void); 203171169Smlaier 204171169Smlaier/* These functions deal with event priorities */ 205171169Smlaier 206171169Smlaierint event_priority_init(int); 207171169Smlaierint event_base_priority_init(struct event_base *, int); 208171169Smlaierint event_priority_set(struct event *, int); 209171169Smlaier 210171169Smlaier/* These functions deal with buffering input and output */ 211171169Smlaier 212171169Smlaierstruct evbuffer { 213171169Smlaier u_char *buffer; 214171169Smlaier u_char *orig_buffer; 215171169Smlaier 216171169Smlaier size_t misalign; 217171169Smlaier size_t totallen; 218171169Smlaier size_t off; 219171169Smlaier 220171169Smlaier void (*cb)(struct evbuffer *, size_t, size_t, void *); 221171169Smlaier void *cbarg; 222171169Smlaier}; 223171169Smlaier 224171169Smlaier/* Just for error reporting - use other constants otherwise */ 225171169Smlaier#define EVBUFFER_READ 0x01 226171169Smlaier#define EVBUFFER_WRITE 0x02 227171169Smlaier#define EVBUFFER_EOF 0x10 228171169Smlaier#define EVBUFFER_ERROR 0x20 229171169Smlaier#define EVBUFFER_TIMEOUT 0x40 230171169Smlaier 231171169Smlaierstruct bufferevent; 232171169Smlaiertypedef void (*evbuffercb)(struct bufferevent *, void *); 233171169Smlaiertypedef void (*everrorcb)(struct bufferevent *, short what, void *); 234171169Smlaier 235171169Smlaierstruct event_watermark { 236171169Smlaier size_t low; 237171169Smlaier size_t high; 238171169Smlaier}; 239171169Smlaier 240171169Smlaierstruct bufferevent { 241171169Smlaier struct event ev_read; 242171169Smlaier struct event ev_write; 243171169Smlaier 244171169Smlaier struct evbuffer *input; 245171169Smlaier struct evbuffer *output; 246171169Smlaier 247171169Smlaier struct event_watermark wm_read; 248171169Smlaier struct event_watermark wm_write; 249171169Smlaier 250171169Smlaier evbuffercb readcb; 251171169Smlaier evbuffercb writecb; 252171169Smlaier everrorcb errorcb; 253171169Smlaier void *cbarg; 254171169Smlaier 255171169Smlaier int timeout_read; /* in seconds */ 256171169Smlaier int timeout_write; /* in seconds */ 257171169Smlaier 258171169Smlaier short enabled; /* events that are currently enabled */ 259171169Smlaier}; 260171169Smlaier 261171169Smlaierstruct bufferevent *bufferevent_new(int fd, 262171169Smlaier evbuffercb readcb, evbuffercb writecb, everrorcb errorcb, void *cbarg); 263171169Smlaierint bufferevent_base_set(struct event_base *base, struct bufferevent *bufev); 264171169Smlaierint bufferevent_priority_set(struct bufferevent *bufev, int pri); 265171169Smlaiervoid bufferevent_free(struct bufferevent *bufev); 266171169Smlaierint bufferevent_write(struct bufferevent *bufev, void *data, size_t size); 267171169Smlaierint bufferevent_write_buffer(struct bufferevent *bufev, struct evbuffer *buf); 268171169Smlaiersize_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size); 269171169Smlaierint bufferevent_enable(struct bufferevent *bufev, short event); 270171169Smlaierint bufferevent_disable(struct bufferevent *bufev, short event); 271171169Smlaiervoid bufferevent_settimeout(struct bufferevent *bufev, 272171169Smlaier int timeout_read, int timeout_write); 273171169Smlaier 274171169Smlaier#define EVBUFFER_LENGTH(x) (x)->off 275171169Smlaier#define EVBUFFER_DATA(x) (x)->buffer 276171169Smlaier#define EVBUFFER_INPUT(x) (x)->input 277171169Smlaier#define EVBUFFER_OUTPUT(x) (x)->output 278171169Smlaier 279171169Smlaierstruct evbuffer *evbuffer_new(void); 280171169Smlaiervoid evbuffer_free(struct evbuffer *); 281171169Smlaierint evbuffer_expand(struct evbuffer *, size_t); 282171169Smlaierint evbuffer_add(struct evbuffer *, const void *, size_t); 283171169Smlaierint evbuffer_remove(struct evbuffer *, void *, size_t); 284171169Smlaierchar *evbuffer_readline(struct evbuffer *); 285171169Smlaierint evbuffer_add_buffer(struct evbuffer *, struct evbuffer *); 286171169Smlaierint evbuffer_add_printf(struct evbuffer *, const char *fmt, ...); 287171169Smlaierint evbuffer_add_vprintf(struct evbuffer *, const char *fmt, va_list ap); 288171169Smlaiervoid evbuffer_drain(struct evbuffer *, size_t); 289171169Smlaierint evbuffer_write(struct evbuffer *, int); 290171169Smlaierint evbuffer_read(struct evbuffer *, int, int); 291171169Smlaieru_char *evbuffer_find(struct evbuffer *, const u_char *, size_t); 292171169Smlaiervoid evbuffer_setcb(struct evbuffer *, void (*)(struct evbuffer *, size_t, size_t, void *), void *); 293171169Smlaier 294171169Smlaier/* 295171169Smlaier * Marshaling tagged data - We assume that all tags are inserted in their 296171169Smlaier * numeric order - so that unknown tags will always be higher than the 297171169Smlaier * known ones - and we can just ignore the end of an event buffer. 298171169Smlaier */ 299171169Smlaier 300171169Smlaiervoid evtag_init(void); 301171169Smlaier 302171169Smlaiervoid evtag_marshal(struct evbuffer *evbuf, u_int8_t tag, const void *data, 303171169Smlaier u_int32_t len); 304171169Smlaier 305171169Smlaiervoid encode_int(struct evbuffer *evbuf, u_int32_t number); 306171169Smlaier 307171169Smlaiervoid evtag_marshal_int(struct evbuffer *evbuf, u_int8_t tag, 308171169Smlaier u_int32_t integer); 309171169Smlaier 310171169Smlaiervoid evtag_marshal_string(struct evbuffer *buf, u_int8_t tag, 311171169Smlaier const char *string); 312171169Smlaier 313171169Smlaiervoid evtag_marshal_timeval(struct evbuffer *evbuf, u_int8_t tag, 314171169Smlaier struct timeval *tv); 315171169Smlaier 316171169Smlaiervoid evtag_test(void); 317171169Smlaier 318171169Smlaierint evtag_unmarshal(struct evbuffer *src, u_int8_t *ptag, 319171169Smlaier struct evbuffer *dst); 320171169Smlaierint evtag_peek(struct evbuffer *evbuf, u_int8_t *ptag); 321171169Smlaierint evtag_peek_length(struct evbuffer *evbuf, u_int32_t *plength); 322171169Smlaierint evtag_payload_length(struct evbuffer *evbuf, u_int32_t *plength); 323171169Smlaierint evtag_consume(struct evbuffer *evbuf); 324171169Smlaier 325171169Smlaierint evtag_unmarshal_int(struct evbuffer *evbuf, u_int8_t need_tag, 326171169Smlaier u_int32_t *pinteger); 327171169Smlaier 328171169Smlaierint evtag_unmarshal_fixed(struct evbuffer *src, u_int8_t need_tag, void *data, 329171169Smlaier size_t len); 330171169Smlaier 331171169Smlaierint evtag_unmarshal_string(struct evbuffer *evbuf, u_int8_t need_tag, 332171169Smlaier char **pstring); 333171169Smlaier 334171169Smlaierint evtag_unmarshal_timeval(struct evbuffer *evbuf, u_int8_t need_tag, 335171169Smlaier struct timeval *ptv); 336171169Smlaier 337171169Smlaier#ifdef __cplusplus 338171169Smlaier} 339171169Smlaier#endif 340171169Smlaier 341171169Smlaier#endif /* _EVENT_H_ */ 342