diff -Nru libevent-2.0.12-stable/buffer.c libevent-2.0.16-stable/buffer.c --- libevent-2.0.12-stable/buffer.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/buffer.c 2011-11-14 17:15:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2002-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -254,6 +254,31 @@ } #endif +/* Free all trailing chains in 'buf' that are neither pinned nor empty, prior + * to replacing them all with a new chain. Return a pointer to the place + * where the new chain will go. + * + * Internal; requires lock. The caller must fix up buf->last and buf->first + * as needed; they might have been freed. + */ +static struct evbuffer_chain ** +evbuffer_free_trailing_empty_chains(struct evbuffer *buf) +{ + struct evbuffer_chain **ch = buf->last_with_datap; + /* Find the first victim chain. It might be *last_with_datap */ + while ((*ch) && ((*ch)->off != 0 || CHAIN_PINNED(*ch))) + ch = &(*ch)->next; + if (*ch) { + EVUTIL_ASSERT(evbuffer_chains_all_empty(*ch)); + evbuffer_free_all_chains(*ch); + *ch = NULL; + } + return ch; +} + +/* Add a single chain 'chain' to the end of 'buf', freeing trailing empty + * chains as necessary. Requires lock. Does not schedule callbacks. + */ static void evbuffer_chain_insert(struct evbuffer *buf, struct evbuffer_chain *chain) @@ -327,6 +352,24 @@ return (buffer); } +int +evbuffer_set_flags(struct evbuffer *buf, ev_uint64_t flags) +{ + EVBUFFER_LOCK(buf); + buf->flags |= (ev_uint32_t)flags; + EVBUFFER_UNLOCK(buf); + return 0; +} + +int +evbuffer_clear_flags(struct evbuffer *buf, ev_uint64_t flags) +{ + EVBUFFER_LOCK(buf); + buf->flags &= ~(ev_uint32_t)flags; + EVBUFFER_UNLOCK(buf); + return 0; +} + void _evbuffer_incref(struct evbuffer *buf) { @@ -444,9 +487,14 @@ } } -static inline void +void evbuffer_invoke_callbacks(struct evbuffer *buffer) { + if (TAILQ_EMPTY(&buffer->callbacks)) { + buffer->n_add_for_cb = buffer->n_del_for_cb = 0; + return; + } + if (buffer->deferred_cbs) { if (buffer->deferred.queued) return; @@ -1081,10 +1129,13 @@ if (nread) { /* we can remove the chain */ + struct evbuffer_chain **chp; + chp = evbuffer_free_trailing_empty_chains(dst); + if (dst->first == NULL) { dst->first = src->first; } else { - dst->last->next = src->first; + *chp = src->first; } dst->last = previous; previous->next = NULL; @@ -1102,6 +1153,9 @@ chain->off -= datlen; nread += datlen; + /* You might think we would want to increment dst->n_add_for_cb + * here too. But evbuffer_add above already took care of that. + */ src->total_len -= nread; src->n_del_for_cb += nread; @@ -1249,7 +1303,7 @@ if (cp) { it->_internal.chain = chain; it->_internal.pos_in_chain = cp - buffer; - it->pos += (cp - buffer); + it->pos += (cp - buffer - i); return it->pos; } it->pos += chain->off - i; @@ -1552,6 +1606,7 @@ memcpy(tmp->buffer, data, datlen); tmp->off = datlen; evbuffer_chain_insert(buf, tmp); + buf->n_add_for_cb += datlen; out: evbuffer_invoke_callbacks(buf); @@ -2262,12 +2317,18 @@ } return (res); #elif defined(SENDFILE_IS_SOLARIS) - res = sendfile(fd, info->fd, &offset, chain->off); - if (res == -1 && EVUTIL_ERR_RW_RETRIABLE(errno)) { - /* if this is EAGAIN or EINTR return 0; otherwise, -1 */ - return (0); + { + const off_t offset_orig = offset; + res = sendfile(fd, info->fd, &offset, chain->off); + if (res == -1 && EVUTIL_ERR_RW_RETRIABLE(errno)) { + if (offset - offset_orig) + return offset - offset_orig; + /* if this is EAGAIN or EINTR and no bytes were + * written, return 0 */ + return (0); + } + return (res); } - return (res); #endif } #endif @@ -2669,10 +2730,19 @@ struct evbuffer_chain *chain; struct evbuffer_chain_fd *info; #endif +#if defined(USE_SENDFILE) + int sendfile_okay = 1; +#endif int ok = 1; #if defined(USE_SENDFILE) if (use_sendfile) { + EVBUFFER_LOCK(outbuf); + sendfile_okay = outbuf->flags & EVBUFFER_FLAG_DRAINS_TO_FD; + EVBUFFER_UNLOCK(outbuf); + } + + if (use_sendfile && sendfile_okay) { chain = evbuffer_chain_new(sizeof(struct evbuffer_chain_fd)); if (chain == NULL) { event_warn("%s: out of memory", __func__); diff -Nru libevent-2.0.12-stable/bufferevent_async.c libevent-2.0.16-stable/bufferevent_async.c --- libevent-2.0.12-stable/bufferevent_async.c 2011-04-23 05:47:11.000000000 +0000 +++ libevent-2.0.16-stable/bufferevent_async.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * All rights reserved. * @@ -80,8 +80,8 @@ struct event_overlapped connect_overlapped; struct event_overlapped read_overlapped; struct event_overlapped write_overlapped; - unsigned read_in_progress : 1; - unsigned write_in_progress : 1; + size_t read_in_progress; + size_t write_in_progress; unsigned ok : 1; unsigned read_added : 1; unsigned write_added : 1; @@ -188,7 +188,7 @@ /* Don't write if there's a write in progress, or we do not * want to write, or when there's nothing left to write. */ - if (beva->write_in_progress) + if (beva->write_in_progress || beva->bev.connecting) return; if (!beva->ok || !(bev->enabled&EV_WRITE) || !evbuffer_get_length(bev->output)) { @@ -198,7 +198,6 @@ at_most = evbuffer_get_length(bev->output); - /* XXXX This over-commits. */ /* This is safe so long as bufferevent_get_write_max never returns * more than INT_MAX. That's true for now. XXXX */ limit = (int)_bufferevent_get_write_max(&beva->bev); @@ -218,7 +217,8 @@ beva->ok = 0; _bufferevent_run_eventcb(bev, BEV_EVENT_ERROR); } else { - beva->write_in_progress = 1; + beva->write_in_progress = at_most; + _bufferevent_decrement_write_buckets(&beva->bev, at_most); bev_async_add_write(beva); } } @@ -234,7 +234,7 @@ /* Don't read if there is a read in progress, or we do not * want to read. */ - if (beva->read_in_progress) + if (beva->read_in_progress || beva->bev.connecting) return; if (!beva->ok || !(bev->enabled&EV_READ)) { bev_async_del_read(beva); @@ -268,10 +268,11 @@ bufferevent_incref(bev); if (evbuffer_launch_read(bev->input, at_most, &beva->read_overlapped)) { beva->ok = 0; - bufferevent_decref(bev); _bufferevent_run_eventcb(bev, BEV_EVENT_ERROR); + bufferevent_decref(bev); } else { - beva->read_in_progress = 1; + beva->read_in_progress = at_most; + _bufferevent_decrement_read_buckets(&beva->bev, at_most); bev_async_add_read(beva); } @@ -324,7 +325,11 @@ if (!bev_async->ok) return -1; - /* NOTE: This interferes with non-blocking connect */ + if (bev_async->bev.connecting) { + /* Don't launch anything during connection attempts. */ + return 0; + } + if (what & EV_READ) BEV_RESET_GENERIC_READ_TIMEOUT(buf); if (what & EV_WRITE) @@ -374,8 +379,10 @@ bev_async_del_write(bev_async); fd = _evbuffer_overlapped_get_fd(bev->input); - if (bev_p->options & BEV_OPT_CLOSE_ON_FREE) + if (bev_p->options & BEV_OPT_CLOSE_ON_FREE) { + /* XXXX possible double-close */ evutil_closesocket(fd); + } /* delete this in case non-blocking connect was used */ if (event_initialized(&bev->ev_write)) { event_del(&bev->ev_write); @@ -438,12 +445,15 @@ struct bufferevent_async *bev_a = upcast_read(eo); struct bufferevent *bev = &bev_a->bev.bev; short what = BEV_EVENT_READING; - + ev_ssize_t amount_unread; BEV_LOCK(bev); EVUTIL_ASSERT(bev_a->read_in_progress); + amount_unread = bev_a->read_in_progress - nbytes; evbuffer_commit_read(bev->input, nbytes); bev_a->read_in_progress = 0; + if (amount_unread) + _bufferevent_decrement_read_buckets(&bev_a->bev, -amount_unread); if (!ok) bev_async_set_wsa_error(bev, eo); @@ -451,8 +461,6 @@ if (bev_a->ok) { if (ok && nbytes) { BEV_RESET_GENERIC_READ_TIMEOUT(bev); - _bufferevent_decrement_read_buckets(&bev_a->bev, - nbytes); if (evbuffer_get_length(bev->input) >= bev->wm_read.low) _bufferevent_run_readcb(bev); bev_async_consider_reading(bev_a); @@ -477,20 +485,26 @@ struct bufferevent_async *bev_a = upcast_write(eo); struct bufferevent *bev = &bev_a->bev.bev; short what = BEV_EVENT_WRITING; + ev_ssize_t amount_unwritten; BEV_LOCK(bev); EVUTIL_ASSERT(bev_a->write_in_progress); + + amount_unwritten = bev_a->write_in_progress - nbytes; evbuffer_commit_write(bev->output, nbytes); bev_a->write_in_progress = 0; + if (amount_unwritten) + _bufferevent_decrement_write_buckets(&bev_a->bev, + -amount_unwritten); + + if (!ok) bev_async_set_wsa_error(bev, eo); if (bev_a->ok) { if (ok && nbytes) { BEV_RESET_GENERIC_WRITE_TIMEOUT(bev); - _bufferevent_decrement_write_buckets(&bev_a->bev, - nbytes); if (evbuffer_get_length(bev->output) <= bev->wm_write.low) _bufferevent_run_writecb(bev); @@ -657,8 +671,20 @@ _evbuffer_overlapped_set_fd(bev->output, data->fd); return 0; } + case BEV_CTRL_CANCEL_ALL: { + struct bufferevent_async *bev_a = upcast(bev); + evutil_socket_t fd = _evbuffer_overlapped_get_fd(bev->input); + if (fd != (evutil_socket_t)INVALID_SOCKET && + (bev_a->bev.options & BEV_OPT_CLOSE_ON_FREE)) { + closesocket(fd); + } + bev_a->ok = 0; + return 0; + } case BEV_CTRL_GET_UNDERLYING: default: return -1; } } + + diff -Nru libevent-2.0.12-stable/bufferevent.c libevent-2.0.16-stable/bufferevent.c --- libevent-2.0.12-stable/bufferevent.c 2011-03-28 17:06:21.000000000 +0000 +++ libevent-2.0.16-stable/bufferevent.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2002-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos, Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos, Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -59,6 +59,9 @@ #include "evbuffer-internal.h" #include "util-internal.h" +static void _bufferevent_cancel_all(struct bufferevent *bev); + + void bufferevent_suspend_read(struct bufferevent *bufev, bufferevent_suspend_flags what) { @@ -674,6 +677,7 @@ { BEV_LOCK(bufev); bufferevent_setcb(bufev, NULL, NULL, NULL, NULL); + _bufferevent_cancel_all(bufev); _bufferevent_decref_and_unlock(bufev); } @@ -750,6 +754,17 @@ return (res<0) ? -1 : d.fd; } +static void +_bufferevent_cancel_all(struct bufferevent *bev) +{ + union bufferevent_ctrl_data d; + memset(&d, 0, sizeof(d)); + BEV_LOCK(bev); + if (bev->be_ops->ctrl) + bev->be_ops->ctrl(bev, BEV_CTRL_CANCEL_ALL, &d); + BEV_UNLOCK(bev); +} + short bufferevent_get_enabled(struct bufferevent *bufev) { diff -Nru libevent-2.0.12-stable/bufferevent_filter.c libevent-2.0.16-stable/bufferevent_filter.c --- libevent-2.0.12-stable/bufferevent_filter.c 2011-04-23 05:47:04.000000000 +0000 +++ libevent-2.0.16-stable/bufferevent_filter.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * Copyright (c) 2002-2006 Niels Provos * All rights reserved. * @@ -504,6 +504,7 @@ return 0; case BEV_CTRL_GET_FD: case BEV_CTRL_SET_FD: + case BEV_CTRL_CANCEL_ALL: default: return -1; } diff -Nru libevent-2.0.12-stable/bufferevent-internal.h libevent-2.0.16-stable/bufferevent-internal.h --- libevent-2.0.12-stable/bufferevent-internal.h 2011-03-28 17:06:21.000000000 +0000 +++ libevent-2.0.16-stable/bufferevent-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2008-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -98,6 +98,8 @@ /** The smallest number of bytes that any member of the group should * be limited to read or write at a time. */ ev_ssize_t min_share; + ev_ssize_t configured_min_share; + /** Timeout event that goes off once a tick, when the bucket is ready * to refill. */ struct event master_refill_event; @@ -195,7 +197,8 @@ enum bufferevent_ctrl_op { BEV_CTRL_SET_FD, BEV_CTRL_GET_FD, - BEV_CTRL_GET_UNDERLYING + BEV_CTRL_GET_UNDERLYING, + BEV_CTRL_CANCEL_ALL }; /** Possible data types for a control callback */ diff -Nru libevent-2.0.12-stable/bufferevent_openssl.c libevent-2.0.16-stable/bufferevent_openssl.c --- libevent-2.0.12-stable/bufferevent_openssl.c 2011-04-23 05:47:04.000000000 +0000 +++ libevent-2.0.16-stable/bufferevent_openssl.c 2011-11-18 19:35:07.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -170,8 +170,8 @@ /* Copy only as much data onto the output buffer as can fit under the * high-water mark. */ - if (bufev->wm_write.high && bufev->wm_write.high >= (outlen+inlen)) { - if (bufev->wm_write.high >= outlen) { + if (bufev->wm_write.high && bufev->wm_write.high <= (outlen+inlen)) { + if (bufev->wm_write.high <= outlen) { /* If no data can fit, we'll need to retry later. */ BIO_set_retry_write(b); return -1; @@ -704,6 +704,50 @@ #define READ_DEFAULT 4096 +/* Try to figure out how many bytes to read; return 0 if we shouldn't be + * reading. */ +static int +bytes_to_read(struct bufferevent_openssl *bev) +{ + struct evbuffer *input = bev->bev.bev.input; + struct event_watermark *wm = &bev->bev.bev.wm_read; + int result = READ_DEFAULT; + ev_ssize_t limit; + /* XXX 99% of this is generic code that nearly all bufferevents will + * want. */ + + if (bev->write_blocked_on_read) { + return 0; + } + + if (! (bev->bev.bev.enabled & EV_READ)) { + return 0; + } + + if (bev->bev.read_suspended) { + return 0; + } + + if (wm->high) { + if (evbuffer_get_length(input) >= wm->high) { + return 0; + } + + result = wm->high - evbuffer_get_length(input); + } else { + result = READ_DEFAULT; + } + + /* Respect the rate limit */ + limit = _bufferevent_get_read_max(&bev->bev); + if (result > limit) { + result = limit; + } + + return result; +} + + /* Things look readable. If write is blocked on read, write till it isn't. * Read from the underlying buffer until we block or we hit our high-water * mark. @@ -712,8 +756,7 @@ consider_reading(struct bufferevent_openssl *bev_ssl) { int r; - struct evbuffer *input = bev_ssl->bev.bev.input; - struct event_watermark *wm = &bev_ssl->bev.bev.wm_read; + int n_to_read; while (bev_ssl->write_blocked_on_read) { r = do_write(bev_ssl, WRITE_FRAME); @@ -722,15 +765,22 @@ } if (bev_ssl->write_blocked_on_read) return; - while ((bev_ssl->bev.bev.enabled & EV_READ) && - (! bev_ssl->bev.read_suspended) && - (! wm->high || evbuffer_get_length(input) < wm->high)) { - int n_to_read = - wm->high ? wm->high - evbuffer_get_length(input) - : READ_DEFAULT; - r = do_read(bev_ssl, n_to_read); - if (r <= 0) + + n_to_read = bytes_to_read(bev_ssl); + + while (n_to_read) { + if (do_read(bev_ssl, n_to_read) <= 0) break; + + /* Read all pending data. This won't hit the network + * again, and will (most importantly) put us in a state + * where we don't need to read anything else until the + * socket is readable again. It'll potentially make us + * overrun our read high-watermark (somewhat + * regrettable). The damage to the rate-limit has + * already been done, since OpenSSL went and read a + * whole SSL record anyway. */ + n_to_read = SSL_pending(bev_ssl->ssl); } if (!bev_ssl->underlying) { @@ -814,6 +864,9 @@ } else if (what & BEV_EVENT_TIMEOUT) { /* We sure didn't set this. Propagate it to the user. */ event = what; + } else if (what & BEV_EVENT_ERROR) { + /* An error occurred on the connection. Propagate it to the user. */ + event = what; } else if (what & BEV_EVENT_CONNECTED) { /* Ignore it. We're saying SSL_connect() already, which will eat it. */ @@ -1164,6 +1217,7 @@ return -1; data->ptr = bev_ssl->underlying; return 0; + case BEV_CTRL_CANCEL_ALL: default: return -1; } @@ -1245,6 +1299,7 @@ } if (underlying) { + bufferevent_setwatermark(underlying, EV_READ, 0, 0); bufferevent_enable(underlying, EV_READ|EV_WRITE); if (state == BUFFEREVENT_SSL_OPEN) bufferevent_suspend_read(underlying, diff -Nru libevent-2.0.12-stable/bufferevent_pair.c libevent-2.0.16-stable/bufferevent_pair.c --- libevent-2.0.12-stable/bufferevent_pair.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/bufferevent_pair.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos, Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos, Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -158,7 +158,7 @@ evbuffer_unfreeze(dst->input, 0); if (dst->wm_read.high) { - size_t dst_size = evbuffer_get_length(dst->input); + dst_size = evbuffer_get_length(dst->input); if (dst_size < dst->wm_read.high) { n = dst->wm_read.high - dst_size; evbuffer_remove_buffer(src->output, dst->input, n); diff -Nru libevent-2.0.12-stable/bufferevent_ratelim.c libevent-2.0.16-stable/bufferevent_ratelim.c --- libevent-2.0.12-stable/bufferevent_ratelim.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/bufferevent_ratelim.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * Copyright (c) 2002-2006 Niels Provos * All rights reserved. * @@ -43,6 +43,7 @@ #include "bufferevent-internal.h" #include "mm-internal.h" #include "util-internal.h" +#include "event-internal.h" int ev_token_bucket_init(struct ev_token_bucket *bucket, @@ -165,7 +166,8 @@ r->read_maximum = read_burst; r->write_maximum = write_burst; memcpy(&r->tick_timeout, tick_len, sizeof(struct timeval)); - r->msec_per_tick = (tick_len->tv_sec * 1000) + tick_len->tv_usec/1000; + r->msec_per_tick = (tick_len->tv_sec * 1000) + + (tick_len->tv_usec & COMMON_TIMEOUT_MICROSECONDS_MASK)/1000; return r; } @@ -187,6 +189,8 @@ static int _bev_group_suspend_reading(struct bufferevent_rate_limit_group *g); static int _bev_group_suspend_writing(struct bufferevent_rate_limit_group *g); +static void _bev_group_unsuspend_reading(struct bufferevent_rate_limit_group *g); +static void _bev_group_unsuspend_writing(struct bufferevent_rate_limit_group *g); /** Helper: figure out the maximum amount we should write if is_write, or the maximum amount we should read if is_read. Return that maximum, or @@ -283,6 +287,10 @@ if (event_add(&bev->rate_limiting->refill_bucket_event, &bev->rate_limiting->cfg->tick_timeout) < 0) r = -1; + } else if (bev->read_suspended & BEV_SUSPEND_BW) { + if (!(bev->write_suspended & BEV_SUSPEND_BW)) + event_del(&bev->rate_limiting->refill_bucket_event); + bufferevent_unsuspend_read(&bev->bev, BEV_SUSPEND_BW); } } @@ -292,6 +300,8 @@ bev->rate_limiting->group->total_read += bytes; if (bev->rate_limiting->group->rate_limit.read_limit <= 0) { _bev_group_suspend_reading(bev->rate_limiting->group); + } else if (bev->rate_limiting->group->read_suspended) { + _bev_group_unsuspend_reading(bev->rate_limiting->group); } UNLOCK_GROUP(bev->rate_limiting->group); } @@ -315,6 +325,10 @@ if (event_add(&bev->rate_limiting->refill_bucket_event, &bev->rate_limiting->cfg->tick_timeout) < 0) r = -1; + } else if (bev->write_suspended & BEV_SUSPEND_BW) { + if (!(bev->read_suspended & BEV_SUSPEND_BW)) + event_del(&bev->rate_limiting->refill_bucket_event); + bufferevent_unsuspend_write(&bev->bev, BEV_SUSPEND_BW); } } @@ -324,6 +338,8 @@ bev->rate_limiting->group->total_written += bytes; if (bev->rate_limiting->group->rate_limit.write_limit <= 0) { _bev_group_suspend_writing(bev->rate_limiting->group); + } else if (bev->rate_limiting->group->write_suspended) { + _bev_group_unsuspend_writing(bev->rate_limiting->group); } UNLOCK_GROUP(bev->rate_limiting->group); } @@ -518,6 +534,7 @@ event_base_gettimeofday_cached(event_get_base(&g->master_refill_event), &now); LOCK_GROUP(g); + tick = ev_token_bucket_get_tick(&now, &g->rate_limit_cfg); ev_token_bucket_update(&g->rate_limit, &g->rate_limit_cfg, tick); @@ -636,13 +653,15 @@ ev_token_bucket_init(&g->rate_limit, cfg, tick, 0); - g->min_share = 64; event_assign(&g->master_refill_event, base, -1, EV_PERSIST, _bev_group_refill_callback, g); /*XXXX handle event_add failure */ event_add(&g->master_refill_event, &cfg->tick_timeout); EVTHREAD_ALLOC_LOCK(g->lock, EVTHREAD_LOCKTYPE_RECURSIVE); + + bufferevent_rate_limit_group_set_min_share(g, 64); + return g; } @@ -670,6 +689,9 @@ event_add(&g->master_refill_event, &cfg->tick_timeout); } + /* The new limits might force us to adjust min_share differently. */ + bufferevent_rate_limit_group_set_min_share(g, g->configured_min_share); + UNLOCK_GROUP(g); return 0; } @@ -682,6 +704,15 @@ if (share > EV_SSIZE_MAX) return -1; + g->configured_min_share = share; + + /* Can't set share to less than the one-tick maximum. IOW, at steady + * state, at least one connection can go per tick. */ + if (share > g->rate_limit_cfg.read_rate) + share = g->rate_limit_cfg.read_rate; + if (share > g->rate_limit_cfg.write_rate) + share = g->rate_limit_cfg.write_rate; + g->min_share = share; return 0; } diff -Nru libevent-2.0.12-stable/bufferevent_sock.c libevent-2.0.16-stable/bufferevent_sock.c --- libevent-2.0.12-stable/bufferevent_sock.c 2011-04-23 05:47:04.000000000 +0000 +++ libevent-2.0.16-stable/bufferevent_sock.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * Copyright (c) 2002-2006 Niels Provos * All rights reserved. * @@ -113,8 +113,9 @@ !bufev_p->write_suspended) { /* Somebody added data to the buffer, and we would like to * write, and we were not writing. So, start writing. */ - be_socket_add(&bufev->ev_write, &bufev->timeout_write); - /* XXXX handle failure from be_socket_add */ + if (be_socket_add(&bufev->ev_write, &bufev->timeout_write) == -1) { + // Should we log this? + } } } @@ -327,6 +328,7 @@ return NULL; } bufev = &bufev_p->bev; + evbuffer_set_flags(bufev->output, EVBUFFER_FLAG_DRAINS_TO_FD); event_assign(&bufev->ev_read, bufev->ev_base, fd, EV_READ|EV_PERSIST, bufferevent_readcb, bufev); @@ -684,6 +686,7 @@ data->fd = event_get_fd(&bev->ev_read); return 0; case BEV_CTRL_GET_UNDERLYING: + case BEV_CTRL_CANCEL_ALL: default: return -1; } diff -Nru libevent-2.0.12-stable/buffer_iocp.c libevent-2.0.16-stable/buffer_iocp.c --- libevent-2.0.12-stable/buffer_iocp.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/buffer_iocp.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -126,6 +126,9 @@ buf->read_in_progress = 0; evbuf->total_len += nBytes; + evbuf->n_add_for_cb += nBytes; + + evbuffer_invoke_callbacks(evbuf); _evbuffer_decref_and_unlock(evbuf); } @@ -150,6 +153,8 @@ struct evbuffer_overlapped *evo; evo = mm_calloc(1, sizeof(struct evbuffer_overlapped)); + if (!evo) + return NULL; TAILQ_INIT(&evo->buffer.callbacks); evo->buffer.refcnt = 1; diff -Nru libevent-2.0.12-stable/changelist-internal.h libevent-2.0.16-stable/changelist-internal.h --- libevent-2.0.12-stable/changelist-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/changelist-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/ChangeLog libevent-2.0.16-stable/ChangeLog --- libevent-2.0.12-stable/ChangeLog 2011-06-05 01:10:42.000000000 +0000 +++ libevent-2.0.16-stable/ChangeLog 2011-11-18 20:09:38.000000000 +0000 @@ -1,3 +1,119 @@ +Changes in version 2.0.16-stable (18 Nov 2011) +BUGFIXES (core): + o More detailed message in case of libevent self-debugging failure. (9e6a4ef Leonid Evdokimov) + o epoll: close fd on alloc fail at initialization (1aee718 Jamie Iles) + o Fix compile warning from saying event2/*.h inside a comment (447b0ba) + o Warn when unable to construct base because of failing make_base_notifiable (4e797f3) + o Don't try to make notifiable event_base when no threading fns are configured (e787413) + +BUGFIXES (evbuffer): + o unit test for remove_buffer bug (90bd620 Greg Hazel) + o Fix an evbuffer crash in evbuffer_remove_buffer() (c37069c) + +BUGFIXES (bufferevent_openssl): + o Refactor amount-to-read calculations in buffervent_ssl consider_reading() (a186e73 Mark Ellzey) + o Move SSL rate-limit enforcement into bytes_to_read() (96c562f) + o Avoid spinning on OpenSSL reads (2aa036f Mark Ellzey) + +BUGFIXES (dns) + o Empty DNS reply with OK status is another way to say NODATA. (21a08d6 Leonid Evdokimov) + +TESTING: + o Tests for 94fba5b and f72e8f6 (d58c15e Leonid Evdokimov) + o Test for commit aff6ba1 (f7841bf Leonid Evdokimov) + o Style and comment tweaks for dns/leak* tests (5e42202) + o improve test to remove at least one buffer from src (7eb52eb Greg Hazel) + +DOCUMENTATION: + o Add note about evhttp_send_reply_end to its doxygen (724bfb5) + o Update copyright dates to 2011. (3c824bd) + o Fix typo in whatsnew-2.0.txt (674bc6a Mansour Moufid) + o Improve win32 behavior of dns-sample.c code (a3f320e Gisle Vanem) + + + +Changes in version 2.0.15-stable (12 Oct 2011) +BUGFIXES (DNS): + o DNS: add ttl for negative answers using RFC 2308 idea. (f72e8f6 Leonid Evdokimov) + o Add DNS_ERR_NODATA error code to handle empty replies. (94fba5b Leonid Evdokimov) + +BUFGIXES (bufferevents and evbuffers): + o Make evbuffer callbacks get the right n_added value after evbuffer_add (1ef1f68 Alex) + o Prefer mmap to sendfile unless a DRAINS_TO_FD flag is set. Allows add_file to work with SSL. (0ba0af9) + +BUGFIXES (event loop): + o When a signal callback is activated to run multiple times, allow event_base_loopbreak to work even before they all have run. (4e8eb6a) + +DOCUMENTATION FIXES: + o Fix docstring in dns.h (2b6eae5 Leonid Evdokimov) + o refer to non-deprecated evdns functions in comments (ba5c27d Greg Hazel) + +BUILD AND TESTING FIXES: + o le-proxy and regress depend on openssl directly (9ae061a Sergey Avseyev) + o Use _SOURCES, not _sources, in sample/Makefile.am (7f82382) + o Fixed compiler warnings for unchecked read/write calls. (c3b62fd Mark Ellzey) + o Make write-checking fixes use tt_fail_perror (2b76847) + o Fix some "value never used" warnings with gcc 4.6.1 (39c0cf7) + + + +Changes in version 2.0.14-stable (31 Aug 2011) +BUGFIXES (bufferevents and evbuffers): + o Propagate errors on the underlying bufferevent to the user. (4a34394 Joachim Bauch) + o Ignore OpenSSL deprecation warnings on OS X (5d1b255 Sebastian Hahn) + o Fix handling of group rate limits under 64 bytes of burst (6d5440e) + o Solaris sendfile: correctly detect amount of data sent (643922e Michael Herf) + o Make rate limiting work with common_timeout logic (5b18f13) + o clear read watermark on underlying bufferevent when creating filtering bev to fix potentially failing fragmented ssl handshakes (54f7e61 Joachim Bauch) + +BUGFIXES (IOCP): + o IOCP: don't launch reads or writes on an unconnected socket (495c227) + o Make IOCP rate-limiting group support stricter and less surprising. (a98da7b) + o Have test-ratelim.c support IOCP (0ff2c5a) + o Make overlapped reads result in evbuffer callbacks getting invoked (6acfbdd) + o Correctly terminate IO on an async bufferevent on bufferevent_free (e6af35d) + +BUGFIXES (other): + o Fix evsig_dealloc memory leak with debugging turned on. (9b724b2 Leonid Evdokimov) + o Fix request_finished memory leak with debugging turned on. (aff6ba1 Leonid Evdokimov) + +BUILD AND TESTING FIXES: + o Allow OS-neutral builds for platforms where some versions have arc4random_buf (b442302 Mitchell Livingston) + o Try to fix 'make distcheck' errors when building out-of-tree (04656ea Dave Hart) + o Clean up some problems identified by Coverity. (7c11e51 Harlan Stenn) + + +Changes in version 2.0.13-stable (18 Jul 2011) +BUGFIXES + o Avoid race-condition when initializing global locks (b683cae) + o Fix bug in SSL bufferevents backed by a bev with a write high-watermarks (e050703 Joachim Bauch) + o Speed up invoke_callbacks on evbuffers when there are no callbacks (f87f568 Mark Ellzey) + o Avoid a segfault when all methods are disabled or broken (27ce38b) + o Fix incorrect results from evbuffer_search_eol(EOL_LF) (4461f1a) + o Add some missing checks for mm_calloc failures (89d5e09) + o Replace an assertion for event_base_free(NULL) with a check-and-warn (09fe97d) + o Report kqueue ebadf, epipe, and eperm as EV_READ events (1fd34ab) + o Check if the `evhttp_new_object' function in `http.c' returns NULL. (446cc7a Mansour Moufid) + o Use the correct printf args when formatting size_t (3203f88) + o Complain if the caller tries to change threading cbs after setting them (cb6ecee) + +DOCUMENTATION FIXES AND IMPROVEMENTS + o Revise the event/evbuffer/bufferevent doxygen for clarity and accuracy (2888fac) + o Update Doxyfile to produce more useful output (aea0555) + +TEST FIXES + o Fix up test_evutil_snprintf (caf695a) + o Fix tinytest invocation from windows shell (57def34 Ed Day) + +BUILD FIXES + o Use AM_CPPFLAGS in sample/Makefile.am, not AM_CFLAGS (4a5c82d) + o Fix select.c compilation on systems with no NFDBITS (49d1136) + o Fix a few warnings on OpenBSD (8ee9f9c Nicholas Marriott) + o Don't break when building tests from git without python installed (b031adf) + o Don't install event_rpcgen.py when --disable-libevent-install is used (e23cda3 Harlan Stenn) + o Fix AIX build issue with TAILQ_FOREACH definition (e934096) + + Changes in version 2.0.12-stable (4 Jun 2011) BUGFIXES o Fix a warn-and-fail bug in kqueue by providing kevent() room to report errors (28317a0) diff -Nru libevent-2.0.12-stable/configure libevent-2.0.16-stable/configure --- libevent-2.0.12-stable/configure 2011-06-03 20:23:56.000000000 +0000 +++ libevent-2.0.16-stable/configure 2011-11-18 20:20:00.000000000 +0000 @@ -3032,7 +3032,7 @@ # Define the identity of the package. PACKAGE=libevent - VERSION=2.0.12-stable + VERSION=2.0.16-stable cat >>confdefs.h <<_ACEOF @@ -3075,7 +3075,7 @@ ac_config_headers="$ac_config_headers config.h" -$as_echo "#define NUMERIC_VERSION 0x02000c00" >>confdefs.h +$as_echo "#define NUMERIC_VERSION 0x02001000" >>confdefs.h if test "$prefix" = "NONE"; then @@ -4600,6 +4600,15 @@ CFLAGS="$CFLAGS -fno-strict-aliasing" fi +# OS X Lion started deprecating the system openssl. Let's just disable +# all deprecation warnings on OS X. +case "$host_os" in + + darwin*) + CFLAGS="$CFLAGS -Wno-deprecated-declarations" + ;; +esac + # Check whether --enable-gcc-warnings was given. if test "${enable_gcc_warnings+set}" = set; then : enableval=$enable_gcc_warnings; diff -Nru libevent-2.0.12-stable/configure.in libevent-2.0.16-stable/configure.in --- libevent-2.0.12-stable/configure.in 2011-06-03 19:43:34.000000000 +0000 +++ libevent-2.0.16-stable/configure.in 2011-11-18 20:16:54.000000000 +0000 @@ -5,9 +5,9 @@ AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE(libevent,2.0.12-stable) +AM_INIT_AUTOMAKE(libevent,2.0.16-stable) AM_CONFIG_HEADER(config.h) -AC_DEFINE(NUMERIC_VERSION, 0x02000c00, [Numeric representation of the version]) +AC_DEFINE(NUMERIC_VERSION, 0x02001000, [Numeric representation of the version]) dnl Initialize prefix. if test "$prefix" = "NONE"; then @@ -43,6 +43,15 @@ CFLAGS="$CFLAGS -fno-strict-aliasing" fi +# OS X Lion started deprecating the system openssl. Let's just disable +# all deprecation warnings on OS X. +case "$host_os" in + + darwin*) + CFLAGS="$CFLAGS -Wno-deprecated-declarations" + ;; +esac + AC_ARG_ENABLE(gcc-warnings, AS_HELP_STRING(--enable-gcc-warnings, enable verbose warnings with GCC)) AC_ARG_ENABLE(thread-support, diff -Nru libevent-2.0.12-stable/debian/changelog libevent-2.0.16-stable/debian/changelog --- libevent-2.0.12-stable/debian/changelog 2011-06-17 14:02:23.000000000 +0000 +++ libevent-2.0.16-stable/debian/changelog 2011-11-28 04:39:34.000000000 +0000 @@ -1,3 +1,29 @@ +libevent (2.0.16-stable-1) unstable; urgency=low + + * New upstream version 2.0.16-stable + * Uploading to unstable, see http://bugs.debian.org/631018 + + -- Anibal Monsalve Salazar Mon, 28 Nov 2011 15:39:09 +1100 + +libevent (2.0.13-stable-1) experimental; urgency=low + + * New upstream version 2.0.13-stable + * Pass "-Zbzip2 -z9" to dpkg-deb + + -- Anibal Monsalve Salazar Sun, 28 Aug 2011 14:46:57 +1000 + +libevent (1.4.14b-stable-1) unstable; urgency=low + + * New upstream version 1.4.14b-stable + * Source format is 3.0 (quilt) + * Standards-Version is 3.9.2 + * Pass parameters -Zbzip2 and -z9 to dpkg-deb via dh_builddeb + * Fix debhelper-but-no-misc-depends + * Fix debian-rules-missing-recommended-target + * Fix description-synopsis-starts-with-article + + -- Anibal Monsalve Salazar Sun, 28 Aug 2011 12:49:20 +1000 + libevent (2.0.12-stable-1) experimental; urgency=low * [9be9bdb9] new upstream version 2.0.12-stable diff -Nru libevent-2.0.12-stable/debian/libevent-2.0-5.shlibs libevent-2.0.16-stable/debian/libevent-2.0-5.shlibs --- libevent-2.0.12-stable/debian/libevent-2.0-5.shlibs 2011-06-17 14:01:02.000000000 +0000 +++ libevent-2.0.16-stable/debian/libevent-2.0-5.shlibs 2011-11-28 04:36:34.000000000 +0000 @@ -1 +1 @@ -libevent-2.0 5 libevent-2.0-5 (>= 2.0.10-stable) +libevent-2.0 5 libevent-2.0-5 (>= 2.0.16-stable) diff -Nru libevent-2.0.12-stable/debian/libevent-core-2.0-5.shlibs libevent-2.0.16-stable/debian/libevent-core-2.0-5.shlibs --- libevent-2.0.12-stable/debian/libevent-core-2.0-5.shlibs 2011-06-17 14:01:02.000000000 +0000 +++ libevent-2.0.16-stable/debian/libevent-core-2.0-5.shlibs 2011-11-28 04:36:45.000000000 +0000 @@ -1 +1 @@ -libevent_core-2.0 5 libevent-core-2.0-5 (>= 2.0.10-stable) +libevent_core-2.0 5 libevent-core-2.0-5 (>= 2.0.16-stable) diff -Nru libevent-2.0.12-stable/debian/libevent-extra-2.0-5.shlibs libevent-2.0.16-stable/debian/libevent-extra-2.0-5.shlibs --- libevent-2.0.12-stable/debian/libevent-extra-2.0-5.shlibs 2011-06-17 14:01:02.000000000 +0000 +++ libevent-2.0.16-stable/debian/libevent-extra-2.0-5.shlibs 2011-11-28 04:36:55.000000000 +0000 @@ -1 +1 @@ -libevent_extra-2.0 5 libevent-extra-2.0-5 (>= 2.0.10-stable) +libevent_extra-2.0 5 libevent-extra-2.0-5 (>= 2.0.16-stable) diff -Nru libevent-2.0.12-stable/debian/libevent-openssl-2.0-5.shlibs libevent-2.0.16-stable/debian/libevent-openssl-2.0-5.shlibs --- libevent-2.0.12-stable/debian/libevent-openssl-2.0-5.shlibs 2011-06-17 14:01:02.000000000 +0000 +++ libevent-2.0.16-stable/debian/libevent-openssl-2.0-5.shlibs 2011-11-28 04:37:05.000000000 +0000 @@ -1 +1 @@ -libevent_openssl-2.0 5 libevent-openssl-2.0-5 (>= 2.0.10-stable) +libevent_openssl-2.0 5 libevent-openssl-2.0-5 (>= 2.0.16-stable) diff -Nru libevent-2.0.12-stable/debian/libevent-pthreads-2.0-5.shlibs libevent-2.0.16-stable/debian/libevent-pthreads-2.0-5.shlibs --- libevent-2.0.12-stable/debian/libevent-pthreads-2.0-5.shlibs 2011-06-17 14:01:02.000000000 +0000 +++ libevent-2.0.16-stable/debian/libevent-pthreads-2.0-5.shlibs 2011-11-28 04:37:19.000000000 +0000 @@ -1 +1 @@ -libevent_pthreads-2.0 5 libevent-pthreads-2.0-5 (>= 2.0.10-stable) +libevent_pthreads-2.0 5 libevent-pthreads-2.0-5 (>= 2.0.16-stable) diff -Nru libevent-2.0.12-stable/debian/rules libevent-2.0.16-stable/debian/rules --- libevent-2.0.12-stable/debian/rules 2011-06-17 14:01:02.000000000 +0000 +++ libevent-2.0.16-stable/debian/rules 2011-08-28 04:43:08.000000000 +0000 @@ -11,3 +11,6 @@ override_dh_strip: dh_strip --dbg-package=libevent-dbg + +override_dh_builddeb: + dh_builddeb -- -Zbzip2 -z9 diff -Nru libevent-2.0.12-stable/defer-internal.h libevent-2.0.16-stable/defer-internal.h --- libevent-2.0.12-stable/defer-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/defer-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/devpoll.c libevent-2.0.16-stable/devpoll.c --- libevent-2.0.12-stable/devpoll.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/devpoll.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2000-2009 Niels Provos - * Copyright 2009-2010 Niels Provos and Nick Mathewson + * Copyright 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/Doxyfile libevent-2.0.16-stable/Doxyfile --- libevent-2.0.12-stable/Doxyfile 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/Doxyfile 2011-07-05 17:04:30.000000000 +0000 @@ -45,6 +45,15 @@ SORT_BRIEF_DOCS = YES +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = include/ + #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- @@ -54,21 +63,25 @@ # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = event.h evdns.h evhttp.h evrpc.h \ - include/event2/event.h include/event2/event_struct.h \ - include/event2/event_compat.h \ - include/event2/buffer_compat.h \ - include/event2/buffer.h include/event2/thread.h \ - include/event2/tag.h include/event2/bufferevent.h \ - include/event2/bufferevent_struct.h \ - include/event2/bufferevent_compat.h \ - include/event2/util.h \ - include/event2/rpc.h include/event2/rpc_struct.h \ - include/event2/rpc_compat.h \ - include/event2/dns.h include/event2/dns_struct.h \ - include/event2/dns_compat.h \ - include/event2/http.h include/event2/http_struct.h \ - include/event2/http_compat.h +INPUT = \ + include/event2/buffer.h \ + include/event2/buffer_compat.h \ + include/event2/bufferevent.h \ + include/event2/bufferevent_compat.h \ + include/event2/bufferevent_ssl.h \ + include/event2/dns.h \ + include/event2/dns_compat.h \ + include/event2/event.h \ + include/event2/event_compat.h \ + include/event2/http.h \ + include/event2/http_compat.h \ + include/event2/listener.h \ + include/event2/rpc.h \ + include/event2/rpc_compat.h \ + include/event2/tag.h \ + include/event2/tag_compat.h \ + include/event2/thread.h \ + include/event2/util.h #--------------------------------------------------------------------------- # configuration options related to the HTML output @@ -140,7 +153,7 @@ # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. -USE_PDFLATEX = NO +USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep @@ -162,7 +175,7 @@ # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages -GENERATE_MAN = YES +GENERATE_MAN = NO # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) @@ -226,7 +239,7 @@ # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = TAILQ_ENTRY RB_ENTRY _EVENT_DEFINED_TQENTRY +PREDEFINED = TAILQ_ENTRY RB_ENTRY _EVENT_DEFINED_TQENTRY _EVENT_IN_DOXYGEN # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff -Nru libevent-2.0.12-stable/epoll.c libevent-2.0.16-stable/epoll.c --- libevent-2.0.12-stable/epoll.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/epoll.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2000-2007 Niels Provos - * Copyright 2007-2010 Niels Provos, Nick Mathewson + * Copyright 2007-2011 Niels Provos, Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -120,8 +120,10 @@ evutil_make_socket_closeonexec(epfd); - if (!(epollop = mm_calloc(1, sizeof(struct epollop)))) + if (!(epollop = mm_calloc(1, sizeof(struct epollop)))) { + close(epfd); return (NULL); + } epollop->epfd = epfd; @@ -129,6 +131,7 @@ epollop->events = mm_calloc(INITIAL_NEVENT, sizeof(struct epoll_event)); if (epollop->events == NULL) { mm_free(epollop); + close(epfd); return (NULL); } epollop->nevents = INITIAL_NEVENT; diff -Nru libevent-2.0.12-stable/epoll_sub.c libevent-2.0.16-stable/epoll_sub.c --- libevent-2.0.12-stable/epoll_sub.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/epoll_sub.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2003-2009 Niels Provos - * Copyright 2009-2010 Niels Provos and Nick Mathewson + * Copyright 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/evbuffer-internal.h libevent-2.0.16-stable/evbuffer-internal.h --- libevent-2.0.12-stable/evbuffer-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/evbuffer-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -129,6 +129,8 @@ /** True iff this buffer is set up for overlapped IO. */ unsigned is_overlapped : 1; #endif + /** Zero or more EVBUFFER_FLAG_* bits */ + ev_uint32_t flags; /** Used to implement deferred callbacks. */ struct deferred_cb_queue *cb_queue; @@ -270,6 +272,8 @@ /** Set the parent bufferevent object for buf to bev */ void evbuffer_set_parent(struct evbuffer *buf, struct bufferevent *bev); +void evbuffer_invoke_callbacks(struct evbuffer *buf); + #ifdef __cplusplus } #endif diff -Nru libevent-2.0.12-stable/evdns.c libevent-2.0.16-stable/evdns.c --- libevent-2.0.12-stable/evdns.c 2011-05-25 20:46:32.000000000 +0000 +++ libevent-2.0.16-stable/evdns.c 2011-10-21 22:25:20.000000000 +0000 @@ -133,6 +133,7 @@ #define TYPE_A EVDNS_TYPE_A #define TYPE_CNAME 5 #define TYPE_PTR EVDNS_TYPE_PTR +#define TYPE_SOA EVDNS_TYPE_SOA #define TYPE_AAAA EVDNS_TYPE_AAAA #define CLASS_INET EVDNS_CLASS_INET @@ -645,6 +646,8 @@ } else { base->global_requests_waiting--; } + /* it was initialized during request_new / evtimer_assign */ + event_debug_unassign(&req->timeout_event); if (!req->request_appended) { /* need to free the request data on it's own */ @@ -758,7 +761,7 @@ cb->reply.data.a.addresses, user_pointer); else - cb->user_callback(cb->err, 0, 0, 0, NULL, user_pointer); + cb->user_callback(cb->err, 0, 0, cb->ttl, NULL, user_pointer); break; case TYPE_PTR: if (cb->have_reply) { @@ -766,7 +769,7 @@ cb->user_callback(DNS_ERR_NONE, DNS_PTR, 1, cb->ttl, &name, user_pointer); } else { - cb->user_callback(cb->err, 0, 0, 0, NULL, user_pointer); + cb->user_callback(cb->err, 0, 0, cb->ttl, NULL, user_pointer); } break; case TYPE_AAAA: @@ -776,7 +779,7 @@ cb->reply.data.aaaa.addresses, user_pointer); else - cb->user_callback(cb->err, 0, 0, 0, NULL, user_pointer); + cb->user_callback(cb->err, 0, 0, cb->ttl, NULL, user_pointer); break; default: EVUTIL_ASSERT(0); @@ -840,13 +843,17 @@ /* there was an error */ if (flags & 0x0200) { error = DNS_ERR_TRUNCATED; - } else { + } else if (flags & 0x000f) { u16 error_code = (flags & 0x000f) - 1; if (error_code > 4) { error = DNS_ERR_UNKNOWN; } else { error = error_codes[error_code]; } + } else if (reply && !reply->have_answer) { + error = DNS_ERR_NODATA; + } else { + error = DNS_ERR_UNKNOWN; } switch (error) { @@ -893,7 +900,7 @@ } /* all else failed. Pass the failure up */ - reply_schedule_callback(req, 0, error, NULL); + reply_schedule_callback(req, ttl, error, NULL); request_finished(req, &REQ_HEAD(req->base, req->trans_id), 1); } else { /* all ok, tell the user */ @@ -996,8 +1003,8 @@ /* If it's not an answer, it doesn't correspond to any request. */ if (!(flags & 0x8000)) return -1; /* must be an answer */ - if (flags & 0x020f) { - /* there was an error */ + if ((flags & 0x020f) && (flags & 0x020f) != DNS_ERR_NOTEXIST) { + /* there was an error and it's not NXDOMAIN */ goto err; } /* if (!answers) return; */ /* must have an answer of some form */ @@ -1037,7 +1044,7 @@ */ TEST_NAME; j += 4; - if (j >= length) goto err; + if (j > length) goto err; } if (!name_matches) @@ -1119,6 +1126,39 @@ } } + if (!reply.have_answer) { + for (i = 0; i < authority; ++i) { + u16 type, class; + SKIP_NAME; + GET16(type); + GET16(class); + GET32(ttl); + GET16(datalength); + if (type == TYPE_SOA && class == CLASS_INET) { + u32 serial, refresh, retry, expire, minimum; + SKIP_NAME; + SKIP_NAME; + GET32(serial); + GET32(refresh); + GET32(retry); + GET32(expire); + GET32(minimum); + (void)expire; + (void)retry; + (void)refresh; + (void)serial; + ttl_r = MIN(ttl_r, ttl); + ttl_r = MIN(ttl_r, minimum); + } else { + /* skip over any other type of resource */ + j += datalength; + } + } + } + + if (ttl_r == 0xffffffff) + ttl_r = 0; + reply_handle(req, flags, ttl_r, &reply); return 0; err: @@ -3839,6 +3879,7 @@ case DNS_ERR_TIMEOUT: return "request timed out"; case DNS_ERR_SHUTDOWN: return "dns subsystem shut down"; case DNS_ERR_CANCEL: return "dns request canceled"; + case DNS_ERR_NODATA: return "no records in the reply"; default: return "[Unknown error code]"; } } diff -Nru libevent-2.0.12-stable/evdns.h libevent-2.0.16-stable/evdns.h --- libevent-2.0.12-stable/evdns.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/evdns.h 2011-11-14 17:15:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,6 +27,16 @@ #ifndef _EVDNS_H_ #define _EVDNS_H_ +/** @file evdns.h + + A dns subsystem for Libevent. + + The header is deprecated in Libevent 2.0 and later; please + use instead. Depending on what functionality you + need, you may also want to include more of the other + headers. + */ + #include #include #include diff -Nru libevent-2.0.12-stable/event.c libevent-2.0.16-stable/event.c --- libevent-2.0.12-stable/event.c 2011-03-28 17:06:21.000000000 +0000 +++ libevent-2.0.16-stable/event.c 2011-11-15 21:24:05.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -182,7 +182,9 @@ int _event_debug_mode_on = 0; /* Set if it's too late to enable event_debug_mode. */ static int event_debug_mode_too_late = 0; +#ifndef _EVENT_DISABLE_THREAD_SUPPORT static void *_event_debug_map_lock = NULL; +#endif static HT_HEAD(event_debug_map, event_debug_entry) global_debug_map = HT_INITIALIZER(); @@ -237,8 +239,10 @@ dent->added = 1; \ } else { \ event_errx(_EVENT_ERR_ABORT, \ - "%s: noting an add on a non-setup event %p", \ - __func__, (ev)); \ + "%s: noting an add on a non-setup event %p" \ + " (events: 0x%x, fd: %d, flags: 0x%x)", \ + __func__, (ev), (ev)->ev_events, \ + (ev)->ev_fd, (ev)->ev_flags); \ } \ EVLOCK_UNLOCK(_event_debug_map_lock, 0); \ } \ @@ -255,8 +259,10 @@ dent->added = 0; \ } else { \ event_errx(_EVENT_ERR_ABORT, \ - "%s: noting a del on a non-setup event %p", \ - __func__, (ev)); \ + "%s: noting a del on a non-setup event %p" \ + " (events: 0x%x, fd: %d, flags: 0x%x)", \ + __func__, (ev), (ev)->ev_events, \ + (ev)->ev_fd, (ev)->ev_flags); \ } \ EVLOCK_UNLOCK(_event_debug_map_lock, 0); \ } \ @@ -271,8 +277,10 @@ dent = HT_FIND(event_debug_map, &global_debug_map, &find); \ if (!dent) { \ event_errx(_EVENT_ERR_ABORT, \ - "%s called on a non-initialized event %p", \ - __func__, (ev)); \ + "%s called on a non-initialized event %p" \ + " (events: 0x%x, fd: %d, flags: 0x%x)", \ + __func__, (ev), (ev)->ev_events, \ + (ev)->ev_fd, (ev)->ev_flags); \ } \ EVLOCK_UNLOCK(_event_debug_map_lock, 0); \ } \ @@ -287,8 +295,10 @@ dent = HT_FIND(event_debug_map, &global_debug_map, &find); \ if (dent && dent->added) { \ event_errx(_EVENT_ERR_ABORT, \ - "%s called on an already added event %p", \ - __func__, (ev)); \ + "%s called on an already added event %p" \ + " (events: 0x%x, fd: %d, flags: 0x%x)", \ + __func__, (ev), (ev)->ev_events, \ + (ev)->ev_fd, (ev)->ev_flags); \ } \ EVLOCK_UNLOCK(_event_debug_map_lock, 0); \ } \ @@ -514,8 +524,6 @@ _event_debug_mode_on = 1; HT_INIT(event_debug_map, &global_debug_map); - - EVTHREAD_ALLOC_LOCK(_event_debug_map_lock, 0); #endif } @@ -545,9 +553,6 @@ #ifndef _EVENT_DISABLE_DEBUG_MODE event_debug_mode_too_late = 1; - if (_event_debug_mode_on && !_event_debug_map_lock) { - EVTHREAD_ALLOC_LOCK(_event_debug_map_lock, 0); - } #endif if ((base = mm_calloc(1, sizeof(struct event_base))) == NULL) { @@ -603,6 +608,7 @@ if (base->evbase == NULL) { event_warnx("%s: no event mechanism available", __func__); + base->evsel = NULL; event_base_free(base); return NULL; } @@ -619,7 +625,8 @@ /* prepare for threading */ #ifndef _EVENT_DISABLE_THREAD_SUPPORT - if (!cfg || !(cfg->flags & EVENT_BASE_FLAG_NOLOCK)) { + if (EVTHREAD_LOCKING_ENABLED() && + (!cfg || !(cfg->flags & EVENT_BASE_FLAG_NOLOCK))) { int r; EVTHREAD_ALLOC_LOCK(base->th_base_lock, EVTHREAD_LOCKTYPE_RECURSIVE); @@ -627,6 +634,7 @@ EVTHREAD_ALLOC_COND(base->current_event_cond); r = evthread_make_base_notifiable(base); if (r<0) { + event_warnx("%s: Unable to make base notifiable.", __func__); event_base_free(base); return NULL; } @@ -680,13 +688,19 @@ /* XXXX grab the lock? If there is contention when one thread frees * the base, then the contending thread will be very sad soon. */ + /* event_base_free(NULL) is how to free the current_base if we + * made it with event_init and forgot to hold a reference to it. */ if (base == NULL && current_base) base = current_base; + /* If we're freeing current_base, there won't be a current_base. */ if (base == current_base) current_base = NULL; - + /* Don't actually free NULL. */ + if (base == NULL) { + event_warnx("%s: no base to free", __func__); + return; + } /* XXX(niels) - check for internal events first */ - EVUTIL_ASSERT(base); #ifdef WIN32 event_base_stop_iocp(base); @@ -1020,6 +1034,7 @@ event_signal_closure(struct event_base *base, struct event *ev) { short ncalls; + int should_break; /* Allows deletes to work */ ncalls = ev->ev_ncalls; @@ -1031,11 +1046,13 @@ if (ncalls == 0) ev->ev_pncalls = NULL; (*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg); -#if 0 - /* XXXX we can't do this without a lock on the base. */ - if (base->event_break) + + EVBASE_ACQUIRE_LOCK(base, th_base_lock); + should_break = base->event_break; + EVBASE_RELEASE_LOCK(base, th_base_lock); + + if (should_break) return; -#endif } } @@ -1053,7 +1070,7 @@ * of index into the event_base's aray of common timeouts. */ -#define MICROSECONDS_MASK 0x000fffff +#define MICROSECONDS_MASK COMMON_TIMEOUT_MICROSECONDS_MASK #define COMMON_TIMEOUT_IDX_MASK 0x0ff00000 #define COMMON_TIMEOUT_IDX_SHIFT 20 #define COMMON_TIMEOUT_MASK 0xf0000000 @@ -2813,3 +2830,18 @@ evthread_notify_base(base); EVBASE_RELEASE_LOCK(base, th_base_lock); } + +#ifndef _EVENT_DISABLE_THREAD_SUPPORT +int +event_global_setup_locks_(const int enable_locks) +{ +#ifndef _EVENT_DISABLE_DEBUG_MODE + EVTHREAD_SETUP_GLOBAL_LOCK(_event_debug_map_lock, 0); +#endif + if (evsig_global_setup_locks_(enable_locks) < 0) + return -1; + if (evutil_secure_rng_global_setup_locks_(enable_locks) < 0) + return -1; + return 0; +} +#endif diff -Nru libevent-2.0.12-stable/event.h libevent-2.0.16-stable/event.h --- libevent-2.0.12-stable/event.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/event.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,135 +27,14 @@ #ifndef _EVENT_H_ #define _EVENT_H_ -/** @mainpage +/** @file event.h - @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 applications; 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 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 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 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 - - libevent 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. - - event2/event.h - The primary libevent header - - event2/buffer.h - Buffer management for network reading and writing - - event2/dns.h - Asynchronous DNS resolution - - event2/http.h - An embedded libevent-based HTTP server - - evrpc.h - A framework for creating RPC servers and clients - - */ - -/** @file libevent/event.h - - A library for writing event-driven network servers + A library for writing event-driven network servers. + The header is deprecated in Libevent 2.0 and later; please + use instead. Depending on what functionality you + need, you may also want to include more of the other event2/ + headers. */ #ifdef __cplusplus diff -Nru libevent-2.0.12-stable/event-internal.h libevent-2.0.16-stable/event-internal.h --- libevent-2.0.12-stable/event-internal.h 2011-03-28 17:06:21.000000000 +0000 +++ libevent-2.0.16-stable/event-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -146,6 +146,9 @@ struct event_base *base; }; +/** Mask used to get the real tv_usec value from a common timeout. */ +#define COMMON_TIMEOUT_MICROSECONDS_MASK 0x000fffff + struct event_change; /* List of 'changes' since the last call to eventop.dispatch. Only maintained @@ -313,10 +316,12 @@ #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) #endif +#ifndef TAILQ_FOREACH #define TAILQ_FOREACH(var, head, field) \ for ((var) = TAILQ_FIRST(head); \ (var) != TAILQ_END(head); \ (var) = TAILQ_NEXT(var, field)) +#endif #ifndef TAILQ_INSERT_BEFORE #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ @@ -335,6 +340,7 @@ void (*fn)(int)); int _evsig_restore_handler(struct event_base *base, int evsignal); + void event_active_nolock(struct event *ev, int res, short count); /* FIXME document. */ diff -Nru libevent-2.0.12-stable/event_iocp.c libevent-2.0.16-stable/event_iocp.c --- libevent-2.0.12-stable/event_iocp.c 2011-05-28 03:13:04.000000000 +0000 +++ libevent-2.0.16-stable/event_iocp.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos, Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos, Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/event_tagging.c libevent-2.0.16-stable/event_tagging.c --- libevent-2.0.12-stable/event_tagging.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/event_tagging.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2003-2009 Niels Provos - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/evhttp.h libevent-2.0.16-stable/evhttp.h --- libevent-2.0.12-stable/evhttp.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/evhttp.h 2011-11-14 17:15:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2000-2007 Niels Provos - * Copyright 2007-2010 Niels Provos and Nick Mathewson + * Copyright 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,6 +27,16 @@ #ifndef _EVHTTP_H_ #define _EVHTTP_H_ +/** @file evhttp.h + + An http implementation subsystem for Libevent. + + The header is deprecated in Libevent 2.0 and later; please + use instead. Depending on what functionality you + need, you may also want to include more of the other + headers. + */ + #include #include #include diff -Nru libevent-2.0.12-stable/evmap.c libevent-2.0.16-stable/evmap.c --- libevent-2.0.12-stable/evmap.c 2011-05-25 20:46:32.000000000 +0000 +++ libevent-2.0.16-stable/evmap.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -127,7 +127,8 @@ }, \ { \ _ent = mm_calloc(1,sizeof(struct event_map_entry)+fdinfo_len); \ - EVUTIL_ASSERT(_ent); \ + if (EVUTIL_UNLIKELY(_ent == NULL)) \ + return (-1); \ _ent->fd = slot; \ (ctor)(&_ent->ent.type); \ _HT_FOI_INSERT(map_node, map, &_key, _ent, ptr) \ @@ -159,14 +160,16 @@ (x) = (struct type *)((map)->entries[slot]) /* As GET_SLOT, but construct the entry for 'slot' if it is not present, by allocating enough memory for a 'struct type', and initializing the new - value by calling the function 'ctor' on it. + value by calling the function 'ctor' on it. Makes the function + return -1 on allocation failure. */ #define GET_SIGNAL_SLOT_AND_CTOR(x, map, slot, type, ctor, fdinfo_len) \ do { \ if ((map)->entries[slot] == NULL) { \ (map)->entries[slot] = \ mm_calloc(1,sizeof(struct type)+fdinfo_len); \ - EVUTIL_ASSERT((map)->entries[slot] != NULL); \ + if (EVUTIL_UNLIKELY((map)->entries[slot] == NULL)) \ + return (-1); \ (ctor)((struct type *)(map)->entries[slot]); \ } \ (x) = (struct type *)((map)->entries[slot]); \ diff -Nru libevent-2.0.12-stable/evmap-internal.h libevent-2.0.16-stable/evmap-internal.h --- libevent-2.0.12-stable/evmap-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/evmap-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/evrpc.c libevent-2.0.16-stable/evrpc.c --- libevent-2.0.12-stable/evrpc.c 2011-03-28 17:06:21.000000000 +0000 +++ libevent-2.0.16-stable/evrpc.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -338,8 +338,12 @@ evrpc_request_cb_closure(void *arg, enum EVRPC_HOOK_RESULT hook_res) { struct evrpc_req_generic *rpc_state = arg; - struct evrpc *rpc = rpc_state->rpc; - struct evhttp_request *req = rpc_state->http_req; + struct evrpc *rpc; + struct evhttp_request *req; + + EVUTIL_ASSERT(rpc_state); + rpc = rpc_state->rpc; + req = rpc_state->http_req; if (hook_res == EVRPC_TERMINATE) goto error; @@ -399,8 +403,13 @@ void evrpc_request_done(struct evrpc_req_generic *rpc_state) { - struct evhttp_request *req = rpc_state->http_req; - struct evrpc *rpc = rpc_state->rpc; + struct evhttp_request *req; + struct evrpc *rpc; + + EVUTIL_ASSERT(rpc_state); + + req = rpc_state->http_req; + rpc = rpc_state->rpc; if (rpc->reply_complete(rpc_state->reply) == -1) { /* the reply was not completely filled in. error out */ @@ -466,7 +475,9 @@ evrpc_request_done_closure(void *arg, enum EVRPC_HOOK_RESULT hook_res) { struct evrpc_req_generic *rpc_state = arg; - struct evhttp_request *req = rpc_state->http_req; + struct evhttp_request *req; + EVUTIL_ASSERT(rpc_state); + req = rpc_state->http_req; if (hook_res == EVRPC_TERMINATE) goto error; diff -Nru libevent-2.0.12-stable/evrpc.h libevent-2.0.16-stable/evrpc.h --- libevent-2.0.12-stable/evrpc.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/evrpc.h 2011-11-14 17:15:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,6 +27,16 @@ #ifndef _EVRPC_H_ #define _EVRPC_H_ +/** @file evrpc.h + + An RPC system for Libevent. + + The header is deprecated in Libevent 2.0 and later; please + use instead. Depending on what functionality you + need, you may also want to include more of the other + headers. + */ + #include #include #include diff -Nru libevent-2.0.12-stable/evrpc-internal.h libevent-2.0.16-stable/evrpc-internal.h --- libevent-2.0.12-stable/evrpc-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/evrpc-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2006-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/evsignal-internal.h libevent-2.0.16-stable/evsignal-internal.h --- libevent-2.0.12-stable/evsignal-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/evsignal-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2000-2007 Niels Provos - * Copyright 2007-2010 Niels Provos and Nick Mathewson + * Copyright 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/evthread.c libevent-2.0.16-stable/evthread.c --- libevent-2.0.12-stable/evthread.c 2011-04-23 05:47:04.000000000 +0000 +++ libevent-2.0.16-stable/evthread.c 2011-11-15 21:24:05.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Niels Provos, Nick Mathewson + * Copyright (c) 2008-2011 Niels Provos, Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -76,12 +76,25 @@ ? &_original_lock_fns : &_evthread_lock_fns; if (!cbs) { + if (target->alloc) + event_warnx("Trying to disable lock functions after " + "they have been set up will probaby not work."); memset(target, 0, sizeof(_evthread_lock_fns)); return 0; } + if (target->alloc) { + /* Uh oh; we already had locking callbacks set up.*/ + if (!memcmp(target, cbs, sizeof(_evthread_lock_fns))) { + /* no change -- allow this. */ + return 0; + } + event_warnx("Can't change lock callbacks once they have been " + "initialized."); + return -1; + } if (cbs->alloc && cbs->free && cbs->lock && cbs->unlock) { memcpy(target, cbs, sizeof(_evthread_lock_fns)); - return 0; + return event_global_setup_locks_(1); } else { return -1; } @@ -95,8 +108,24 @@ ? &_original_cond_fns : &_evthread_cond_fns; if (!cbs) { + if (target->alloc_condition) + event_warnx("Trying to disable condition functions " + "after they have been set up will probaby not " + "work."); memset(target, 0, sizeof(_evthread_cond_fns)); - } else if (cbs->alloc_condition && cbs->free_condition && + return 0; + } + if (target->alloc_condition) { + /* Uh oh; we already had condition callbacks set up.*/ + if (!memcmp(target, cbs, sizeof(_evthread_cond_fns))) { + /* no change -- allow this. */ + return 0; + } + event_warnx("Can't change condition callbacks once they " + "have been initialized."); + return -1; + } + if (cbs->alloc_condition && cbs->free_condition && cbs->signal_condition && cbs->wait_condition) { memcpy(target, cbs, sizeof(_evthread_cond_fns)); } @@ -247,6 +276,9 @@ sizeof(struct evthread_condition_callbacks)); _evthread_cond_fns.wait_condition = debug_cond_wait; _evthread_lock_debugging_enabled = 1; + + /* XXX return value should get checked. */ + event_global_setup_locks_(0); } int @@ -270,6 +302,62 @@ return lock->lock; } +void * +evthread_setup_global_lock_(void *lock_, unsigned locktype, int enable_locks) +{ + /* there are four cases here: + 1) we're turning on debugging; locking is not on. + 2) we're turning on debugging; locking is on. + 3) we're turning on locking; debugging is not on. + 4) we're turning on locking; debugging is on. */ + + if (!enable_locks && _original_lock_fns.alloc == NULL) { + /* Case 1: allocate a debug lock. */ + EVUTIL_ASSERT(lock_ == NULL); + return debug_lock_alloc(locktype); + } else if (!enable_locks && _original_lock_fns.alloc != NULL) { + /* Case 2: wrap the lock in a debug lock. */ + struct debug_lock *lock; + EVUTIL_ASSERT(lock_ != NULL); + + if (!(locktype & EVTHREAD_LOCKTYPE_RECURSIVE)) { + /* We can't wrap it: We need a recursive lock */ + _original_lock_fns.free(lock_, locktype); + return debug_lock_alloc(locktype); + } + lock = mm_malloc(sizeof(struct debug_lock)); + if (!lock) { + _original_lock_fns.free(lock_, locktype); + return NULL; + } + lock->lock = lock_; + lock->locktype = locktype; + lock->count = 0; + lock->held_by = 0; + return lock; + } else if (enable_locks && ! _evthread_lock_debugging_enabled) { + /* Case 3: allocate a regular lock */ + EVUTIL_ASSERT(lock_ == NULL); + return _evthread_lock_fns.alloc(locktype); + } else { + /* Case 4: Fill in a debug lock with a real lock */ + struct debug_lock *lock = lock_; + EVUTIL_ASSERT(enable_locks && + _evthread_lock_debugging_enabled); + EVUTIL_ASSERT(lock->locktype == locktype); + EVUTIL_ASSERT(lock->lock == NULL); + lock->lock = _original_lock_fns.alloc( + locktype|EVTHREAD_LOCKTYPE_RECURSIVE); + if (!lock->lock) { + lock->count = -200; + mm_free(lock); + return NULL; + } + return lock; + } +} + + #ifndef EVTHREAD_EXPOSE_STRUCTS unsigned long _evthreadimpl_get_id() @@ -337,6 +425,12 @@ { return _evthread_lock_debugging_enabled; } + +int +_evthreadimpl_locking_enabled(void) +{ + return _evthread_lock_fns.lock != NULL; +} #endif #endif diff -Nru libevent-2.0.12-stable/evthread-internal.h libevent-2.0.16-stable/evthread-internal.h --- libevent-2.0.12-stable/evthread-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/evthread-internal.h 2011-11-15 21:24:05.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Niels Provos, Nick Mathewson + * Copyright (c) 2008-2011 Niels Provos, Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -173,6 +173,10 @@ #define EVTHREAD_COND_WAIT_TIMED(cond, lock, tv) \ ( (cond) ? _evthread_cond_fns.wait_condition((cond), (lock), (tv)) : 0 ) +/** True iff locking functions have been configured. */ +#define EVTHREAD_LOCKING_ENABLED() \ + (_evthread_lock_fns.lock != NULL) + #elif ! defined(_EVENT_DISABLE_THREAD_SUPPORT) unsigned long _evthreadimpl_get_id(void); @@ -185,6 +189,7 @@ void _evthreadimpl_cond_free(void *cond); int _evthreadimpl_cond_signal(void *cond, int broadcast); int _evthreadimpl_cond_wait(void *cond, void *lock, const struct timeval *tv); +int _evthreadimpl_locking_enabled(void); #define EVTHREAD_GET_ID() _evthreadimpl_get_id() #define EVBASE_IN_THREAD(base) \ @@ -281,6 +286,9 @@ #define EVTHREAD_COND_WAIT_TIMED(cond, lock, tv) \ ( (cond) ? _evthreadimpl_cond_wait((cond), (lock), (tv)) : 0 ) +#define EVTHREAD_LOCKING_ENABLED() \ + (_evthreadimpl_locking_enabled()) + #else /* _EVENT_DISABLE_THREAD_SUPPORT */ #define EVTHREAD_GET_ID() 1 @@ -307,6 +315,8 @@ #define EVTHREAD_COND_WAIT(cond, lock) _EVUTIL_NIL_STMT #define EVTHREAD_COND_WAIT_TIMED(cond, lock, howlong) _EVUTIL_NIL_STMT +#define EVTHREAD_LOCKING_ENABLED() 0 + #endif /* This code is shared between both lock impls */ @@ -345,6 +355,24 @@ int _evthread_is_debug_lock_held(void *lock); void *_evthread_debug_get_real_lock(void *lock); + +void *evthread_setup_global_lock_(void *lock_, unsigned locktype, + int enable_locks); + +#define EVTHREAD_SETUP_GLOBAL_LOCK(lockvar, locktype) \ + do { \ + lockvar = evthread_setup_global_lock_(lockvar, \ + (locktype), enable_locks); \ + if (!lockvar) { \ + event_warn("Couldn't allocate %s", #lockvar); \ + return -1; \ + } \ + } while (0); + +int event_global_setup_locks_(const int enable_locks); +int evsig_global_setup_locks_(const int enable_locks); +int evutil_secure_rng_global_setup_locks_(const int enable_locks); + #endif #ifdef __cplusplus diff -Nru libevent-2.0.12-stable/evthread_pthread.c libevent-2.0.16-stable/evthread_pthread.c --- libevent-2.0.12-stable/evthread_pthread.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/evthread_pthread.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright 2009-2010 Niels Provos and Nick Mathewson + * Copyright 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/evthread_win32.c libevent-2.0.16-stable/evthread_win32.c --- libevent-2.0.12-stable/evthread_win32.c 2011-05-28 03:13:20.000000000 +0000 +++ libevent-2.0.16-stable/evthread_win32.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright 2009-2010 Niels Provos and Nick Mathewson + * Copyright 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/evutil.c libevent-2.0.16-stable/evutil.c --- libevent-2.0.12-stable/evutil.c 2011-04-12 18:09:16.000000000 +0000 +++ libevent-2.0.16-stable/evutil.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -55,15 +55,15 @@ #include #include #include -#ifdef _EVENT_HAVE_ARPA_INET_H -#include -#endif #ifdef _EVENT_HAVE_NETINET_IN_H #include #endif #ifdef _EVENT_HAVE_NETINET_IN6_H #include #endif +#ifdef _EVENT_HAVE_ARPA_INET_H +#include +#endif #ifndef _EVENT_HAVE_GETTIMEOFDAY #include @@ -445,9 +445,9 @@ int made_fd = 0; if (*fd_ptr < 0) { - made_fd = 1; if ((*fd_ptr = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) goto err; + made_fd = 1; if (evutil_make_socket_nonblocking(*fd_ptr) < 0) { goto err; } diff -Nru libevent-2.0.12-stable/evutil.h libevent-2.0.16-stable/evutil.h --- libevent-2.0.12-stable/evutil.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/evutil.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,6 +26,14 @@ #ifndef _EVUTIL_H_ #define _EVUTIL_H_ +/** @file evutil.h + + Utility and compatibility functions for Libevent. + + The header is deprecated in Libevent 2.0 and later; please + use instead. +*/ + #include #endif /* _EVUTIL_H_ */ diff -Nru libevent-2.0.12-stable/evutil_rand.c libevent-2.0.16-stable/evutil_rand.c --- libevent-2.0.12-stable/evutil_rand.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/evutil_rand.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -49,11 +49,18 @@ (void) arc4random(); return 0; } +int +evutil_secure_rng_global_setup_locks_(const int enable_locks) +{ + return 0; +} -#ifndef _EVENT_HAVE_ARC4RANDOM_BUF static void -arc4random_buf(void *buf, size_t n) +ev_arc4random_buf(void *buf, size_t n) { +#ifdef _EVENT_HAVE_ARC4RANDOM_BUF + return arc4random_buf(buf, n); +#else unsigned char *b = buf; /* Make sure that we start out with b at a 4-byte alignment; plenty * of CPUs care about this for 32-bit access. */ @@ -73,8 +80,8 @@ ev_uint32_t u = arc4random(); memcpy(b, &u, n); } -} #endif +} #else /* !_EVENT_HAVE_ARC4RANDOM { */ @@ -84,7 +91,9 @@ #define ARC4RANDOM_EXPORT static #define _ARC4_LOCK() EVLOCK_LOCK(arc4rand_lock, 0) #define _ARC4_UNLOCK() EVLOCK_UNLOCK(arc4rand_lock, 0) +#ifndef _EVENT_DISABLE_THREAD_SUPPORT static void *arc4rand_lock; +#endif #define ARC4RANDOM_UINT32 ev_uint32_t #define ARC4RANDOM_NOSTIR @@ -93,13 +102,19 @@ #include "./arc4random.c" +#ifndef _EVENT_DISABLE_THREAD_SUPPORT +int +evutil_secure_rng_global_setup_locks_(const int enable_locks) +{ + EVTHREAD_SETUP_GLOBAL_LOCK(arc4rand_lock, 0); + return 0; +} +#endif + int evutil_secure_rng_init(void) { int val; - if (!arc4rand_lock) { - EVTHREAD_ALLOC_LOCK(arc4rand_lock, 0); - } _ARC4_LOCK(); if (!arc4_seeded_ok) @@ -109,12 +124,18 @@ return val; } +static void +ev_arc4random_buf(void *buf, size_t n) +{ + arc4random_buf(buf, n); +} + #endif /* } !_EVENT_HAVE_ARC4RANDOM */ void evutil_secure_rng_get_bytes(void *buf, size_t n) { - arc4random_buf(buf, n); + ev_arc4random_buf(buf, n); } void diff -Nru libevent-2.0.12-stable/ht-internal.h libevent-2.0.16-stable/ht-internal.h --- libevent-2.0.12-stable/ht-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/ht-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* Based on work Copyright 2002 Christopher Clark */ -/* Copyright 2005-2010 Nick Mathewson */ -/* Copyright 2009-2010 Niels Provos and Nick Mathewson */ +/* Copyright 2005-2011 Nick Mathewson */ +/* Copyright 2009-2011 Niels Provos and Nick Mathewson */ /* See license at end. */ /* Based on ideas by Christopher Clark and interfaces from Niels Provos. */ @@ -223,7 +223,6 @@ void *data) \ { \ unsigned idx; \ - int remove; \ struct type **p, **nextp, *next; \ if (!head->hth_table) \ return; \ @@ -232,8 +231,7 @@ while (*p) { \ nextp = &(*p)->field.hte_next; \ next = *nextp; \ - remove = fn(*p, data); \ - if (remove) { \ + if (fn(*p, data)) { \ --head->hth_n_entries; \ *p = next; \ } else { \ diff -Nru libevent-2.0.12-stable/http.c libevent-2.0.16-stable/http.c --- libevent-2.0.12-stable/http.c 2011-05-27 19:08:12.000000000 +0000 +++ libevent-2.0.16-stable/http.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2002-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -459,8 +459,8 @@ if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) && evhttp_find_header(req->output_headers, "Content-Length") == NULL){ char size[22]; - evutil_snprintf(size, sizeof(size), "%ld", - (long)evbuffer_get_length(req->output_buffer)); + evutil_snprintf(size, sizeof(size), EV_SIZE_FMT, + EV_SIZE_ARG(evbuffer_get_length(req->output_buffer))); evhttp_add_header(req->output_headers, "Content-Length", size); } } @@ -518,12 +518,13 @@ * unless it already has a content-length or transfer-encoding header. */ static void evhttp_maybe_add_content_length_header(struct evkeyvalq *headers, - long content_length) /* XXX use size_t or int64, not long. */ + size_t content_length) { if (evhttp_find_header(headers, "Transfer-Encoding") == NULL && evhttp_find_header(headers, "Content-Length") == NULL) { char len[22]; - evutil_snprintf(len, sizeof(len), "%ld", content_length); + evutil_snprintf(len, sizeof(len), EV_SIZE_FMT, + EV_SIZE_ARG(content_length)); evhttp_add_header(headers, "Content-Length", len); } } @@ -563,7 +564,7 @@ */ evhttp_maybe_add_content_length_header( req->output_headers, - (long)evbuffer_get_length(req->output_buffer)); + evbuffer_get_length(req->output_buffer)); } } @@ -1076,9 +1077,10 @@ input = bufferevent_get_input(evcon->bufev); total_len = evbuffer_get_length(input); - event_debug(("%s: read %d bytes in EVCON_IDLE state," - " resetting connection", - __func__, (int)total_len)); + event_debug(("%s: read "EV_SIZE_FMT + " bytes in EVCON_IDLE state," + " resetting connection", + __func__, EV_SIZE_ARG(total_len))); #endif evhttp_connection_reset(evcon); @@ -1870,9 +1872,9 @@ req->ntoread = ntoread; } - event_debug(("%s: bytes to read: %ld (in buffer %ld)\n", - __func__, (long)req->ntoread, - evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))); + event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n", + __func__, EV_I64_ARG(req->ntoread), + EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev))))); return (0); } @@ -3203,8 +3205,11 @@ struct evhttp * evhttp_new(struct event_base *base) { - struct evhttp *http = evhttp_new_object(); + struct evhttp *http = NULL; + http = evhttp_new_object(); + if (http == NULL) + return (NULL); http->base = base; return (http); @@ -3217,8 +3222,11 @@ struct evhttp * evhttp_start(const char *address, unsigned short port) { - struct evhttp *http = evhttp_new_object(); + struct evhttp *http = NULL; + http = evhttp_new_object(); + if (http == NULL) + return (NULL); if (evhttp_bind_socket(http, address, port) == -1) { mm_free(http); return (NULL); diff -Nru libevent-2.0.12-stable/http-internal.h libevent-2.0.16-stable/http-internal.h --- libevent-2.0.12-stable/http-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/http-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2001-2007 Niels Provos - * Copyright 2007-2010 Niels Provos and Nick Mathewson + * Copyright 2007-2011 Niels Provos and Nick Mathewson * * This header file contains definitions for dealing with HTTP requests * that are internal to libevent. As user of the library, you should not diff -Nru libevent-2.0.12-stable/include/event2/buffer_compat.h libevent-2.0.16-stable/include/event2/buffer_compat.h --- libevent-2.0.12-stable/include/event2/buffer_compat.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/buffer_compat.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,7 +27,7 @@ #ifndef _EVENT2_BUFFER_COMPAT_H_ #define _EVENT2_BUFFER_COMPAT_H_ -/** @file buffer_compat.h +/** @file event2/buffer_compat.h Obsolete and deprecated versions of the functions in buffer.h: provided only for backward compatibility. diff -Nru libevent-2.0.12-stable/include/event2/bufferevent_compat.h libevent-2.0.16-stable/include/event2/bufferevent_compat.h --- libevent-2.0.12-stable/include/event2/bufferevent_compat.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/bufferevent_compat.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos, Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos, Nick Mathewson * Copyright (c) 2000-2007 Niels Provos * All rights reserved. * @@ -54,6 +54,10 @@ If multiple bases are in use, bufferevent_base_set() must be called before enabling the bufferevent for the first time. + @deprecated This function is deprecated because it uses the current + event base, and as such can be error prone for multithreaded programs. + Use bufferevent_socket_new() instead. + @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 diff -Nru libevent-2.0.12-stable/include/event2/bufferevent.h libevent-2.0.16-stable/include/event2/bufferevent.h --- libevent-2.0.12-stable/include/event2/bufferevent.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/bufferevent.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,27 +27,51 @@ #ifndef _EVENT2_BUFFEREVENT_H_ #define _EVENT2_BUFFEREVENT_H_ -/** @file bufferevent.h +/** + @file event2/bufferevent.h Functions for buffering data for network sending or receiving. Bufferevents are higher level than evbuffers: each has an underlying evbuffer for reading and one for writing, and callbacks that are invoked under certain circumstances. - 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. - + A bufferevent provides input and output buffers that get filled and + drained automatically. The user of a bufferevent 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 reading is enabled, the bufferevent will try to read from the + file descriptor onto its input buffer, and and call the read callback. + When writing is enabled, the bufferevent will try to write data onto its + file descriptor when writing is enabled, and call the write callback + when the output buffer is sufficiently drained. + + Bufferevents come in several flavors, including: + +
+
Socket-based bufferevents
+
A bufferevent that reads and writes data onto a network + socket. Created with bufferevent_socket_new().
+ +
Paired bufferevents
+
A pair of bufferevents that send and receive data to one + another without touching the network. Created with + bufferevent_pair_new().
+ +
Filtering bufferevents
+
A bufferevent that transforms data, and sends or receives it + over another underlying bufferevent. Created with + bufferevent_filter_new().
+ +
SSL-backed bufferevents
+
A bufferevent that uses the openssl library to send and + receive data over an encrypted connection. Created with + bufferevent_openssl_socket_new() or + bufferevent_openssl_filter_new().
+
*/ #ifdef __cplusplus @@ -65,20 +89,36 @@ /* For int types. */ #include -/* Just for error reporting - use other constants otherwise */ +/** @name Bufferevent event codes + + These flags are passed as arguments to a bufferevent's event callback. + + @{ +*/ #define BEV_EVENT_READING 0x01 /**< error encountered while reading */ #define BEV_EVENT_WRITING 0x02 /**< error encountered while writing */ #define BEV_EVENT_EOF 0x10 /**< eof file reached */ #define BEV_EVENT_ERROR 0x20 /**< unrecoverable error encountered */ -#define BEV_EVENT_TIMEOUT 0x40 /**< user specified timeout reached */ +#define BEV_EVENT_TIMEOUT 0x40 /**< user-specified timeout reached */ #define BEV_EVENT_CONNECTED 0x80 /**< connect operation finished. */ -struct bufferevent; +/**@}*/ + +/** + An opaque type for handling buffered IO + + @see event2/bufferevent.h + */ +struct bufferevent +#ifdef _EVENT_IN_DOXYGEN +{} +#endif +; struct event_base; struct evbuffer; struct sockaddr; /** - type definition for the read or write callback. + A read or write callback for a bufferevent. The read callback is triggered when new data arrives in the input buffer and the amount of readable data exceed the low watermark @@ -88,14 +128,14 @@ exhausted or fell below its low watermark. @param bev the bufferevent that triggered the callback - @param ctx the user specified context for this bufferevent + @param ctx the user-specified context for this bufferevent */ typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *ctx); /** - type definition for the error callback of a bufferevent. + An event/error callback for a bufferevent. - The error callback is triggered if either an EOF condition or another + The event callback is triggered if either an EOF condition or another unrecoverable error was encountered. @param bev the bufferevent for which the error condition was reached @@ -104,7 +144,7 @@ and one of the following flags: BEV_EVENT_EOF, BEV_EVENT_ERROR, BEV_EVENT_TIMEOUT, BEV_EVENT_CONNECTED. - @param ctx the user specified context for this bufferevent + @param ctx the user-specified context for this bufferevent */ typedef void (*bufferevent_event_cb)(struct bufferevent *bev, short what, void *ctx); @@ -136,6 +176,7 @@ This file descriptor is not allowed to be a pipe(2). It is safe to set the fd to -1, so long as you later set it with bufferevent_setfd or bufferevent_socket_connect(). + @param options Zero or more BEV_OPT_* flags @return a pointer to a newly allocated bufferevent struct, or NULL if an error occurred @see bufferevent_free() @@ -143,8 +184,10 @@ struct bufferevent *bufferevent_socket_new(struct event_base *base, evutil_socket_t fd, int options); /** - Launch a connect() attempt with a socket. When the connect succeeds, - the eventcb will be invoked with BEV_EVENT_CONNECTED set. + Launch a connect() attempt with a socket-based bufferevent. + + When the connect succeeds, the eventcb will be invoked with + BEV_EVENT_CONNECTED set. If the bufferevent does not already have a socket set, we allocate a new socket here and make it nonblocking before we begin. @@ -188,7 +231,7 @@ may block while it waits for a DNS response. This is probably not what you want. */ -int bufferevent_socket_connect_hostname(struct bufferevent *b, +int bufferevent_socket_connect_hostname(struct bufferevent *, struct evdns_base *, int, const char *, int); /** @@ -383,7 +426,7 @@ short bufferevent_get_enabled(struct bufferevent *bufev); /** - Set the read and write timeout for a buffered event. + Set the read and write timeout for a bufferevent. A bufferevent's timeout will fire the first time that the indicated amount of time has elapsed since a successful read or write operation, @@ -460,8 +503,7 @@ }; /** - Triggers the bufferevent to produce more - data if possible. + Triggers the bufferevent to produce more data if possible. @param bufev the bufferevent object @param iotype either EV_READ or EV_WRITE or both. @@ -473,9 +515,10 @@ enum bufferevent_flush_mode mode); /** - Support for filtering input and output of bufferevents. - */ + @name Filtering support + @{ +*/ /** Values that filters can return. */ @@ -533,6 +576,7 @@ int options, void (*free_context)(void *), void *ctx); +/**@}*/ /** Allocate a pair of linked bufferevents. The bufferevents behave as would @@ -680,13 +724,16 @@ /** Remove 'bev' from its current rate-limit group (if any). */ int bufferevent_remove_from_rate_limit_group(struct bufferevent *bev); -/*@{*/ /** + @name Rate limit inspection + Return the current read or write bucket size for a bufferevent. If it is not configured with a per-bufferevent ratelimit, return EV_SSIZE_MAX. This function does not inspect the group limit, if any. Note that it can return a negative value if the bufferevent has been made to read or write more than its limit. + + @{ */ ev_ssize_t bufferevent_get_read_limit(struct bufferevent *bev); ev_ssize_t bufferevent_get_write_limit(struct bufferevent *bev); @@ -695,11 +742,14 @@ ev_ssize_t bufferevent_get_max_to_read(struct bufferevent *bev); ev_ssize_t bufferevent_get_max_to_write(struct bufferevent *bev); -/*@{*/ /** + @name GrouprRate limit inspection + Return the read or write bucket size for a bufferevent rate limit group. Note that it can return a negative value if bufferevents in the group have been made to read or write more than their limits. + + @{ */ ev_ssize_t bufferevent_rate_limit_group_get_read_limit( struct bufferevent_rate_limit_group *); @@ -707,8 +757,9 @@ struct bufferevent_rate_limit_group *); /*@}*/ -/*@{*/ /** + @name Rate limit manipulation + Subtract a number of bytes from a bufferevent's read or write bucket. The decrement value can be negative, if you want to manually refill the bucket. If the change puts the bucket above or below zero, the @@ -717,13 +768,16 @@ group, if any. Returns 0 on success, -1 on internal error. + + @{ */ int bufferevent_decrement_read_limit(struct bufferevent *bev, ev_ssize_t decr); int bufferevent_decrement_write_limit(struct bufferevent *bev, ev_ssize_t decr); /*@}*/ -/*@{*/ /** + @name Group rate limit manipulation + Subtract a number of bytes from a bufferevent rate-limiting group's read or write bucket. The decrement value can be negative, if you want to manually refill the bucket. If the change puts the bucket @@ -731,6 +785,8 @@ suspend reading writing as appropriate. Returns 0 on success, -1 on internal error. + + @{ */ int bufferevent_rate_limit_group_decrement_read( struct bufferevent_rate_limit_group *, ev_ssize_t); @@ -739,14 +795,20 @@ /*@}*/ -/** Set the variable pointed to by total_read_out to the total number of bytes +/** + * Inspect the total bytes read/written on a group. + * + * Set the variable pointed to by total_read_out to the total number of bytes * ever read on grp, and the variable pointed to by total_written_out to the * total number of bytes ever written on grp. */ void bufferevent_rate_limit_group_get_totals( struct bufferevent_rate_limit_group *grp, ev_uint64_t *total_read_out, ev_uint64_t *total_written_out); -/** Reset the number of bytes read or written on grp as given by +/** + * Reset the total bytes read/written on a group. + * + * Reset the number of bytes read or written on grp as given by * bufferevent_rate_limit_group_reset_totals(). */ void bufferevent_rate_limit_group_reset_totals( diff -Nru libevent-2.0.12-stable/include/event2/bufferevent_ssl.h libevent-2.0.16-stable/include/event2/bufferevent_ssl.h --- libevent-2.0.12-stable/include/event2/bufferevent_ssl.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/bufferevent_ssl.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,7 +26,7 @@ #ifndef _EVENT2_BUFFEREVENT_SSL_H_ #define _EVENT2_BUFFEREVENT_SSL_H_ -/** @file bufferevent_ssl.h +/** @file event2/bufferevent_ssl.h OpenSSL support for bufferevents. */ @@ -39,15 +39,31 @@ extern "C" { #endif +/* This is what openssl's SSL objects are underneath. */ struct ssl_st; +/** + The state of an SSL object to be used when creating a new + SSL bufferevent. + */ enum bufferevent_ssl_state { BUFFEREVENT_SSL_OPEN = 0, BUFFEREVENT_SSL_CONNECTING = 1, BUFFEREVENT_SSL_ACCEPTING = 2 }; -#ifdef _EVENT_HAVE_OPENSSL +#if defined(_EVENT_HAVE_OPENSSL) || defined(_EVENT_IN_DOXYGEN) +/** + Create a new SSL bufferevent to send its data over another bufferevent. + + @param base An event_base to use to detect reading and writing. It + must also be the base for the underlying bufferevent. + @param underlying A socket to use for this SSL + @param ssl A SSL* object from openssl. + @param state The current state of the SSL connection + @param options One or more bufferevent_options + @return A new bufferevent on success, or NULL on failure +*/ struct bufferevent * bufferevent_openssl_filter_new(struct event_base *base, struct bufferevent *underlying, @@ -55,6 +71,16 @@ enum bufferevent_ssl_state state, int options); +/** + Create a new SSL bufferevent to send its data over an SSL * on a socket. + + @param base An event_base to use to detect reading and writing + @param fd A socket to use for this SSL + @param ssl A SSL* object from openssl. + @param state The current state of the SSL connection + @param options One or more bufferevent_options + @return A new bufferevent on success, or NULL on failure. +*/ struct bufferevent * bufferevent_openssl_socket_new(struct event_base *base, evutil_socket_t fd, @@ -62,11 +88,14 @@ enum bufferevent_ssl_state state, int options); +/** Return the underlying openssl SSL * object for an SSL bufferevent. */ struct ssl_st * bufferevent_openssl_get_ssl(struct bufferevent *bufev); +/** Tells a bufferevent to begin SSL renegotiation. */ int bufferevent_ssl_renegotiate(struct bufferevent *bev); +/** Return the most recent OpenSSL error reported on an SSL bufferevent. */ unsigned long bufferevent_get_openssl_error(struct bufferevent *bev); #endif diff -Nru libevent-2.0.12-stable/include/event2/bufferevent_struct.h libevent-2.0.16-stable/include/event2/bufferevent_struct.h --- libevent-2.0.12-stable/include/event2/bufferevent_struct.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/bufferevent_struct.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,14 @@ #ifndef _EVENT2_BUFFEREVENT_STRUCT_H_ #define _EVENT2_BUFFEREVENT_STRUCT_H_ -/** @file bufferevent_struct.h +/** @file event2/bufferevent_struct.h Data structures for bufferevents. Using these structures may hurt forward compatibility with later versions of Libevent: be careful! + @deprecated Use of bufferevent_struct.h is completely deprecated; these + structures are only exposed for backward compatibility with programs + written before Libevent 2.0 that used them. */ #ifdef __cplusplus diff -Nru libevent-2.0.12-stable/include/event2/buffer.h libevent-2.0.16-stable/include/event2/buffer.h --- libevent-2.0.12-stable/include/event2/buffer.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/buffer.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,20 +26,22 @@ #ifndef _EVENT2_BUFFER_H_ #define _EVENT2_BUFFER_H_ -/** @file buffer.h +/** @file event2/buffer.h Functions for buffering data for network sending or receiving. An evbuffer can be used for preparing data before sending it to the network or conversely for reading data from the network. Evbuffers try to avoid memory copies as much as possible. As a - result evbuffers can be used to pass data around without actually + result, evbuffers can be used to pass data around without actually incurring the overhead of copying the data. A new evbuffer can be allocated with evbuffer_new(), and can be - freed with evbuffer_free(). + freed with evbuffer_free(). Most users will be using evbuffers via + the bufferevent interface. To access a bufferevent's evbuffers, use + bufferevent_get_input() and bufferevent_get_output(). - There are several guide lines for using evbuffers. + There are several guidelines for using evbuffers. - if you already know how much data you are going to add as a result of calling evbuffer_add() multiple times, it makes sense to use @@ -53,12 +55,21 @@ if you use them, you will wind up with fragmented memory in your buffer. - As the contents of an evbuffer can be stored into multiple different + - For high-performance code, you may want to avoid copying data into and out + of buffers. You can skip the copy step by using + evbuffer_reserve_space()/evbuffer_commit_space() when writing into a + buffer, and evbuffer_peek() when reading. + + In Libevent 2.0 and later, evbuffers are represented using a linked + list of memory chunks, with pointers to the first and last chunk in + the chain. + + As the contents of an evbuffer can be stored in multiple different memory blocks, it cannot be accessed directly. Instead, evbuffer_pullup() - can be used to force a specified number of bytes to be continuous. This + can be used to force a specified number of bytes to be contiguous. This will cause memory reallocation and memory copies if the data is split - across multiple blocks. - + across multiple blocks. It is more efficient, however, to use + evbuffer_peek() if you don't require that the memory to be contiguous. */ #ifdef __cplusplus @@ -75,12 +86,25 @@ #endif #include -struct evbuffer; +/** + An evbuffer is an opaque data type for efficiently buffering data to be + sent or received on the network. + + @see event2/event.h for more information +*/ +struct evbuffer +#ifdef _EVENT_IN_DOXYGEN +{} +#endif +; -/** Points to a position within an evbuffer. Used when repeatedly searching - through a buffer. Calls to any function that modifies or re-packs the - buffer contents may invalidate all evbuffer_ptrs for that buffer. Do not - modify these values except with evbuffer_ptr_set. +/** + Pointer to a position within an evbuffer. + + Used when repeatedly searching through a buffer. Calling any function + that modifies or re-packs the buffer contents may invalidate all + evbuffer_ptrs for that buffer. Do not modify these values except with + evbuffer_ptr_set. */ struct evbuffer_ptr { ev_ssize_t pos; @@ -117,8 +141,6 @@ occurred */ struct evbuffer *evbuffer_new(void); - - /** Deallocate storage for an evbuffer. @@ -152,11 +174,46 @@ */ void evbuffer_unlock(struct evbuffer *buf); + +/** If this flag is set, then we will not use evbuffer_peek(), + * evbuffer_remove(), evbuffer_remove_buffer(), and so on to read bytes + * from this buffer: we'll only take bytes out of this buffer by + * writing them to the network (as with evbuffer_write_atmost), by + * removing them without observing them (as with evbuffer_drain), + * or by copying them all out at once (as with evbuffer_add_buffer). + * + * Using this option allows the implementation to use sendfile-based + * operations for evbuffer_add_file(); see that function for more + * information. + * + * This flag is on by default for bufferevents that can take advantage + * of it; you should never actually need to set it on a bufferevent's + * output buffer. + */ +#define EVBUFFER_FLAG_DRAINS_TO_FD 1 + +/** Change the flags that are set for an evbuffer by adding more. + * + * @param buffer the evbuffer that the callback is watching. + * @param cb the callback whose status we want to change. + * @param flags One or more EVBUFFER_FLAG_* options + * @return 0 on success, -1 on failure. + */ +int evbuffer_set_flags(struct evbuffer *buf, ev_uint64_t flags); +/** Change the flags that are set for an evbuffer by removing some. + * + * @param buffer the evbuffer that the callback is watching. + * @param cb the callback whose status we want to change. + * @param flags One or more EVBUFFER_FLAG_* options + * @return 0 on success, -1 on failure. + */ +int evbuffer_clear_flags(struct evbuffer *buf, ev_uint64_t flags); + /** - Returns the total number of bytes stored in the event buffer + Returns the total number of bytes stored in the evbuffer @param buf pointer to the evbuffer - @return the number of bytes stored in the event buffer + @return the number of bytes stored in the evbuffer */ size_t evbuffer_get_length(const struct evbuffer *buf); @@ -175,28 +232,28 @@ size_t evbuffer_get_contiguous_space(const struct evbuffer *buf); /** - Expands the available space in an event buffer. + Expands the available space in an evbuffer. - Expands the available space in the event buffer to at least datlen, so that + Expands the available space in the evbuffer to at least datlen, so that appending datlen additional bytes will not require any new allocations. - @param buf the event buffer to be expanded + @param buf the evbuffer 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 *buf, size_t datlen); /** - Reserves space in the last chain of an event buffer. + Reserves space in the last chain or chains of an evbuffer. - Makes space available in the last chain of an event buffer that can + Makes space available in the last chain or chains of an evbuffer that can be arbitrarily written to by a user. The space does not become available for reading until it has been committed with evbuffer_commit_space(). The space is made available as one or more extents, represented by an initial pointer and a length. You can force the memory to be - available as only one extent. Allowing more, however, makes the + available as only one extent. Allowing more extents, however, makes the function more efficient. Multiple subsequent calls to this function will make the same space @@ -208,19 +265,20 @@ NOTE: The code currently does not ever use more than two extents. This may change in future versions. - @param buf the event buffer in which to reserve space. + @param buf the evbuffer in which to reserve space. @param size how much space to make available, at minimum. The total length of the extents may be greater than the requested length. @param vec an array of one or more evbuffer_iovec structures to hold pointers to the reserved extents of memory. - @param n_vec The length of the vec array. Must be at least 1. + @param n_vec The length of the vec array. Must be at least 1; + 2 is more efficient. @return the number of provided extents, or -1 on error. - @see evbuffer_commit_space + @see evbuffer_commit_space() */ int evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size, - struct evbuffer_iovec *vec, int n_vecs); + struct evbuffer_iovec *vec, int n_vec); /** Commits previously reserved space. @@ -233,15 +291,15 @@ has been added to the buffer since the space was reserved. If you want to commit less data than you got reserved space for, - modify the iov_len pointer of the buffer to a smaller value. Note - that you may have received more space than you requested if it was - available! + modify the iov_len pointer of the appropriate extent to a smaller + value. Note that you may have received more space than you + requested if it was available! - @param buf the event buffer in which to reserve space. + @param buf the evbuffer in which to reserve space. @param vec one or two extents returned by evbuffer_reserve_space. @param n_vecs the number of extents. @return 0 on success, -1 on error - @see evbuffer_reserve_space + @see evbuffer_reserve_space() */ int evbuffer_commit_space(struct evbuffer *buf, struct evbuffer_iovec *vec, int n_vecs); @@ -249,7 +307,7 @@ /** Append data to the end of an evbuffer. - @param buf the event buffer to be appended to + @param buf the evbuffer 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 @return 0 on success, -1 on failure. @@ -258,9 +316,12 @@ /** - Read data from an event buffer and drain the bytes read. + Read data from an evbuffer and drain the bytes read. - @param buf the event buffer to be read from + If more bytes are requested than are available in the evbuffer, we + only extract as many bytes as were available. + + @param buf the evbuffer 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, or -1 if we can't drain the buffer. @@ -268,22 +329,28 @@ int evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen); /** - Read data from an event buffer, and leave the buffer unchanged. + Read data from an evbuffer, and leave the buffer unchanged. - @param buf the event buffer to be read from - @param data the destination buffer to store the result + If more bytes are requested than are available in the evbuffer, we + only extract as many bytes as were available. + + @param buf the evbuffer to be read from + @param data_out the destination buffer to store the result @param datlen the maximum size of the destination buffer @return the number of bytes read, or -1 if we can't drain the buffer. */ ev_ssize_t evbuffer_copyout(struct evbuffer *buf, void *data_out, size_t datlen); /** - Read data from an event buffer into another event buffer draining - the bytes from the src buffer read. This function avoids memcpy - as possible. + Read data from an evbuffer into another evbuffer, draining + the bytes from the source buffer. This function avoids copy + operations to the extent possible. - @param src the event buffer to be read from - @param dst the destination event buffer to store the result into + If more bytes are requested than are available in src, the src + buffer is drained completely. + + @param src the evbuffer to be read from + @param dst the destination evbuffer to store the result into @param datlen the maximum numbers of bytes to transfer @return the number of bytes read */ @@ -293,7 +360,15 @@ /** 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. */ + /** Any sequence of CR and LF characters is acceptable as an + * EOL. + * + * Note that this style can produce ambiguous results: the + * sequence "CRLF" will be treated as a single EOL if it is + * all in the buffer at once, but if you first read a CR from + * the network and later read an LF from the network, it will + * be treated as two EOLs. + */ EVBUFFER_EOL_ANY, /** An EOL is an LF, optionally preceded by a CR. This style is * most useful for implementing text-based internet protocols. */ @@ -305,7 +380,7 @@ }; /** - * Read a single line from an event buffer. + * Read a single line from an evbuffer. * * 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 @@ -322,7 +397,7 @@ enum evbuffer_eol_style eol_style); /** - Move data from one evbuffer into another evbuffer. + Move all data from one evbuffer into another evbuffer. This is a destructive add. The data from one buffer moves into the other buffer. However, no unnecessary memory copies occur. @@ -330,10 +405,17 @@ @param outbuf the output buffer @param inbuf the input buffer @return 0 if successful, or -1 if an error occurred + + @see evbuffer_remove_buffer() */ int evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf); +/** + A cleanup function for a piece of memory added to an evbuffer by + reference. + @see evbuffer_add_reference() + */ typedef void (*evbuffer_ref_cleanup_cb)(const void *data, size_t datalen, void *extra); @@ -348,44 +430,49 @@ @param data the memory to reference @param datlen how memory to reference @param cleanupfn callback to be invoked when the memory is no longer - referenced - @param extra optional argument to the cleanup callback + referenced by this evbuffer. + @param cleanupfn_arg optional argument to the cleanup callback @return 0 if successful, or -1 if an error occurred */ int evbuffer_add_reference(struct evbuffer *outbuf, const void *data, size_t datlen, - evbuffer_ref_cleanup_cb cleanupfn, void *extra); + evbuffer_ref_cleanup_cb cleanupfn, void *cleanupfn_arg); /** - Move data from a file into the evbuffer for writing to a socket. + Copy data from a file into the evbuffer for writing to a socket. This function avoids unnecessary data copies between userland and - kernel. Where available, it uses sendfile or splice. + kernel. If sendfile is available and the EVBUFFER_FLAG_DRAINS_TO_FD + flag is set, it uses those functions. Otherwise, it tries to use + mmap (or CreateFileMapping on Windows). The function owns the resulting file descriptor and will close it when finished transferring data. - The results of using evbuffer_remove() or evbuffer_pullup() are - undefined. + The results of using evbuffer_remove() or evbuffer_pullup() on + evbuffers whose data was added using this function are undefined. @param outbuf the output buffer @param fd the file descriptor - @param off the offset from which to read data + @param offset the offset from which to read data @param length how much data to read @return 0 if successful, or -1 if an error occurred */ -int evbuffer_add_file(struct evbuffer *output, int fd, ev_off_t offset, +int evbuffer_add_file(struct evbuffer *outbuf, int fd, ev_off_t offset, ev_off_t length); /** Append a formatted string to the end of an evbuffer. + The string is formated as printf. + @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. + @see evutil_printf(), evbuffer_add_vprintf() */ int evbuffer_add_printf(struct evbuffer *buf, const char *fmt, ...) #ifdef __GNUC__ @@ -393,7 +480,6 @@ #endif ; - /** Append a va_list formatted string to the end of an evbuffer. @@ -445,7 +531,7 @@ /** Read from a file descriptor and store the result in an evbuffer. - @param buf the evbuffer to store the result + @param buffer 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 @@ -482,6 +568,10 @@ */ struct evbuffer_ptr evbuffer_search_range(struct evbuffer *buffer, const char *what, size_t len, const struct evbuffer_ptr *start, const struct evbuffer_ptr *end); +/** + Defines how to adjust an evbuffer_ptr by evbuffer_ptr_set() + + @see evbuffer_ptr_set() */ enum evbuffer_ptr_how { /** Sets the pointer to the position; can be called on with an uninitialized evbuffer_ptr. */ @@ -503,7 +593,7 @@ @returns 0 on success or -1 otherwise */ int -evbuffer_ptr_set(struct evbuffer *buffer, struct evbuffer_ptr *pos, +evbuffer_ptr_set(struct evbuffer *buffer, struct evbuffer_ptr *ptr, size_t position, enum evbuffer_ptr_how how); /** @@ -524,14 +614,6 @@ struct evbuffer_ptr *start, size_t *eol_len_out, enum evbuffer_eol_style eol_style); -/** Structure passed to an evbuffer callback */ -struct evbuffer_cb_info { - /** The size of */ - size_t orig_size; - size_t n_added; - size_t n_deleted; -}; - /** Function to peek at data inside an evbuffer without removing it or copying it out. @@ -562,6 +644,21 @@ struct evbuffer_ptr *start_at, struct evbuffer_iovec *vec_out, int n_vec); + +/** Structure passed to an evbuffer_cb_func evbuffer callback + + @see evbuffer_cb_func, evbuffer_add_cb() + */ +struct evbuffer_cb_info { + /** The number of bytes in this evbuffer when callbacks were last + * invoked. */ + size_t orig_size; + /** The number of bytes added since callbacks were last invoked. */ + size_t n_added; + /** The number of bytes removed since callbacks were last invoked. */ + size_t n_deleted; +}; + /** Type definition for a callback that is invoked whenever data is added or removed from an evbuffer. @@ -617,7 +714,10 @@ int evbuffer_remove_cb(struct evbuffer *buffer, evbuffer_cb_func cb, void *cbarg); /** If this flag is not set, then a callback is temporarily disabled, and - * should not be invoked. */ + * should not be invoked. + * + * @see evbuffer_cb_set_flags(), evbuffer_cb_clear_flags() + */ #define EVBUFFER_CB_ENABLED 1 /** Change the flags that are set for a callback on a buffer by adding more. diff -Nru libevent-2.0.12-stable/include/event2/dns_compat.h libevent-2.0.16-stable/include/event2/dns_compat.h --- libevent-2.0.12-stable/include/event2/dns_compat.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/dns_compat.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2006-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,12 @@ #ifndef _EVENT2_DNS_COMPAT_H_ #define _EVENT2_DNS_COMPAT_H_ -/** @file dns_compat.h +/** @file event2/dns_compat.h Potentially non-threadsafe versions of the functions in dns.h: provided only for backwards compatibility. + */ #ifdef __cplusplus diff -Nru libevent-2.0.12-stable/include/event2/dns.h libevent-2.0.16-stable/include/event2/dns.h --- libevent-2.0.12-stable/include/event2/dns.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/dns.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2006-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -47,7 +47,7 @@ * the source verbatim in their source distributions) */ -/** @file dns.h +/** @file event2/dns.h * * Welcome, gentle reader * @@ -166,6 +166,10 @@ #define DNS_ERR_SHUTDOWN 68 /** The request was canceled via a call to evdns_cancel_request */ #define DNS_ERR_CANCEL 69 +/** There were no answers and no error condition in the DNS packet. + * This can happen when you ask for an address that exists, but a record + * type that doesn't. */ +#define DNS_ERR_NODATA 70 #define DNS_IPv4_A 1 #define DNS_PTR 2 @@ -206,7 +210,7 @@ @param event_base the event base to associate the dns client with @param initialize_nameservers 1 if resolve.conf processing should occur - @return 0 if successful, or -1 if an error occurred + @return evdns_base object if successful, or NULL if an error occurred. @see evdns_base_free() */ struct evdns_base * evdns_base_new(struct event_base *event_base, int initialize_nameservers); @@ -266,7 +270,7 @@ /** Remove all configured nameservers, and suspend all pending resolves. - Resolves will not necessarily be re-attempted until evdns_resume() is called. + Resolves will not necessarily be re-attempted until evdns_base_resume() is called. @param base the evdns_base to which to apply this operation @return 0 if successful, or -1 if an error occurred @@ -279,7 +283,7 @@ Resume normal operation and continue any suspended resolve requests. Re-attempt resolves left in limbo after an earlier call to - evdns_clear_nameservers_and_suspend(). + evdns_base_clear_nameservers_and_suspend(). @param base the evdns_base to which to apply this operation @return 0 if successful, or -1 if an error occurred @@ -377,7 +381,7 @@ @param base the evdns_base that was used to make the request @param req the evdns_request that was returned by calling a resolve function - @see evdns_base_resolve_ip4(), evdns_base_resolve_ipv6, evdns_base_resolve_reverse + @see evdns_base_resolve_ipv4(), evdns_base_resolve_ipv6, evdns_base_resolve_reverse */ void evdns_cancel_request(struct evdns_base *base, struct evdns_request *req); diff -Nru libevent-2.0.12-stable/include/event2/dns_struct.h libevent-2.0.16-stable/include/event2/dns_struct.h --- libevent-2.0.12-stable/include/event2/dns_struct.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/dns_struct.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,7 +27,7 @@ #ifndef _EVENT2_DNS_STRUCT_H_ #define _EVENT2_DNS_STRUCT_H_ -/** @file dns_struct.h +/** @file event2/dns_struct.h Data structures for dns. Using these structures may hurt forward compatibility with later versions of Libevent: be careful! diff -Nru libevent-2.0.12-stable/include/event2/event_compat.h libevent-2.0.16-stable/include/event2/event_compat.h --- libevent-2.0.12-stable/include/event2/event_compat.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/event_compat.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,19 @@ #ifndef _EVENT2_EVENT_COMPAT_H_ #define _EVENT2_EVENT_COMPAT_H_ -/** @file event_compat.h +/** @file event2/event_compat.h Potentially non-threadsafe versions of the functions in event.h: provided only for backwards compatibility. + In the oldest versions of Libevent, event_base was not a first-class + structure. Instead, there was a single event base that every function + manipulated. Later, when separate event bases were added, the old functions + that didn't take an event_base argument needed to work by manipulating the + "current" event base. This could lead to thread-safety issues, and obscure, + hard-to-diagnose bugs. + + @deprecated All functions in this file are by definition deprecated. */ #ifdef __cplusplus @@ -67,31 +75,26 @@ /** 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. + Like event_base_dispatch(), but uses the "current" base. @deprecated This function is deprecated because it is easily confused by multiple calls to event_init(), and because it is not safe for multithreaded use. The replacement is event_base_dispatch(). - @see event_base_dispatch() + @see event_base_dispatch(), event_init() */ int event_dispatch(void); /** Handle events. - This is a more flexible version of event_dispatch(). + This function behaves like event_base_loop(), but uses the "current" base @deprecated This function is deprecated because it uses the event base from the last call to event_init, and is therefore not safe for multithreaded use. The replacement is event_base_loop(). - @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_base_loopexit(), event_base_loop() + @see event_base_loop(), event_init() */ int event_loop(int); @@ -99,19 +102,14 @@ /** 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. + This function behaves like event_base_loopexit(), except that it uses the + "current" base. - @deprecated This function is deprecated because it is easily confused by - multiple calls to event_init(), and because it is not safe for - multithreaded use. The replacement is event_base_loopexit(). + @deprecated This function is deprecated because it uses the event base from + the last call to event_init, and is therefore not safe for multithreaded + use. The replacement is event_base_loopexit(). - @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() + @see event_init, event_base_loopexit() */ int event_loopexit(const struct timeval *); @@ -119,42 +117,25 @@ /** 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. + This function behaves like event_base_loopbreakt(), except that it uses the + "current" base. - @deprecated This function is deprecated because it is easily confused by - multiple calls to event_init(), and because it is not safe for - multithreaded use. The replacement is event_base_loopbreak(). + @deprecated This function is deprecated because it uses the event base from + the last call to event_init, and is therefore not safe for multithreaded + use. The replacement is event_base_loopbreak(). - @return 0 if successful, or -1 if an error occurred - @see event_base_loopbreak(), event_loopexit() + @see event_base_loopbreak(), event_init() */ int event_loopbreak(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. - - @deprecated This function is deprecated because it is easily confused by - multiple calls to event_init(), and because it is not safe for - multithreaded use. The replacement is event_base_once(). - - @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() + @deprecated This function is obsolete, and has been replaced by + event_base_once(). Its use is deprecated because it relies on the + "current" base configured by event_init(). + @see event_base_once() */ int event_once(evutil_socket_t , short, void (*)(evutil_socket_t, short, void *), void *, const struct timeval *); @@ -163,11 +144,11 @@ /** Get the kernel event notification mechanism used by Libevent. - @return a string identifying the kernel event mechanism (kqueue, epoll, etc.) + @deprecated This function is obsolete, and has been replaced by + event_base_get_method(). Its use is deprecated because it relies on the + "current" base configured by event_init(). - @deprecated This function is deprecated because it is easily confused by - multiple calls to event_init(), and because it is not safe for - multithreaded use. The replacement is event_base_get_method(). + @see event_base_get_method() */ const char *event_get_method(void); @@ -175,61 +156,19 @@ /** 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. - @deprecated This function is deprecated because it is easily confused by multiple calls to event_init(), and because it is not safe for multithreaded use. The replacement is event_base_priority_init(). - @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() - + @see event_base_priority_init() */ int event_priority_init(int); /** 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. - - For read and write events, edge-triggered behavior can be requested - with the EV_ET flag. Not all backends support edge-triggered - behavior. When an edge-triggered event is activated, the EV_ET flag - is added to its events argument. - - @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() - @deprecated event_set() is not recommended for new code, because it requires - a subsequent call to event_base_set() to be safe under many circumstances. + a subsequent call to event_base_set() to be safe under most circumstances. Use event_assign() or event_new() instead. */ void event_set(struct event *, evutil_socket_t, short, void (*)(evutil_socket_t, short, void *), void *); @@ -240,76 +179,33 @@ /** - * Add a timeout event. - * - * @param ev the event struct to be disabled - * @param tv the timeout value, in seconds - * - * @deprecated This macro is deprecated because its naming is inconsistent. - * The recommend macro is evtimer_add(). - */ -#define timeout_add(ev, tv) event_add((ev), (tv)) - + @name timeout_* macros -/** - * 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 - * - * @deprecated This macro is deprecated because its naming is inconsistent. - * The recommend macro is evtimer_set(). + @deprecated These macros are deprecated because their naming is inconsistent + with the rest of Libevent. Use the evtimer_* macros instead. + @{ */ +#define timeout_add(ev, tv) event_add((ev), (tv)) #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 - * - * @deprecated This macro is deprecated because its naming is inconsistent. - * The recommend macro is evtimer_del(). - */ #define timeout_del(ev) event_del(ev) - -/** - @deprecated This macro is deprecated because its naming is inconsistent. - The recommend macro is evtimer_pending(). -*/ #define timeout_pending(ev, tv) event_pending((ev), EV_TIMEOUT, (tv)) -/** - @deprecated This macro is deprecated because its naming is inconsistent. - The recommend macro is evtimer_initialized(). -*/ #define timeout_initialized(ev) event_initialized(ev) +/**@}*/ /** - @deprecated This macro is deprecated because its naming is inconsistent. - The recommend macro is evsignal_add(). -*/ + @name signal_* macros + + @deprecated These macros are deprecated because their naming is inconsistent + with the rest of Libevent. Use the evsignal_* macros instead. + @{ + */ #define signal_add(ev, tv) event_add((ev), (tv)) -/** - @deprecated This macro is deprecated because its naming is inconsistent. - The recommend macro is evsignal_set(). -*/ #define signal_set(ev, x, cb, arg) \ event_set((ev), (x), EV_SIGNAL|EV_PERSIST, (cb), (arg)) -/** - @deprecated This macro is deprecated because its naming is inconsistent. - The recommend macro is evsignal_del(). -*/ #define signal_del(ev) event_del(ev) -/** - @deprecated This macro is deprecated because its naming is inconsistent. - The recommend macro is evsignal_pending(). -*/ #define signal_pending(ev, tv) event_pending((ev), EV_SIGNAL, (tv)) -/** - @deprecated This macro is deprecated because its naming is inconsistent. - The recommend macro is evsignal_initialized(). -*/ #define signal_initialized(ev) event_initialized(ev) +/**@}*/ #ifndef EVENT_FD /* These macros are obsolete; use event_get_fd and event_get_signal instead. */ diff -Nru libevent-2.0.12-stable/include/event2/event.h libevent-2.0.16-stable/include/event2/event.h --- libevent-2.0.12-stable/include/event2/event.h 2011-05-03 18:14:46.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/event.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,10 +27,157 @@ #ifndef _EVENT2_EVENT_H_ #define _EVENT2_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), + epoll(4), and evports. 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 multithreaded programs. Libevent + should compile on Linux, *BSD, Mac OS X, Solaris and, Windows. + + @section usage Standard usage + + Every program that uses Libevent must inclurde the + header, and pass the -levent flag to the linker. (You can instead link + -levent_core if you only want the main event and buffered IO-based code, + and don't want to link any protocol code.) + + @section setup Library setup + + Before you call any other Libevent functions, you need to set up the + library. If you're going to use Libevent from multiple threads in a + multithreaded application, you need to initialize thread support -- + typically by using evthread_use_pthreads() or + evthread_use_windows_threads(). See for more + information. + + This is also the point where you can replace Libevent's memory + management functions with event_set_mem_functions, and enable debug mode + with event_enable_debug_mode(). + + @section base Creating an event base + + Next, you need to create an event_base structure, using event_base_new() + or event_base_new_with_config(). The event_base is responsible for + keeping track of which events are "pending" (that is to say, being + watched to see if they become active) and which events are "active". + Every event is associated with a single event_base. + + @section event Event notification + + For each file descriptor that you wish to monitor, you must create an + event structure with event_new(). (You may also declare an event + structure and call event_assign() 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 generally be + allocated on the heap. + + @section loop Dispaching evets. + + Finally, you call event_base_dispatch() to loop and dispatch events. + You can also use event_base_loop() for more fine-grained control. + + Currently, only one thread can be dispatching a given event_base at a + time. If you want to run events in multiple threads at once, you can + either have a single event_base whose events add work to a work queue, + or you can create multiple event_base objects. + + @section bufferevent I/O Buffers + + Libevent provides a buffered I/O abstraction on top of the regular event + callbacks. This abstraction is called a bufferevent. A bufferevent + 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_socket_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. + + See for more information. + + @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_new() function returns + an event struct to use as a timer. To activate the timer, call + evtimer_add(). Timers can be deactivated by calling evtimer_del(). + + @section evdns Asynchronous DNS resolution + + Libevent provides an asynchronous DNS resolver that should be used instead + of the standard DNS resolver functions. See the + functions for more detail. + + @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 header in your + program. See that header for more information. + + @section evrpc A framework for RPC servers and clients + + Libevent 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. + + event2/event.h + The primary libevent header + + event2/thread.h + Functions for use by multithreaded programs + + event2/buffer.h and event2/bufferevent.h + Buffer management for network reading and writing + + event2/util.h + Utility functions for portable nonblocking network code + + event2/dns.h + Asynchronous DNS resolution + + event2/http.h + An embedded libevent-based HTTP server + + event2/rpc.h + A framework for creating RPC servers and clients + + */ + /** @file event2/event.h Core functions for waiting for and receiving events, and using event bases. - */ #ifdef __cplusplus @@ -50,15 +197,109 @@ /* For int types. */ #include -struct event_base; -struct event; -struct event_config; - -/** Enable some relatively expensive debugging checks in Libevent that would - * normally be turned off. Generally, these cause code that would otherwise - * crash mysteriously to fail earlier with an assertion failure. Note that - * this method MUST be called before any events or event_bases have been - * created. +/** + * Structure to hold information and state for a Libevent dispatch loop. + * + * The event_base lies at the center of Libevent; every application will + * have one. It keeps track of all pending and active events, and + * notifies your application of the active ones. + * + * This is an opaque structure; you can allocate one using + * event_base_new() or event_base_new_with_config(). + * + * @see event_base_new(), event_base_free(), event_base_loop(), + * event_base_new_with_config() + */ +struct event_base +#ifdef _EVENT_IN_DOXYGEN +{/*Empty body so that doxygen will generate documentation here.*/} +#endif +; + +/** + * @struct event + * + * Structure to represent a single event. + * + * An event can have some underlying condition it represents: a socket + * becoming readable or writeable (or both), or a signal becoming raised. + * (An event that represents no underlying condition is still useful: you + * can use one to implement a timer, or to communicate between threads.) + * + * Generally, you can create events with event_new(), then make them + * pending with event_add(). As your event_base runs, it will run the + * callbacks of an events whose conditions are triggered. When you + * longer want the event, free it with event_free(). + * + * In more depth: + * + * An event may be "pending" (one whose condition we are watching), + * "active" (one whose condition has triggered and whose callback is about + * to run), neither, or both. Events come into existence via + * event_assign() or event_new(), and are then neither active nor pending. + * + * To make an event pending, pass it to event_add(). When doing so, you + * can also set a timeout for the event. + * + * Events become active during an event_base_loop() call when either their + * condition has triggered, or when their timeout has elapsed. You can + * also activate an event manually using event_active(). The even_base + * loop will run the callbacks of active events; after it has done so, it + * marks them as no longer active. + * + * You can make an event non-pending by passing it to event_del(). This + * also makes the event non-active. + * + * Events can be "persistent" or "non-persistent". A non-persistent event + * becomes non-pending as soon as it is triggered: thus, it only runs at + * most once per call to event_add(). A persistent event remains pending + * even when it becomes active: you'll need to event_del() it manually in + * order to make it non-pending. When a persistent event with a timeout + * becomes active, its timeout is reset: this means you can use persistent + * events to implement periodic timeouts. + * + * This should be treated as an opaque structure; you should never read or + * write any of its fields directly. For backward compatibility with old + * code, it is defined in the event2/event_struct.h header; including this + * header may make your code incompatible with other versions of Libevent. + * + * @see event_new(), event_free(), event_assign(), event_get_assignment(), + * event_add(), event_del(), event_active(), event_pending(), + * event_get_fd(), event_get_base(), event_get_events(), + * event_get_callback(), event_get_callback_arg(), + * event_priority_set() + */ +struct event +#ifdef _EVENT_IN_DOXYGEN +{/*Empty body so that doxygen will generate documentation here.*/} +#endif +; + +/** + * Configuration for an event_base. + * + * There are many options that can be used to alter the behavior and + * implementation of an event_base. To avoid having to pass them all in a + * complex many-argument constructor, we provide an abstract data type + * wrhere you set up configation information before passing it to + * event_base_new_with_config(). + * + * @see event_config_new(), event_config_free(), event_base_new_with_config(), + * event_config_avoid_method(), event_config_require_features(), + * event_config_set_flag(), event_config_set_num_cpus_hint() + */ +struct event_config +#ifdef _EVENT_IN_DOXYGEN +{/*Empty body so that doxygen will generate documentation here.*/} +#endif +; + +/** + * Enable some relatively expensive debugging checks in Libevent that + * would normally be turned off. Generally, these checks cause code that + * would otherwise crash mysteriously to fail earlier with an assertion + * failure. Note that this method MUST be called before any events or + * event_bases have been created. * * Debug mode can currently catch the following errors: * An event is re-assigned while it is added @@ -70,6 +311,8 @@ * debug mode, and you find yourself running out of memory, you will need * to use event_debug_unassign to explicitly stop tracking events that * are no longer considered set-up. + * + * @see event_debug_unassign() */ void event_enable_debug_mode(void); @@ -79,40 +322,44 @@ * nothing. * * This function must only be called on a non-added event. + * + * @see event_enable_debug_mode() */ void event_debug_unassign(struct event *); /** - Initialize the event API. - - Use event_base_new() to initialize a new event base. - - @see event_base_set(), event_base_free(), - event_base_new_with_config() + * Create and return a new event_base to use with the rest of Libevent. + * + * @return a new event_base on success, or NULL on failure. + * + * @see event_base_free(), event_base_new_with_config() */ struct event_base *event_base_new(void); /** - Reinitialized the event base after a fork + Reinitialize 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() + @see event_base_new() */ int event_reinit(struct event_base *base); /** - Threadsafe event dispatching loop. + Event dispatching loop This loop will run the event base until either there are no more added events, or until something calls event_base_loopbreak() or - evenet_base_loopexit(). + event_base_loopexit(). - @param eb the event_base structure returned by event_init() - @see event_init(), event_dispatch() + @param base the event_base structure returned by event_base_new() or + event_base_new_with_config() + @return 0 if successful, -1 if an error occurred, or 1 if no events were + registered. + @see event_base_loop() */ int event_base_dispatch(struct event_base *); @@ -144,10 +391,10 @@ The event configuration object can be used to change the behavior of an event base. - @return an event_config object that can be used to store configuration or - NULL when an error is encountered. + @return an event_config object that can be used to store configuration, or + NULL if an error is encountered. + @see event_base_new_with_config(), event_config_free(), event_config */ - struct event_config *event_config_new(void); /** @@ -161,28 +408,46 @@ Enters an event method that should be avoided into the configuration. This can be used to avoid event mechanisms that do not support certain - file descriptor types. An application can make use of multiple event - bases to accommodate incompatible file descriptor types. + file descriptor types, or for debugging to avoid certain event + mechanisms. An application can make use of multiple event bases to + accommodate incompatible file descriptor types. @param cfg the event configuration object - @param method the event method to avoid + @param method the name of the event method to avoid @return 0 on success, -1 on failure. */ int event_config_avoid_method(struct event_config *cfg, const char *method); +/** + A flag used to describe which features an event_base (must) provide. + + Because of OS limitations, not every Libevent backend supports every + possible feature. You can use this type with + event_config_require_features() to tell Libevent to only proceed if your + event_base implements a given feature, and you can receive this type from + event_base_get_features() to see which features are available. +*/ enum event_method_feature { - /* Require an event method that allows edge-triggered events with EV_ET. */ + /** Require an event method that allows edge-triggered events with EV_ET. */ EV_FEATURE_ET = 0x01, - /* Require an event method where having one event triggered among + /** Require an event method where having one event triggered among * many is [approximately] an O(1) operation. This excludes (for * example) select and poll, which are approximately O(N) for N * equal to the total number of possible events. */ EV_FEATURE_O1 = 0x02, - /* Require an event method that allows file descriptors as well as + /** Require an event method that allows file descriptors as well as * sockets. */ EV_FEATURE_FDS = 0x04 }; +/** + A flag passed to event_config_set_flag(). + + These flags change the behavior of an allocated event_base. + + @see event_config_set_flag(), event_base_new_with_config(), + event_method_feature + */ enum event_base_config_flag { /** Do not allocate a lock for the event base, even if we have locking set up. */ @@ -190,7 +455,12 @@ /** Do not check the EVENT_* environment variables when configuring an event_base */ EVENT_BASE_FLAG_IGNORE_ENV = 0x02, - /** Windows only: enable the IOCP dispatcher at startup */ + /** Windows only: enable the IOCP dispatcher at startup + + If this flag is set then bufferevent_socket_new() and + evconn_listener_new() will use IOCP-backed implementations + instead of the usual select-based one on Windows. + */ EVENT_BASE_FLAG_STARTUP_IOCP = 0x04, /** Instead of checking the current time every time the event loop is ready to run timeout callbacks, check after each timeout callback. @@ -215,7 +485,11 @@ }; /** - Return a bitmask of the features implemented by an event base. + Return a bitmask of the features implemented by an event base. This + will be a bitwise OR of one or more of the values of + event_method_feature + + @see event_method_feature */ int event_base_get_features(const struct event_base *base); @@ -239,11 +513,16 @@ @param feature a bitfield of one or more event_method_feature values. Replaces values from previous calls to this function. @return 0 on success, -1 on failure. + @see event_method_feature, event_base_new_with_config() */ int event_config_require_features(struct event_config *cfg, int feature); -/** Sets one or more flags to configure what parts of the eventual event_base - * will be initialized, and how they'll work. */ +/** + * Sets one or more flags to configure what parts of the eventual event_base + * will be initialized, and how they'll work. + * + * @see event_base_config_flags, event_base_new_with_config() + **/ int event_config_set_flag(struct event_config *cfg, int flag); /** @@ -275,19 +554,25 @@ 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. + to event_new as the argument to callback. @param eb an event_base to be freed */ void event_base_free(struct event_base *); +/** @name Log severities + */ +/**@{*/ #define _EVENT_LOG_DEBUG 0 #define _EVENT_LOG_MSG 1 #define _EVENT_LOG_WARN 2 #define _EVENT_LOG_ERR 3 +/**@}*/ -/* +/** A callback function used to intercept Libevent's log messages. + + @see event_set_log_callback */ typedef void (*event_log_cb)(int severity, const char *msg); /** @@ -303,6 +588,13 @@ void event_set_log_callback(event_log_cb cb); /** + A function to be called if Libevent encounters a fatal internal error. + + @see event_set_fatal_callback + */ +typedef void (*event_fatal_cb)(int err); + +/** Override Libevent's behavior in the event of a fatal internal error. By default, Libevent will call exit(1) if a programming error makes it @@ -314,31 +606,34 @@ Libevent will (almost) always log an _EVENT_LOG_ERR message before calling this function; look at the last log message to see why Libevent has died. */ -typedef void (*event_fatal_cb)(int err); void event_set_fatal_callback(event_fatal_cb cb); /** Associate a different event base with an event. + The event to be associated must not be currently active or pending. + @param eb the event base @param ev the event + @return 0 on success, -1 on failure. */ int event_base_set(struct event_base *, struct event *); -/** - event_base_loop() flags +/** @name Loop flags + + These flags control the behavior of event_base_loop(). */ -/*@{*/ +/**@{*/ /** Block until we have an active event, then exit once all active events * have had their callbacks run. */ #define EVLOOP_ONCE 0x01 /** Do not block: see which events are ready now, run the callbacks * of the highest-priority ones, then exit. */ #define EVLOOP_NONBLOCK 0x02 -/*@}*/ +/**@}*/ /** - Handle events (threadsafe version). + Wait for events to become active, and run their callbacks. This is a more flexible version of event_base_dispatch(). @@ -347,16 +642,18 @@ evenet_base_loopexit(). You can override this behavior with the 'flags' argument. - @param eb the event_base structure returned by event_init() + @param eb the event_base structure returned by event_base_new() or + event_base_new_with_config() @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() + @see event_base_loopexit(), event_base_dispatch(), EVLOOP_ONCE, + EVLOOP_NONBLOCK */ int event_base_loop(struct event_base *, int); /** - Exit the event loop after the specified time (threadsafe variant). + Exit the event loop after the specified time The next event_base_loop() iteration after the given timer expires will complete normally (handling all queued events) then exit without @@ -365,9 +662,10 @@ 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. + @param tv the amount of time after which the loop should terminate, + or NULL to exit after running all currently active events. @return 0 if successful, or -1 if an error occurred - @see event_loopexit() + @see event_base_loopbreak() */ int event_base_loopexit(struct event_base *, const struct timeval *); @@ -382,7 +680,7 @@ @param eb the event_base structure returned by event_init() @return 0 if successful, or -1 if an error occurred - @see event_base_loopexit + @see event_base_loopexit() */ int event_base_loopbreak(struct event_base *); @@ -395,8 +693,8 @@ @param eb the event_base structure returned by event_init() @return true if event_base_loopexit() was called on this event base, or 0 otherwise - @see event_base_loopexit - @see event_base_got_break + @see event_base_loopexit() + @see event_base_got_break() */ int event_base_got_exit(struct event_base *); @@ -409,52 +707,58 @@ @param eb the event_base structure returned by event_init() @return true if event_base_loopbreak() was called on this event base, or 0 otherwise - @see event_base_loopbreak - @see event_base_got_exit + @see event_base_loopbreak() + @see event_base_got_exit() */ int event_base_got_break(struct event_base *); -/* Flags to pass to event_set(), event_new(), event_assign(), - * event_pending(), and anything else with an argument of the form - * "short events" */ +/** + * @name event flags + * + * Flags to pass to event_new(), event_assign(), event_pending(), and + * anything else with an argument of the form "short events" + */ +/**@{*/ +/** Indicates that a timeout has occurred. It's not necessary to pass + * this flag to event_for new()/event_assign() to get a timeout. */ #define EV_TIMEOUT 0x01 +/** Wait for a socket or FD to become readable */ #define EV_READ 0x02 +/** Wait for a socket or FD to become writeable */ #define EV_WRITE 0x04 +/** Wait for a POSIX signal to be raised*/ #define EV_SIGNAL 0x08 -/** Persistent event: won't get removed automatically when activated. */ +/** + * Persistent event: won't get removed automatically when activated. + * + * When a persistent event with a timeout becomes activated, its timeout + * is reset to 0. + */ #define EV_PERSIST 0x10 /** Select edge-triggered behavior, if supported by the backend. */ #define EV_ET 0x20 +/**@}*/ /** - Define a timer event. + @name evtimer_* macros - @param ev event struct to be modified - @param b an event_base - @param cb callback function - @param arg argument that will be passed to the callback function - */ + Aliases for working with one-shot timer events */ +/**@{*/ #define evtimer_assign(ev, b, cb, arg) \ event_assign((ev), (b), -1, 0, (cb), (arg)) #define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg)) - -/** - Add a timer event. - - @param ev the event struct - @param tv timeval struct - */ #define evtimer_add(ev, tv) event_add((ev), (tv)) - -/** - * 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) event_initialized(ev) +/**@}*/ + +/** + @name evsignal_* macros + Aliases for working with signal events + */ +/**@{*/ #define evsignal_add(ev, tv) event_add((ev), (tv)) #define evsignal_assign(ev, b, x, cb, arg) \ event_assign((ev), (b), (x), EV_SIGNAL|EV_PERSIST, cb, (arg)) @@ -463,57 +767,117 @@ #define evsignal_del(ev) event_del(ev) #define evsignal_pending(ev, tv) event_pending((ev), EV_SIGNAL, (tv)) #define evsignal_initialized(ev) event_initialized(ev) +/**@}*/ + +/** + A callback function for an event. + + It receives three arguments: + @param fd An fd or signal + @param events One or more EV_* flags + @param arg A user-supplied argument. + + @see event_new() + */ typedef void (*event_callback_fn)(evutil_socket_t, short, void *); /** - Prepare an event structure to be added. + Allocate and asssign a new event structure, ready to be added. + + The function event_new() returns a new event that can be used in + future calls to event_add() and event_del(). The fd and events + arguments determine which conditions will trigger the event; the + callback and callback_arg arguments tell Libevent what to do when the + event becomes active. + + If events contains one of EV_READ, EV_WRITE, or EV_READ|EV_WRITE, then + fd is a file descriptor or socket that should get monitored for + readiness to read, readiness to write, or readiness for either operation + (respectively). If events contains EV_SIGNAL, then fd is a signal + number to wait for. If events contains none of those flags, then the + event can be triggered only by a timeout or by manual activation with + event_active(): In this case, fd must be -1. + + The EV_PERSIST flag can also be passed in the events argument: it makes + event_add() persistent until event_del() is called. + + The EV_ET flag is compatible with EV_READ and EV_WRITE, and supported + only by certain backends. It tells Libevent to use edge-triggered + events. + + The EV_TIMEOUT flag has no effect here. + + It is okay to have multiple events all listening on the same fds; but + they must either all be edge-triggered, or all not be edge triggerd. + + When the event becomes active, the event loop will run the provided + callbuck function, with three arguments. The first will be the provided + fd value. The second will be a bitfield of the events that triggered: + EV_READ, EV_WRITE, or EV_SIGNAL. Here the EV_TIMEOUT flag indicates + that a timeout occurred, and EV_ET indicates that an edge-triggered + event occurred. The third event will be the callback_arg pointer that + you provide. + + @param base the event base to which the event should be attached. + @param fd the file descriptor or signal to be monitored, or -1. + @param events desired events to monitor: bitfield of EV_READ, EV_WRITE, + EV_SIGNAL, EV_PERSIST, EV_ET. + @param callback callback function to be invoked when the event occurs + @param callback_arg an argument to be passed to the callback function + + @return a newly allocated struct event that must later be freed with + event_free(). + @see event_free(), event_add(), event_del(), event_assign() + */ +struct event *event_new(struct event_base *, evutil_socket_t, short, event_callback_fn, void *); + + +/** + Prepare a new, already-allocated event structure to be added. - The function event_assign() 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. - - Note that using event_assign() request that you have already allocated the - event struct. Doing so will often require your code to depend on the size - of the structure, and will create possible incompatibility with future - versions of Libevent. If this seems like a bad idea to you, use event_new() - and event_free() instead. + The function event_assign() prepares the event structure ev to be used + in future calls to event_add() and event_del(). Unlike event_new(), it + doesn't allocate memory itself: it requires that you have already + allocated a struct event, probably on the heap. Doing this will + typically make your code depend on the size of the event structure, and + thereby create incompatibility with future versions of Libevent. + + The easiest way to avoid this problem is just to use event_new() and + event_free() instead. + + A slightly harder way to future-proof your code is to use + event_get_struct_event_size() to determine the required size of an event + at runtime. + + Note that it is NOT safe to call this function on an event that is + active or pending. Doing so WILL corrupt internal data structures in + Libevent, and lead to strange, hard-to-diagnose bugs. You _can_ use + event_assign to change an existing event, but only if it is not active + or pending! + + The arguments for this function, and the behavior of the events that it + makes, are as for event_new(). @param ev an event struct to be modified @param base the event base to which ev should be attached. @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 + @param events desired events to monitor; can be EV_READ and/or EV_WRITE + @param callback callback function to be invoked when the event occurs + @param callback_arg an argument to be passed to the callback function @return 0 if success, or -1 on invalid arguments. - @see event_add(), event_del(), event_once() - + @see event_new(), event_add(), event_del(), event_base_once(), + event_get_struct_event_size() */ int event_assign(struct event *, struct event_base *, evutil_socket_t, short, event_callback_fn, void *); /** - Create and allocate a new event structure, ready to be added. - - Arguments are as for event_assign; returns a newly allocated struct event * - that must later be deallocated with event_free(). - - */ -struct event *event_new(struct event_base *, evutil_socket_t, short, event_callback_fn, void *); - -/** Deallocate a struct event * returned by event_new(). + + If the event is pending or active, first make it non-pending and + non-active. */ void event_free(struct event *); @@ -521,41 +885,49 @@ Schedule a one-time event 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 + 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 + Note that in Libevent 2.0 and earlier, if the event is never triggered, + the internal memory used to hold it will never be freed. This may be + fixed in a later version of Libevent. + + @param base an event_base + @param fd a file descriptor to monitor, or -1 for no fd. + @param events event(s) to monitor; can be any of EV_READ | + EV_WRITE, or EV_TIMEOUT @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 + @param timeout the maximum amount of time to wait for the event. NULL + makes an EV_READ/EV_WRITE event make forever; NULL makes an + EV_TIMEOUT event succees immediately. @return 0 if successful, or -1 if an error occurred - @see event_once() */ int event_base_once(struct event_base *, evutil_socket_t, short, event_callback_fn, void *, const struct timeval *); /** - Add an event to the set of monitored events. + Add an event to the set of pending 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. + event specified in event_assign()/event_new() occurs, or when the time + specified in timeout has elapesed. If atimeout is NULL, no timeout + occurs and the function will only be + called if a matching event occurs. The event in the + ev argument must be already initialized by event_assign() or event_new() + and may not be used + in calls to event_assign() until it is no longer pending. + + If the event in the ev argument already has a scheduled timeout, calling + event_add() replaces the old timeout with the new one, or clears the old + timeout if the timeout argument is NULL. @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() + @see event_del(), event_assign(), event_new() */ -int event_add(struct event *, const struct timeval *); +int event_add(struct event *ev, const struct timeval *timeout); /** Remove an event from the set of monitored events. @@ -574,18 +946,24 @@ /** Make an event active. + You can use this function on a pending or a non-pending event to make it + active, so that its callback will be run by event_base_dispatch() or + event_base_loop(). + + One common use in multithreaded programs is to wake the thread running + event_base_loop() from another thread. + @param ev an event to make active. @param res a set of flags to pass to the event's callback. - @param ncalls + @param ncalls an obsolete argument: this is ignored. **/ -void event_active(struct event *, int, short); - +void event_active(struct event *ev, int res, short ncalls); /** Checks if a specific event is pending or scheduled. @param ev an event struct previously passed to event_add() - @param what the requested event type; any of EV_TIMEOUT|EV_READ| + @param events the requested event type; any of EV_TIMEOUT|EV_READ| EV_WRITE|EV_SIGNAL @param tv if this field is not NULL, and the event has a timeout, this field is set to hold the time at which the timeout will @@ -593,9 +971,8 @@ @return true if the event is pending on any of the events in 'what', (that is to say, it has been added), or 0 if the event is not added. - */ -int event_pending(const struct event *, short, struct timeval *); +int event_pending(const struct event *ev, short events, struct timeval *tv); /** @@ -616,17 +993,18 @@ int event_initialized(const struct event *ev); /** - Get the signal number assigned to an event. + Get the signal number assigned to a signal event */ #define event_get_signal(ev) ((int)event_get_fd(ev)) /** - Get the socket assigned to an event. + Get the socket or signal assigned to an event, or -1 if the event has + no socket. */ evutil_socket_t event_get_fd(const struct event *ev); /** - Get the event_base assigned to an event. + Get the event_base associated with an event. */ struct event_base *event_get_base(const struct event *ev); @@ -701,20 +1079,37 @@ * headers. */ #define LIBEVENT_VERSION_NUMBER _EVENT_NUMERIC_VERSION +/** Largest number of priorities that Libevent can support. */ #define EVENT_MAX_PRIORITIES 256 /** - Set the number of different event priorities (threadsafe variant). + Set the number of different event priorities - See the description of event_priority_init() for more information. + 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_base_priority_init() function. This function should be called + before the first call to event_base_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. + + Note that urgent-priority events can starve less-urgent events: after + running all urgent-priority callbacks, Libevent checks for more urgent + events again, before running less-urgent events. Less-urgent events + will not have their callbacks run until there are no events more urgent + than them that want to be active. - @param eb the event_base structure returned by event_init() + @param eb the event_base structure returned by event_base_new() @param npriorities the maximum number of priorities @return 0 if successful, or -1 if an error occurred - @see event_priority_init(), event_priority_set() + @see event_priority_set() */ int event_base_priority_init(struct event_base *, int); - /** Assign a priority to an event. @@ -726,14 +1121,15 @@ int event_priority_set(struct event *, int); /** - Prepare Libevent to use a large number of timeouts with the same duration. + Prepare an event_base to use a large number of timeouts with the same + duration. Libevent's default scheduling algorithm is optimized for having a large - number of timeouts with their durations more or less randomly distributed. - If you have a large number of timeouts that all have the same duration (for - example, if you have a large number of connections that all have a - 10-second timeout), then you can improve Libevent's performance by telling - Libevent about it. + number of timeouts with their durations more or less randomly + distributed. But if you have a large number of timeouts that all have + the same duration (for example, if you have a large number of + connections that all have a 10-second timeout), then you can improve + Libevent's performance by telling Libevent about it. To do this, call this function with the common duration. It will return a pointer to a different, opaque timeout value. (Don't depend on its actual @@ -746,14 +1142,13 @@ const struct timeval *event_base_init_common_timeout(struct event_base *base, const struct timeval *duration); -#ifndef _EVENT_DISABLE_MM_REPLACEMENT +#if !defined(_EVENT_DISABLE_MM_REPLACEMENT) || defined(_EVENT_IN_DOXYGEN) /** Override the functions that Libevent uses for memory management. Usually, Libevent uses the standard libc functions malloc, realloc, and free to allocate memory. Passing replacements for those functions to - event_set_mem_functions() overrides this behavior. To restore the default - behavior, pass NULLs as the arguments to this function. + event_set_mem_functions() overrides this behavior. Note that all memory returned from Libevent will be allocated by the replacement functions rather than by malloc() and realloc(). Thus, if you @@ -761,6 +1156,11 @@ that you get from Libevent. Instead, you must use the free_fn replacement that you provided. + Note also that if you are going to call this function, you should do so + before any call to any Libevent function that does allocation. + Otherwise, those funtions will allocate their memory using malloc(), but + then later free it using your provided free_fn. + @param malloc_fn A replacement for malloc. @param realloc_fn A replacement for realloc @param free_fn A replacement for free. @@ -769,6 +1169,8 @@ void *(*malloc_fn)(size_t sz), void *(*realloc_fn)(void *ptr, size_t sz), void (*free_fn)(void *ptr)); +/** This definition is present if Libevent was built with support for + event_set_mem_functions() */ #define EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED #endif diff -Nru libevent-2.0.12-stable/include/event2/event_struct.h libevent-2.0.16-stable/include/event2/event_struct.h --- libevent-2.0.12-stable/include/event2/event_struct.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/event_struct.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,13 @@ #ifndef _EVENT2_EVENT_STRUCT_H_ #define _EVENT2_EVENT_STRUCT_H_ -/** @file event_struct.h +/** @file event2/event_struct.h - Structures used by event.h. Using these structures directly may harm - forward compatibility: be careful! + Structures used by event.h. Using these structures directly WILL harm + forward compatibility: be careful. + No field declared in this file should be used directly in user code. Except + for historical reasons, these fields would not be exposed at all. */ #ifdef __cplusplus diff -Nru libevent-2.0.12-stable/include/event2/http_compat.h libevent-2.0.16-stable/include/event2/http_compat.h --- libevent-2.0.12-stable/include/event2/http_compat.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/http_compat.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,7 +27,7 @@ #ifndef _EVENT2_HTTP_COMPAT_H_ #define _EVENT2_HTTP_COMPAT_H_ -/** @file http_compat.h +/** @file event2/http_compat.h Potentially non-threadsafe versions of the functions in http.h: provided only for backwards compatibility. diff -Nru libevent-2.0.12-stable/include/event2/http.h libevent-2.0.16-stable/include/event2/http.h --- libevent-2.0.12-stable/include/event2/http.h 2011-03-03 17:55:15.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/http.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -38,7 +38,7 @@ struct evbuffer; struct event_base; -/** @file http.h +/** @file event2/http.h * * Basic support for HTTP serving. * @@ -357,7 +357,7 @@ void evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf); /** - Complete a chunked reply. + Complete a chunked reply, freeing the request as appropriate. @param req a request object */ diff -Nru libevent-2.0.12-stable/include/event2/http_struct.h libevent-2.0.16-stable/include/event2/http_struct.h --- libevent-2.0.12-stable/include/event2/http_struct.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/http_struct.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,7 +27,7 @@ #ifndef _EVENT2_HTTP_STRUCT_H_ #define _EVENT2_HTTP_STRUCT_H_ -/** @file http_struct.h +/** @file event2/http_struct.h Data structures for http. Using these structures may hurt forward compatibility with later versions of Libevent: be careful! diff -Nru libevent-2.0.12-stable/include/event2/keyvalq_struct.h libevent-2.0.16-stable/include/event2/keyvalq_struct.h --- libevent-2.0.12-stable/include/event2/keyvalq_struct.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/keyvalq_struct.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/include/event2/listener.h libevent-2.0.16-stable/include/event2/listener.h --- libevent-2.0.12-stable/include/event2/listener.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/listener.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/include/event2/rpc_compat.h libevent-2.0.16-stable/include/event2/rpc_compat.h --- libevent-2.0.12-stable/include/event2/rpc_compat.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/rpc_compat.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2006-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,7 +27,7 @@ #ifndef _EVENT2_RPC_COMPAT_H_ #define _EVENT2_RPC_COMPAT_H_ -/** @file rpc_compat.h +/** @file event2/rpc_compat.h Deprecated versions of the functions in rpc.h: provided only for backwards compatibility. diff -Nru libevent-2.0.12-stable/include/event2/rpc.h libevent-2.0.16-stable/include/event2/rpc.h --- libevent-2.0.12-stable/include/event2/rpc.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/rpc.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2006-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/include/event2/rpc_struct.h libevent-2.0.16-stable/include/event2/rpc_struct.h --- libevent-2.0.12-stable/include/event2/rpc_struct.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/rpc_struct.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2006-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,7 +31,7 @@ extern "C" { #endif -/** @file rpc_struct.h +/** @file event2/rpc_struct.h Structures used by rpc.h. Using these structures directly may harm forward compatibility: be careful! diff -Nru libevent-2.0.12-stable/include/event2/tag_compat.h libevent-2.0.16-stable/include/event2/tag_compat.h --- libevent-2.0.12-stable/include/event2/tag_compat.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/tag_compat.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,13 +27,23 @@ #ifndef _EVENT2_TAG_COMPAT_H_ #define _EVENT2_TAG_COMPAT_H_ -/** @file tag_compat.h +/** @file event2/tag_compat.h Obsolete/deprecated functions from tag.h; provided only for backwards compatibility. */ +/** + @name Misnamed functions + + @deprecated These macros are deprecated because their names don't follow + Libevent's naming conventions. Use evtag_encode_int and + evtag_encode_int64 instead. + + @{ +*/ #define encode_int(evbuf, number) evtag_encode_int((evbuf), (number)) #define encode_int64(evbuf, number) evtag_encode_int64((evbuf), (number)) +/**@}*/ #endif /* _EVENT2_TAG_H_ */ diff -Nru libevent-2.0.12-stable/include/event2/tag.h libevent-2.0.16-stable/include/event2/tag.h --- libevent-2.0.12-stable/include/event2/tag.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/tag.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,7 +27,7 @@ #ifndef _EVENT2_TAG_H_ #define _EVENT2_TAG_H_ -/** @file tag.h +/** @file event2/tag.h Helper functions for reading and writing tagged data onto buffers. diff -Nru libevent-2.0.12-stable/include/event2/thread.h libevent-2.0.16-stable/include/event2/thread.h --- libevent-2.0.12-stable/include/event2/thread.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/thread.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2008-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,7 +26,7 @@ #ifndef _EVENT2_THREAD_H_ #define _EVENT2_THREAD_H_ -/** @file thread.h +/** @file event2/thread.h Functions for multi-threaded applications using Libevent. @@ -38,18 +38,11 @@ _must_ be set up before an event_base is created if you want the base to use them. - A multi-threaded application must provide locking functions to - Libevent via evthread_set_locking_callback(). Libevent will invoke - this callback whenever a lock needs to be acquired or released. - - The total number of locks employed by Libevent can be determined - via the evthread_num_locks() function. An application must provision - that many locks. - - If the owner of an event base is waiting for events to happen, - Libevent may signal the thread via a special file descriptor to wake - up. To enable this feature, an application needs to provide a - thread identity function via evthread_set_id_callback(). + Most programs will either be using Windows threads or Posix threads. You + can configure Libevent to use one of these event_use_windows_threads() or + event_use_pthreads() respectively. If you're using another threading + library, you'll need to configure threading functions manually using + evthread_set_lock_callbacks() and evthread_set_condition_callbacks(). */ @@ -59,6 +52,11 @@ #include +/** + @name Flags passed to lock functions + + @{ +*/ /** A flag passed to a locking callback when the lock was allocated as a * read-write lock, and we want to acquire or release the lock for writing. */ #define EVTHREAD_WRITE 0x04 @@ -69,11 +67,16 @@ * for the lock; if we can't get the lock immediately, we will instead * return nonzero from the locking callback. */ #define EVTHREAD_TRY 0x10 +/**@}*/ -#ifndef _EVENT_DISABLE_THREAD_SUPPORT +#if !defined(_EVENT_DISABLE_THREAD_SUPPORT) || defined(_EVENT_IN_DOXYGEN) #define EVTHREAD_LOCK_API_VERSION 1 +/** + @name Types of locks + + @{*/ /** A recursive lock is one that can be acquired multiple times at once by the * same thread. No other process can allocate the lock until the thread that * has been holding it has unlocked it as many times as it locked it. */ @@ -81,9 +84,10 @@ /* A read-write lock is one that allows multiple simultaneous readers, but * where any one writer excludes all other writers and readers. */ #define EVTHREAD_LOCKTYPE_READWRITE 2 +/**@}*/ /** This structure describes the interface a threading library uses for - * locking. It's used to tell evthread_set_lock_callbacks how to use + * locking. It's used to tell evthread_set_lock_callbacks() how to use * locking on this platform. */ struct evthread_lock_callbacks { @@ -168,7 +172,7 @@ * * Note that if you're using Windows or the Pthreads threading library, you * probably shouldn't call this function; instead, use - * evthread_use_windows_threads() or evthread_use_posix_threads() if you can. + * evthread_use_windows_threads() or evthread_use_pthreads() if you can. */ int evthread_set_condition_callbacks( const struct evthread_condition_callbacks *); @@ -183,38 +187,45 @@ void evthread_set_id_callback( unsigned long (*id_fn)(void)); -#if defined(WIN32) && !defined(_EVENT_DISABLE_THREAD_SUPPORT) +#if (defined(WIN32) && !defined(_EVENT_DISABLE_THREAD_SUPPORT)) || defined(_EVENT_IN_DOXYGEN) /** Sets up Libevent for use with Windows builtin locking and thread ID - functions. Unavailable if Libevent is not built for Windows. + functions. Unavailable if Libevent is not built for Windows. - @return 0 on success, -1 on failure. */ + @return 0 on success, -1 on failure. */ int evthread_use_windows_threads(void); +/** + Defined if Libevent was built with support for evthread_use_windows_threads() +*/ #define EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED 1 #endif -#if defined(_EVENT_HAVE_PTHREADS) +#if defined(_EVENT_HAVE_PTHREADS) || defined(_EVENT_IN_DOXYGEN) /** Sets up Libevent for use with Pthreads locking and thread ID functions. - Unavailable if Libevent is not build for use with pthreads. Requires - libraries to link against Libevent_pthreads as well as Libevent. + Unavailable if Libevent is not build for use with pthreads. Requires + libraries to link against Libevent_pthreads as well as Libevent. - @return 0 on success, -1 on failure. */ + @return 0 on success, -1 on failure. */ int evthread_use_pthreads(void); +/** Defined if Libevent was built with support for evthread_use_pthreads() */ #define EVTHREAD_USE_PTHREADS_IMPLEMENTED 1 #endif /** Enable debugging wrappers around the current lock callbacks. If Libevent * makes one of several common locking errors, exit with an assertion failure. + * + * If you're going to call this function, you must do so before any locks are + * allocated. **/ void evthread_enable_lock_debuging(void); #endif /* _EVENT_DISABLE_THREAD_SUPPORT */ struct event_base; -/** Make sure it's safe to tell an event base to wake up from another thread. +/** Make sure it's safe to tell an event base to wake up from another thread or a signal handler. - @return 0 on success, -1 on failure. + @return 0 on success, -1 on failure. */ int evthread_make_base_notifiable(struct event_base *base); diff -Nru libevent-2.0.12-stable/include/event2/util.h libevent-2.0.16-stable/include/event2/util.h --- libevent-2.0.12-stable/include/event2/util.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/include/event2/util.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -69,19 +69,39 @@ #include #endif -/* Integer type definitions for types that are supposed to be defined in the +/* Some openbsd autoconf versions get the name of this macro wrong. */ +#if defined(_EVENT_SIZEOF_VOID__) && !defined(_EVENT_SIZEOF_VOID_P) +#define _EVENT_SIZEOF_VOID_P _EVENT_SIZEOF_VOID__ +#endif + +/** + * @name Standard integer types. + * + * Integer type definitions for types that are supposed to be defined in the * C99-specified stdint.h. Shamefully, some platforms do not include * stdint.h, so we need to replace it. (If you are on a platform like this, * your C headers are now over 10 years out of date. You should bug them to * do something about this.) * * We define: - * ev_uint64_t, ev_uint32_t, ev_uint16_t, ev_uint8_t -- unsigned integer - * types of exactly 64, 32, 16, and 8 bits respectively. - * ev_int64_t, ev_int32_t, ev_int16_t, ev_int8_t -- signed integer - * types of exactly 64, 32, 16, and 8 bits respectively. - * ev_uintptr_t, ev_intptr_t -- unsigned/signed integers large enough - * to hold a pointer without loss of bits. + * + *
+ *
ev_uint64_t, ev_uint32_t, ev_uint16_t, ev_uint8_t
+ *
unsigned integer types of exactly 64, 32, 16, and 8 bits + * respectively.
+ *
ev_int64_t, ev_int32_t, ev_int16_t, ev_int8_t
+ *
signed integer types of exactly 64, 32, 16, and 8 bits + * respectively.
+ *
ev_uintptr_t, ev_intptr_t
+ *
unsigned/signed integers large enough + * to hold a pointer without loss of bits.
+ *
ev_ssize_t
+ *
A signed type of the same size as size_t
+ *
ev_off_t
+ *
A signed type typically used to represent offsets within a + * (potentially large) file
+ * + * @{ */ #ifdef _EVENT_HAVE_UINT64_T #define ev_uint64_t uint64_t @@ -95,6 +115,9 @@ #elif _EVENT_SIZEOF_LONG == 8 #define ev_uint64_t unsigned long #define ev_int64_t long +#elif defined(_EVENT_IN_DOXYGEN) +#define ev_uint64_t ... +#define ev_int64_t ... #else #error "No way to define ev_uint64_t" #endif @@ -111,6 +134,9 @@ #elif _EVENT_SIZEOF_INT == 4 #define ev_uint32_t unsigned int #define ev_int32_t signed int +#elif defined(_EVENT_IN_DOXYGEN) +#define ev_uint32_t ... +#define ev_int32_t ... #else #error "No way to define ev_uint32_t" #endif @@ -127,6 +153,9 @@ #elif _EVENT_SIZEOF_SHORT == 2 #define ev_uint16_t unsigned short #define ev_int16_t signed short +#elif defined(_EVENT_IN_DOXYGEN) +#define ev_uint16_t ... +#define ev_int16_t ... #else #error "No way to define ev_uint16_t" #endif @@ -134,16 +163,14 @@ #ifdef _EVENT_HAVE_UINT8_T #define ev_uint8_t uint8_t #define ev_int8_t int8_t +#elif defined(_EVENT_IN_DOXYGEN) +#define ev_uint8_t ... +#define ev_int8_t ... #else #define ev_uint8_t unsigned char #define ev_int8_t signed char #endif -/* Some openbsd autoconf versions get the name of this macro wrong. */ -#if defined(_EVENT_SIZEOF_VOID__) && !defined(_EVENT_SIZEOF_VOID_P) -#define _EVENT_SIZEOF_VOID_P _EVENT_SIZEOF_VOID__ -#endif - #ifdef _EVENT_HAVE_UINTPTR_T #define ev_uintptr_t uintptr_t #define ev_intptr_t intptr_t @@ -153,6 +180,9 @@ #elif _EVENT_SIZEOF_VOID_P <= 8 #define ev_uintptr_t ev_uint64_t #define ev_intptr_t ev_int64_t +#elif defined(_EVENT_IN_DOXYGEN) +#define ev_uintptr_t ... +#define ev_intptr_t ... #else #error "No way to define ev_uintptr_t" #endif @@ -168,6 +198,7 @@ #else #define ev_off_t off_t #endif +/**@}*/ /* Limits for integer types. @@ -176,6 +207,14 @@ - The platform does signed arithmetic in two's complement. */ +/** + @name Limits for integer types + + These macros hold the largest or smallest values possible for the + ev_[u]int*_t types. + + @{ +*/ #define EV_UINT64_MAX ((((ev_uint64_t)0xffffffffUL) << 32) | 0xffffffffUL) #define EV_INT64_MAX ((((ev_int64_t) 0x7fffffffL) << 32) | 0xffffffffL) #define EV_INT64_MIN ((-EV_INT64_MAX) - 1) @@ -188,18 +227,28 @@ #define EV_UINT8_MAX 255 #define EV_INT8_MAX 127 #define EV_INT8_MIN ((-EV_INT8_MAX) - 1) +/** @} */ + +/** + @name Limits for SIZE_T and SSIZE_T + @{ +*/ #if _EVENT_SIZEOF_SIZE_T == 8 #define EV_SIZE_MAX EV_UINT64_MAX #define EV_SSIZE_MAX EV_INT64_MAX #elif _EVENT_SIZEOF_SIZE_T == 4 #define EV_SIZE_MAX EV_UINT32_MAX #define EV_SSIZE_MAX EV_INT32_MAX +#elif defined(_EVENT_IN_DOXYGEN) +#define EV_SIZE_MAX ... +#define EV_SSIZE_MAX ... #else #error "No way to define SIZE_MAX" #endif #define EV_SSIZE_MIN ((-EV_SSIZE_MAX) - 1) +/**@}*/ #ifdef WIN32 #define ev_socklen_t int @@ -216,17 +265,20 @@ #endif #endif -#ifdef WIN32 -/** A type wide enough to hold the output of "socket()" or "accept()". On +/** + * A type wide enough to hold the output of "socket()" or "accept()". On * Windows, this is an intptr_t; elsewhere, it is an int. */ +#ifdef WIN32 #define evutil_socket_t intptr_t #else #define evutil_socket_t int #endif -/** Create two new sockets that are connected to each other. On Unix, this - simply calls socketpair(). On Windows, it uses the loopback network - interface on 127.0.0.1, and only AF_INET,SOCK_STREAM are supported. +/** Create two new sockets that are connected to each other. + + On Unix, this simply calls socketpair(). On Windows, it uses the + loopback network interface on 127.0.0.1, and only + AF_INET,SOCK_STREAM are supported. (This may fail on some Windows hosts where firewall software has cleverly decided to keep 127.0.0.1 from talking to itself.) @@ -241,9 +293,13 @@ */ int evutil_make_socket_nonblocking(evutil_socket_t sock); -/** Do platform-specific operations on a listener socket to make sure that - another program will be able to bind this address right after we've - closed the listener +/** Do platform-specific operations to make a listener socket reusable. + + Specifically, we want to make sure that another program will be able + to bind this address right after we've closed the listener. + + This differs from Windows's interpretation of "reusable", which + allows multiple listeners to bind the same address at the same time. @param sock The socket to make reusable @return 0 on success, -1 on failure @@ -267,11 +323,6 @@ int evutil_closesocket(evutil_socket_t sock); #define EVUTIL_CLOSESOCKET(s) evutil_closesocket(s) -/* Winsock handles socket errors differently from the rest of the world. - * Elsewhere, a socket error is like any other error and is stored in errno. - * But winsock functions require you to retrieve the error with a special - * function, and don't let you use strerror for the error codes. And handling - * EWOULDBLOCK is ... different. */ #ifdef WIN32 /** Return the most recent socket error. Not idempotent on all platforms. */ @@ -283,6 +334,30 @@ int evutil_socket_geterror(evutil_socket_t sock); /** Convert a socket error to a string. */ const char *evutil_socket_error_to_string(int errcode); +#elif defined(_EVENT_IN_DOXYGEN) +/** + @name Socket error functions + + These functions are needed for making programs compatible between + Windows and Unix-like platforms. + + You see, Winsock handles socket errors differently from the rest of + the world. Elsewhere, a socket error is like any other error and is + stored in errno. But winsock functions require you to retrieve the + error with a special function, and don't let you use strerror for + the error codes. And handling EWOULDBLOCK is ... different. + + @{ +*/ +/** Return the most recent socket error. Not idempotent on all platforms. */ +#define EVUTIL_SOCKET_ERROR() ... +/** Replace the most recent socket error with errcode */ +#define EVUTIL_SET_SOCKET_ERROR(errcode) ... +/** Return the most recent socket error to occur on sock. */ +#define evutil_socket_geterror(sock) ... +/** Convert a socket error to a string. */ +#define evutil_socket_error_to_string(errcode) ... +/**@}*/ #else #define EVUTIL_SOCKET_ERROR() (errno) #define EVUTIL_SET_SOCKET_ERROR(errcode) \ @@ -291,9 +366,14 @@ #define evutil_socket_error_to_string(errcode) (strerror(errcode)) #endif -/* - * Manipulation macros for struct timeval. We define replacements + +/** + * @name Manipulation macros for struct timeval. + * + * We define replacements * for timeradd, timersub, timerclear, timercmp, and timerisset. + * + * @{ */ #ifdef _EVENT_HAVE_TIMERADD #define evutil_timeradd(tvp, uvp, vvp) timeradd((tvp), (uvp), (vvp)) @@ -324,6 +404,7 @@ #else #define evutil_timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 #endif +/**@}*/ /** Return true iff the tvp is related to uvp according to the relational * operator cmp. Recognized values for cmp are ==, <=, <, >=, and >. */ @@ -338,7 +419,7 @@ #define evutil_timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) #endif -/* Replacement for offsetof on platforms that don't define it. */ +/** Replacement for offsetof on platforms that don't define it. */ #ifdef offsetof #define evutil_offsetof(type, field) offsetof(type, field) #else @@ -349,7 +430,7 @@ /** Parse a 64-bit value from a string. Arguments are as for strtol. */ ev_int64_t evutil_strtoll(const char *s, char **endptr, int base); -/* Replacement for gettimeofday on platforms that lack it. */ +/** Replacement for gettimeofday on platforms that lack it. */ #ifdef _EVENT_HAVE_GETTIMEOFDAY #define evutil_gettimeofday(tv, tz) gettimeofday((tv), (tz)) #else @@ -365,6 +446,9 @@ __attribute__((format(printf, 3, 4))) #endif ; +/** Replacement for vsnprintf to get consistent behavior on platforms for + which the return value of snprintf does not conform to C99. + */ int evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap); /** Replacement for inet_ntop for platforms which lack it. */ @@ -412,11 +496,16 @@ */ int evutil_ascii_strncasecmp(const char *str1, const char *str2, size_t n); -/* Here we define evutil_addrinfo to the native addrinfo type, or redefinte it +/* Here we define evutil_addrinfo to the native addrinfo type, or redefine it * if this system has no getaddrinfo(). */ #ifdef _EVENT_HAVE_STRUCT_ADDRINFO #define evutil_addrinfo addrinfo #else +/** A definition of struct addrinfo for systems that lack it. + + (This is just an alias for struct addrinfo if the system defines + struct addrinfo.) +*/ struct evutil_addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ int ai_family; /* PF_xxx */ @@ -428,6 +517,13 @@ struct evutil_addrinfo *ai_next; /* next structure in linked list */ }; #endif +/** @name evutil_getaddrinfo() error codes + + These values are possible error codes for evutil_getaddrinfo() and + related functions. + + @{ +*/ #ifdef EAI_ADDRFAMILY #define EVUTIL_EAI_ADDRFAMILY EAI_ADDRFAMILY #else @@ -524,9 +620,11 @@ #else #define EVUTIL_AI_ADDRCONFIG 0x40000 #endif +/**@}*/ struct evutil_addrinfo; -/* This function clones getaddrinfo for systems that don't have it. For full +/** + * This function clones getaddrinfo for systems that don't have it. For full * details, see RFC 3493, section 6.1. * * Limitations: @@ -539,12 +637,12 @@ int evutil_getaddrinfo(const char *nodename, const char *servname, const struct evutil_addrinfo *hints_in, struct evutil_addrinfo **res); -/* Release storage allocated by evutil_getaddrinfo or evdns_getaddrinfo. */ +/** Release storage allocated by evutil_getaddrinfo or evdns_getaddrinfo. */ void evutil_freeaddrinfo(struct evutil_addrinfo *ai); const char *evutil_gai_strerror(int err); -/* Generate n bytes of secure pseudorandom data, and store them in buf. +/** Generate n bytes of secure pseudorandom data, and store them in buf. * * By default, Libevent uses an ARC4-based random number generator, seeded * using the platform's entropy source (/dev/urandom on Unix-like systems; diff -Nru libevent-2.0.12-stable/iocp-internal.h libevent-2.0.16-stable/iocp-internal.h --- libevent-2.0.12-stable/iocp-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/iocp-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/ipv6-internal.h libevent-2.0.16-stable/ipv6-internal.h --- libevent-2.0.12-stable/ipv6-internal.h 2011-03-03 17:55:15.000000000 +0000 +++ libevent-2.0.16-stable/ipv6-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/kqueue.c libevent-2.0.16-stable/kqueue.c --- libevent-2.0.12-stable/kqueue.c 2011-05-03 18:14:46.000000000 +0000 +++ libevent-2.0.16-stable/kqueue.c 2011-10-26 14:16:09.000000000 +0000 @@ -2,7 +2,7 @@ /* * Copyright 2000-2007 Niels Provos - * Copyright 2007-2010 Niels Provos and Nick Mathewson + * Copyright 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,8 +51,10 @@ * easy way to tell them apart via autoconf, so we need to use OS macros. */ #if defined(_EVENT_HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__darwin__) && !defined(__APPLE__) #define PTR_TO_UDATA(x) ((intptr_t)(x)) +#define INT_TO_UDATA(x) ((intptr_t)(x)) #else #define PTR_TO_UDATA(x) (x) +#define INT_TO_UDATA(x) ((void*)(x)) #endif #include "event-internal.h" @@ -169,6 +171,8 @@ /* Do nothing here */ } +#define ADD_UDATA 0x30303 + static void kq_setup_kevent(struct kevent *out, evutil_socket_t fd, int filter, short change) { @@ -178,6 +182,9 @@ if (change & EV_CHANGE_ADD) { out->flags = EV_ADD; + /* We set a magic number here so that we can tell 'add' + * errors from 'del' errors. */ + out->udata = INT_TO_UDATA(ADD_UDATA); if (change & EV_ET) out->flags |= EV_CLEAR; #ifdef NOTE_EOF @@ -316,27 +323,47 @@ int which = 0; if (events[i].flags & EV_ERROR) { - /* - * Error messages that can happen, when a delete fails. - * EBADF happens when the file descriptor has been - * closed, - * ENOENT when the file descriptor was closed and - * then reopened. - * EINVAL for some reasons not understood; EINVAL - * should not be returned ever; but FreeBSD does :-\ - * An error is also indicated when a callback deletes - * an event we are still processing. In that case - * the data field is set to ENOENT. - */ - if (events[i].data == EBADF || - events[i].data == EINVAL || - events[i].data == ENOENT) + switch (events[i].data) { + + /* Can occur on delete if we are not currently + * watching any events on this fd. That can + * happen when the fd was closed and another + * file was opened with that fd. */ + case ENOENT: + /* Can occur for reasons not fully understood + * on FreeBSD. */ + case EINVAL: continue; - errno = events[i].data; - return (-1); - } - if (events[i].filter == EVFILT_READ) { + /* Can occur on a delete if the fd is closed. Can + * occur on an add if the fd was one side of a pipe, + * and the other side was closed. */ + case EBADF: + /* These two can occur on an add if the fd was one side + * of a pipe, and the other side was closed. */ + case EPERM: + case EPIPE: + /* Report read events, if we're listening for + * them, so that the user can learn about any + * add errors. (If the operation was a + * delete, then udata should be cleared.) */ + if (events[i].udata) { + /* The operation was an add: + * report the error as a read. */ + which |= EV_READ; + break; + } else { + /* The operation was a del: + * report nothing. */ + continue; + } + + /* Other errors shouldn't occur. */ + default: + errno = events[i].data; + return (-1); + } + } else if (events[i].filter == EVFILT_READ) { which |= EV_READ; } else if (events[i].filter == EVFILT_WRITE) { which |= EV_WRITE; diff -Nru libevent-2.0.12-stable/LICENSE libevent-2.0.16-stable/LICENSE --- libevent-2.0.12-stable/LICENSE 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/LICENSE 2011-10-26 14:16:09.000000000 +0000 @@ -3,7 +3,7 @@ ============================== Copyright (c) 2000-2007 Niels Provos -Copyright (c) 2007-2010 Niels Provos and Nick Mathewson +Copyright (c) 2007-2011 Niels Provos and Nick Mathewson Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/listener.c libevent-2.0.16-stable/listener.c --- libevent-2.0.12-stable/listener.c 2011-05-28 03:13:46.000000000 +0000 +++ libevent-2.0.16-stable/listener.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos, Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos, Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/log.c libevent-2.0.16-stable/log.c --- libevent-2.0.12-stable/log.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/log.c 2011-10-26 14:16:09.000000000 +0000 @@ -5,7 +5,7 @@ * * Based on err.c, which was adapted from OpenBSD libc *err* *warn* code. * - * Copyright (c) 2005-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2005-2011 Niels Provos and Nick Mathewson * * Copyright (c) 2000 Dug Song * diff -Nru libevent-2.0.12-stable/log-internal.h libevent-2.0.16-stable/log-internal.h --- libevent-2.0.12-stable/log-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/log-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/Makefile.am libevent-2.0.16-stable/Makefile.am --- libevent-2.0.12-stable/Makefile.am 2011-06-03 19:45:36.000000000 +0000 +++ libevent-2.0.16-stable/Makefile.am 2011-11-18 20:19:11.000000000 +0000 @@ -32,7 +32,7 @@ # # Once an RC is out, DO NOT MAKE ANY ABI-BREAKING CHANGES IN THAT SERIES # UNLESS YOU REALLY REALLY HAVE TO. -VERSION_INFO = 6:1:1 +VERSION_INFO = 6:4:1 # History: RELEASE VERSION_INFO # 2.0.1-alpha -- 2.0 1:0:0 @@ -47,6 +47,10 @@ # 2.0.10-stable-- 2.0 5:1:0 (No ABI change) # 2.0.11-stable-- 2.0 6:0:1 (ABI changed, backward-compatible) # 2.0.12-stable-- 2.0 6:1:1 (No ABI change) +# 2.0.13-stable-- 2.0 6:2:1 (No ABI change) +# 2.0.14-stable-- 2.0 6:3:1 (No ABI change) +# 2.0.15-stable-- 2.0 6:3:1 (Forgot to update :( ) +# 2.0.16-stable-- 2.0 6:4:1 (No ABI change) # # For Libevent 2.1: # 2.1.1-alpha -- 2.1 1:0:0 @@ -70,7 +74,9 @@ # is user-visible, and so we can pretty much guarantee that release # series won't be binary-compatible. +if INSTALL_LIBEVENT dist_bin_SCRIPTS = event_rpcgen.py +endif pkgconfigdir=$(libdir)/pkgconfig LIBEVENT_PKGCONFIG=libevent.pc @@ -84,6 +90,7 @@ EXTRA_DIST = \ LICENSE \ autogen.sh \ + event_rpcgen.py \ libevent.pc.in \ Doxyfile \ whatsnew-2.0.txt \ diff -Nru libevent-2.0.12-stable/Makefile.in libevent-2.0.16-stable/Makefile.in --- libevent-2.0.12-stable/Makefile.in 2011-06-03 20:23:58.000000000 +0000 +++ libevent-2.0.16-stable/Makefile.in 2011-11-18 20:20:03.000000000 +0000 @@ -50,11 +50,11 @@ @SIGNAL_SUPPORT_TRUE@am__append_11 = signal.c @INSTALL_LIBEVENT_FALSE@am__append_12 = $(EVENT1_HDRS) subdir = . -DIST_COMMON = README $(am__configure_deps) $(am__include_HEADERS_DIST) \ - $(am__noinst_HEADERS_DIST) $(dist_bin_SCRIPTS) \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/config.h.in $(srcdir)/libevent.pc.in \ - $(srcdir)/libevent_openssl.pc.in \ +DIST_COMMON = README $(am__configure_deps) \ + $(am__dist_bin_SCRIPTS_DIST) $(am__include_HEADERS_DIST) \ + $(am__noinst_HEADERS_DIST) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(srcdir)/libevent.pc.in $(srcdir)/libevent_openssl.pc.in \ $(srcdir)/libevent_pthreads.pc.in $(top_srcdir)/configure \ ChangeLog compile config.guess config.sub depcomp epoll_sub.c \ install-sh ltmain.sh missing @@ -181,6 +181,7 @@ @INSTALL_LIBEVENT_FALSE@@PTHREADS_TRUE@am_libevent_pthreads_la_rpath = @INSTALL_LIBEVENT_TRUE@@PTHREADS_TRUE@am_libevent_pthreads_la_rpath = \ @INSTALL_LIBEVENT_TRUE@@PTHREADS_TRUE@ -rpath $(libdir) +am__dist_bin_SCRIPTS_DIST = event_rpcgen.py SCRIPTS = $(dist_bin_SCRIPTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -423,7 +424,7 @@ # # Once an RC is out, DO NOT MAKE ANY ABI-BREAKING CHANGES IN THAT SERIES # UNLESS YOU REALLY REALLY HAVE TO. -VERSION_INFO = 6:1:1 +VERSION_INFO = 6:4:1 # History: RELEASE VERSION_INFO # 2.0.1-alpha -- 2.0 1:0:0 @@ -438,6 +439,10 @@ # 2.0.10-stable-- 2.0 5:1:0 (No ABI change) # 2.0.11-stable-- 2.0 6:0:1 (ABI changed, backward-compatible) # 2.0.12-stable-- 2.0 6:1:1 (No ABI change) +# 2.0.13-stable-- 2.0 6:2:1 (No ABI change) +# 2.0.14-stable-- 2.0 6:3:1 (No ABI change) +# 2.0.15-stable-- 2.0 6:3:1 (Forgot to update :( ) +# 2.0.16-stable-- 2.0 6:4:1 (No ABI change) # # For Libevent 2.1: # 2.1.1-alpha -- 2.1 1:0:0 @@ -459,7 +464,7 @@ # nice and rare. For the next couple of years, though, 'struct event' # is user-visible, and so we can pretty much guarantee that release # series won't be binary-compatible. -dist_bin_SCRIPTS = event_rpcgen.py +@INSTALL_LIBEVENT_TRUE@dist_bin_SCRIPTS = event_rpcgen.py pkgconfigdir = $(libdir)/pkgconfig LIBEVENT_PKGCONFIG = libevent.pc $(am__append_2) $(am__append_4) @@ -472,6 +477,7 @@ EXTRA_DIST = \ LICENSE \ autogen.sh \ + event_rpcgen.py \ libevent.pc.in \ Doxyfile \ whatsnew-2.0.txt \ diff -Nru libevent-2.0.12-stable/minheap-internal.h libevent-2.0.16-stable/minheap-internal.h --- libevent-2.0.12-stable/minheap-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/minheap-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Copyright (c) 2006 Maxim Yegorushkin * diff -Nru libevent-2.0.12-stable/mm-internal.h libevent-2.0.16-stable/mm-internal.h --- libevent-2.0.12-stable/mm-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/mm-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/poll.c libevent-2.0.16-stable/poll.c --- libevent-2.0.12-stable/poll.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/poll.c 2011-10-26 14:16:09.000000000 +0000 @@ -2,7 +2,7 @@ /* * Copyright 2000-2007 Niels Provos - * Copyright 2007-2010 Niels Provos and Nick Mathewson + * Copyright 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/ratelim-internal.h libevent-2.0.16-stable/ratelim-internal.h --- libevent-2.0.12-stable/ratelim-internal.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/ratelim-internal.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/README libevent-2.0.16-stable/README --- libevent-2.0.12-stable/README 2011-06-03 19:30:34.000000000 +0000 +++ libevent-2.0.16-stable/README 2011-11-15 22:21:56.000000000 +0000 @@ -75,6 +75,7 @@ Weston Andros Adamson William Ahern Ivan Andropov + Sergey Avseyev Avi Bab Gilad Benjamini Stas Bekman @@ -85,24 +86,31 @@ Tomash Brechko Kelly Brock Ralph Castain + Adrian Chadd + Lawnstein Chan Shuo Chen Ka-Hing Cheung Andrew Danforth + Ed Day Christopher Davis Mike Davis Mihai Draghicioiu Mark Ellzey Shie Erlich + Leonid Evdokimov Christophe Fillot Alexander von Gernler Artur Grabowski Dave Hart + Greg Hazel Michael Herf Sebastian Hahn Aaron Hopkins Tani Hosokawa + Jamie Iles Claudio Jeker Evan Jones + George Kadianakis Phua Keat Kevin Ko Brian Koehmstedt @@ -116,8 +124,10 @@ David Libenzi Yan Lin Moshe Litvin + Mitchell Livingston Hagne Mahre Lubomir Marinov + Abilio Marques Nick Mathewson James Mansion Nicholas Marriott @@ -152,10 +162,12 @@ Dongsheng Song Brodie Thiesfield Jason Toffaletti + Gisle Vanem Bas Verhoeven Constantine Verutin Zack Weinberg Jardel Weyrich + Alex Taral propanbutan mmadia diff -Nru libevent-2.0.12-stable/sample/dns-example.c libevent-2.0.16-stable/sample/dns-example.c --- libevent-2.0.12-stable/sample/dns-example.c 2011-04-23 05:47:04.000000000 +0000 +++ libevent-2.0.16-stable/sample/dns-example.c 2011-11-14 17:15:09.000000000 +0000 @@ -165,6 +165,13 @@ ++idx; } +#ifdef WIN32 + { + WSADATA WSAData; + WSAStartup(0x101, &WSAData); + } +#endif + event_base = event_base_new(); evdns_base = evdns_base_new(event_base, 0); evdns_set_log_fn(logfn); @@ -173,6 +180,10 @@ evutil_socket_t sock; struct sockaddr_in my_addr; sock = socket(PF_INET, SOCK_DGRAM, 0); + if (sock == -1) { + perror("socket"); + exit(1); + } evutil_make_socket_nonblocking(sock); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(10053); @@ -184,12 +195,17 @@ evdns_add_server_port_with_base(event_base, sock, 0, evdns_server_callback, NULL); } if (idx < c) { + int res; #ifdef WIN32 - evdns_base_config_windows_nameservers(evdns_base); + res = evdns_base_config_windows_nameservers(evdns_base); #else - evdns_base_resolv_conf_parse(evdns_base, DNS_OPTION_NAMESERVERS, + res = evdns_base_resolv_conf_parse(evdns_base, DNS_OPTION_NAMESERVERS, "/etc/resolv.conf"); #endif + if (res < 0) { + fprintf(stderr, "Couldn't configure nameservers"); + return 1; + } } printf("EVUTIL_AI_CANONNAME in example = %d\n", EVUTIL_AI_CANONNAME); diff -Nru libevent-2.0.12-stable/sample/http-server.c libevent-2.0.16-stable/sample/http-server.c --- libevent-2.0.12-stable/sample/http-server.c 2011-05-25 23:44:06.000000000 +0000 +++ libevent-2.0.16-stable/sample/http-server.c 2011-08-29 17:26:33.000000000 +0000 @@ -133,7 +133,8 @@ int n; char cbuf[128]; n = evbuffer_remove(buf, cbuf, sizeof(buf)-1); - fwrite(cbuf, 1, n, stdout); + if (n > 0) + fwrite(cbuf, 1, n, stdout); } puts(">>>"); @@ -179,6 +180,8 @@ /* We need to decode it, to see what path the user really wanted. */ decoded_path = evhttp_uridecode(path, 0, NULL); + if (decoded_path == NULL) + goto err; /* Don't allow any ".."s in the path, to avoid exposing stuff outside * of the docroot. This test is both overzealous and underzealous: * it forbids aceptable paths like "/this/one..here", but it doesn't diff -Nru libevent-2.0.12-stable/sample/Makefile.am libevent-2.0.16-stable/sample/Makefile.am --- libevent-2.0.12-stable/sample/Makefile.am 2011-05-23 21:45:50.000000000 +0000 +++ libevent-2.0.16-stable/sample/Makefile.am 2011-10-03 15:54:40.000000000 +0000 @@ -1,21 +1,21 @@ AUTOMAKE_OPTIONS = foreign no-dependencies LDADD = $(LIBEVENT_GC_SECTIONS) ../libevent.la -AM_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat -I$(top_srcdir)/include -I../include +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat -I$(top_srcdir)/include -I../include noinst_PROGRAMS = event-test time-test signal-test dns-example hello-world http-server -event_test_sources = event-test.c -time_test_sources = time-test.c -signal_test_sources = signal-test.c -dns_example_sources = dns-example.c -hello_world_sources = hello-world.c -http_server_sources = http-server.c +event_test_SOURCES = event-test.c +time_test_SOURCES = time-test.c +signal_test_SOURCES = signal-test.c +dns_example_SOURCES = dns-example.c +hello_world_SOURCES = hello-world.c +http_server_SOURCES = http-server.c if OPENSSL noinst_PROGRAMS += le-proxy -le_proxy_sources = le-proxy.c -le_proxy_LDADD = $(LDADD) ../libevent_openssl.la +le_proxy_SOURCES = le-proxy.c +le_proxy_LDADD = $(LDADD) ../libevent_openssl.la -lssl -lcrypto endif verify: diff -Nru libevent-2.0.12-stable/sample/Makefile.in libevent-2.0.16-stable/sample/Makefile.in --- libevent-2.0.12-stable/sample/Makefile.in 2011-06-03 20:23:57.000000000 +0000 +++ libevent-2.0.16-stable/sample/Makefile.in 2011-11-18 20:20:02.000000000 +0000 @@ -53,34 +53,35 @@ CONFIG_CLEAN_VPATH_FILES = @OPENSSL_TRUE@am__EXEEXT_1 = le-proxy$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) -dns_example_SOURCES = dns-example.c -dns_example_OBJECTS = dns-example.$(OBJEXT) +am_dns_example_OBJECTS = dns-example.$(OBJEXT) +dns_example_OBJECTS = $(am_dns_example_OBJECTS) dns_example_LDADD = $(LDADD) am__DEPENDENCIES_1 = dns_example_DEPENDENCIES = $(am__DEPENDENCIES_1) ../libevent.la -event_test_SOURCES = event-test.c -event_test_OBJECTS = event-test.$(OBJEXT) +am_event_test_OBJECTS = event-test.$(OBJEXT) +event_test_OBJECTS = $(am_event_test_OBJECTS) event_test_LDADD = $(LDADD) event_test_DEPENDENCIES = $(am__DEPENDENCIES_1) ../libevent.la -hello_world_SOURCES = hello-world.c -hello_world_OBJECTS = hello-world.$(OBJEXT) +am_hello_world_OBJECTS = hello-world.$(OBJEXT) +hello_world_OBJECTS = $(am_hello_world_OBJECTS) hello_world_LDADD = $(LDADD) hello_world_DEPENDENCIES = $(am__DEPENDENCIES_1) ../libevent.la -http_server_SOURCES = http-server.c -http_server_OBJECTS = http-server.$(OBJEXT) +am_http_server_OBJECTS = http-server.$(OBJEXT) +http_server_OBJECTS = $(am_http_server_OBJECTS) http_server_LDADD = $(LDADD) http_server_DEPENDENCIES = $(am__DEPENDENCIES_1) ../libevent.la -le_proxy_SOURCES = le-proxy.c -le_proxy_OBJECTS = le-proxy.$(OBJEXT) +am__le_proxy_SOURCES_DIST = le-proxy.c +@OPENSSL_TRUE@am_le_proxy_OBJECTS = le-proxy.$(OBJEXT) +le_proxy_OBJECTS = $(am_le_proxy_OBJECTS) am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) ../libevent.la @OPENSSL_TRUE@le_proxy_DEPENDENCIES = $(am__DEPENDENCIES_2) \ @OPENSSL_TRUE@ ../libevent_openssl.la -signal_test_SOURCES = signal-test.c -signal_test_OBJECTS = signal-test.$(OBJEXT) +am_signal_test_OBJECTS = signal-test.$(OBJEXT) +signal_test_OBJECTS = $(am_signal_test_OBJECTS) signal_test_LDADD = $(LDADD) signal_test_DEPENDENCIES = $(am__DEPENDENCIES_1) ../libevent.la -time_test_SOURCES = time-test.c -time_test_OBJECTS = time-test.$(OBJEXT) +am_time_test_OBJECTS = time-test.$(OBJEXT) +time_test_OBJECTS = $(am_time_test_OBJECTS) time_test_LDADD = $(LDADD) time_test_DEPENDENCIES = $(am__DEPENDENCIES_1) ../libevent.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) @@ -95,10 +96,14 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = dns-example.c event-test.c hello-world.c http-server.c \ - le-proxy.c signal-test.c time-test.c -DIST_SOURCES = dns-example.c event-test.c hello-world.c http-server.c \ - le-proxy.c signal-test.c time-test.c +SOURCES = $(dns_example_SOURCES) $(event_test_SOURCES) \ + $(hello_world_SOURCES) $(http_server_SOURCES) \ + $(le_proxy_SOURCES) $(signal_test_SOURCES) \ + $(time_test_SOURCES) +DIST_SOURCES = $(dns_example_SOURCES) $(event_test_SOURCES) \ + $(hello_world_SOURCES) $(http_server_SOURCES) \ + $(am__le_proxy_SOURCES_DIST) $(signal_test_SOURCES) \ + $(time_test_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -227,15 +232,15 @@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign no-dependencies LDADD = $(LIBEVENT_GC_SECTIONS) ../libevent.la -AM_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat -I$(top_srcdir)/include -I../include -event_test_sources = event-test.c -time_test_sources = time-test.c -signal_test_sources = signal-test.c -dns_example_sources = dns-example.c -hello_world_sources = hello-world.c -http_server_sources = http-server.c -@OPENSSL_TRUE@le_proxy_sources = le-proxy.c -@OPENSSL_TRUE@le_proxy_LDADD = $(LDADD) ../libevent_openssl.la +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat -I$(top_srcdir)/include -I../include +event_test_SOURCES = event-test.c +time_test_SOURCES = time-test.c +signal_test_SOURCES = signal-test.c +dns_example_SOURCES = dns-example.c +hello_world_SOURCES = hello-world.c +http_server_SOURCES = http-server.c +@OPENSSL_TRUE@le_proxy_SOURCES = le-proxy.c +@OPENSSL_TRUE@le_proxy_LDADD = $(LDADD) ../libevent_openssl.la -lssl -lcrypto DISTCLEANFILES = *~ all: all-am diff -Nru libevent-2.0.12-stable/select.c libevent-2.0.16-stable/select.c --- libevent-2.0.12-stable/select.c 2011-05-31 04:46:29.000000000 +0000 +++ libevent-2.0.16-stable/select.c 2011-10-26 14:16:09.000000000 +0000 @@ -2,7 +2,7 @@ /* * Copyright 2000-2007 Niels Provos - * Copyright 2007-2010 Niels Provos and Nick Mathewson + * Copyright 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -50,17 +50,22 @@ #include "log-internal.h" #include "evmap-internal.h" -#ifndef howmany -#define howmany(x, y) (((x)+((y)-1))/(y)) -#endif - #ifndef _EVENT_HAVE_FD_MASK /* This type is mandatory, but Android doesn't define it. */ -#undef NFDBITS -#define NFDBITS (sizeof(long)*8) typedef unsigned long fd_mask; #endif +#ifndef NFDBITS +#define NFDBITS (sizeof(fd_mask)*8) +#endif + +/* Divide positive x by y, rounding up. */ +#define DIV_ROUNDUP(x, y) (((x)+((y)-1))/(y)) + +/* How many bytes to allocate for N fds? */ +#define SELECT_ALLOC_SIZE(n) \ + (DIV_ROUNDUP(n, NFDBITS) * sizeof(fd_mask)) + struct selectop { int event_fds; /* Highest fd in fd set */ int event_fdsz; @@ -100,7 +105,7 @@ if (!(sop = mm_calloc(1, sizeof(struct selectop)))) return (NULL); - if (select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask))) { + if (select_resize(sop, SELECT_ALLOC_SIZE(32 + 1))) { select_free_selectop(sop); return (NULL); } @@ -253,8 +258,7 @@ /* In theory we should worry about overflow here. In * reality, though, the highest fd on a unixy system will * not overflow here. XXXX */ - while (fdsz < - (int) (howmany(fd + 1, NFDBITS) * sizeof(fd_mask))) + while (fdsz < (int) SELECT_ALLOC_SIZE(fd + 1)) fdsz *= 2; if (fdsz != sop->event_fdsz) { diff -Nru libevent-2.0.12-stable/signal.c libevent-2.0.16-stable/signal.c --- libevent-2.0.12-stable/signal.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/signal.c 2011-10-26 14:16:09.000000000 +0000 @@ -2,7 +2,7 @@ /* * Copyright 2000-2007 Niels Provos - * Copyright 2007-2010 Niels Provos and Nick Mathewson + * Copyright 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -168,11 +168,6 @@ int evsig_init(struct event_base *base) { -#ifndef _EVENT_DISABLE_THREAD_SUPPORT - if (! evsig_base_lock) - EVTHREAD_ALLOC_LOCK(evsig_base_lock, 0); -#endif - /* * Our signal handler is going to write to one end of the socket * pair to wake up our event loop. The event loop then scans for @@ -404,9 +399,11 @@ int i = 0; if (base->sig.ev_signal_added) { event_del(&base->sig.ev_signal); - event_debug_unassign(&base->sig.ev_signal); base->sig.ev_signal_added = 0; } + /* debug event is created in evsig_init/event_assign even when + * ev_signal_added == 0, so unassign is required */ + event_debug_unassign(&base->sig.ev_signal); for (i = 0; i < NSIG; ++i) { if (i < base->sig.sh_old_max && base->sig.sh_old[i] != NULL) @@ -436,3 +433,12 @@ base->sig.sh_old = NULL; } } + +#ifndef _EVENT_DISABLE_THREAD_SUPPORT +int +evsig_global_setup_locks_(const int enable_locks) +{ + EVTHREAD_SETUP_GLOBAL_LOCK(evsig_base_lock, 0); + return 0; +} +#endif diff -Nru libevent-2.0.12-stable/test/bench.c libevent-2.0.16-stable/test/bench.c --- libevent-2.0.12-stable/test/bench.c 2011-05-25 23:44:06.000000000 +0000 +++ libevent-2.0.16-stable/test/bench.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright 2003-2007 Niels Provos - * Copyright 2007-2010 Niels Provos and Nick Mathewson + * Copyright 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/bench_cascade.c libevent-2.0.16-stable/test/bench_cascade.c --- libevent-2.0.12-stable/test/bench_cascade.c 2011-05-25 23:44:06.000000000 +0000 +++ libevent-2.0.16-stable/test/bench_cascade.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright 2007-2010 Niels Provos and Nick Mathewson + * Copyright 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/bench_http.c libevent-2.0.16-stable/test/bench_http.c --- libevent-2.0.12-stable/test/bench_http.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/test/bench_http.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright 2008-2010 Niels Provos and Nick Mathewson + * Copyright 2008-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -91,6 +91,7 @@ int c; int use_iocp = 0; unsigned short port = 8080; + char *endptr = NULL; #ifdef WIN32 WSADATA WSAData; @@ -113,11 +114,23 @@ switch (c) { case 'p': - port = atoi(argv[i+1]); + if (i+1 >= argc || !argv[i+1]) { + fprintf(stderr, "Missing port\n"); + exit(1); + } + port = (int)strtol(argv[i+1], &endptr, 10); + if (*endptr != '\0') { + fprintf(stderr, "Bad port\n"); + exit(1); + } break; case 'l': - content_len = atol(argv[i+1]); - if (content_len == 0) { + if (i+1 >= argc || !argv[i+1]) { + fprintf(stderr, "Missing content length\n"); + exit(1); + } + content_len = (size_t)strtol(argv[i+1], &endptr, 10); + if (*endptr != '\0' || content_len == 0) { fprintf(stderr, "Bad content length\n"); exit(1); } diff -Nru libevent-2.0.12-stable/test/bench_httpclient.c libevent-2.0.16-stable/test/bench_httpclient.c --- libevent-2.0.12-stable/test/bench_httpclient.c 2011-05-25 23:44:06.000000000 +0000 +++ libevent-2.0.16-stable/test/bench_httpclient.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright 2009-2010 Niels Provos and Nick Mathewson + * Copyright 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/Makefile.am libevent-2.0.16-stable/test/Makefile.am --- libevent-2.0.12-stable/test/Makefile.am 2011-05-25 23:44:06.000000000 +0000 +++ libevent-2.0.16-stable/test/Makefile.am 2011-10-03 15:54:40.000000000 +0000 @@ -2,7 +2,7 @@ AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat -I$(top_srcdir)/include -I../include -DTINYTEST_LOCAL -EXTRA_DIST = regress.rpc regress.gen.h regress.gen.c test.sh +EXTRA_DIST = regress.rpc regress.gen.h regress.gen.c rpcgen_wrapper.sh test.sh noinst_PROGRAMS = test-init test-eof test-weof test-time \ bench bench_cascade bench_http bench_httpclient test-ratelim \ @@ -59,7 +59,7 @@ if OPENSSL regress_SOURCES += regress_ssl.c -regress_LDADD += ../libevent_openssl.la +regress_LDADD += ../libevent_openssl.la -lssl -lcrypto endif bench_SOURCES = bench.c @@ -71,8 +71,19 @@ bench_httpclient_SOURCES = bench_httpclient.c bench_httpclient_LDADD = $(LIBEVENT_GC_SECTIONS) ../libevent_core.la -regress.gen.c regress.gen.h: regress.rpc $(top_srcdir)/event_rpcgen.py - $(top_srcdir)/event_rpcgen.py $(srcdir)/regress.rpc || echo "No Python installed" +regress.gen.c regress.gen.h: rpcgen-attempted + +rpcgen-attempted: $(srcdir)/regress.rpc $(srcdir)/../event_rpcgen.py $(srcdir)/rpcgen_wrapper.sh + date -u > $@ + if $(srcdir)/rpcgen_wrapper.sh $(srcdir); then \ + echo "rpcgen okay"; \ + else \ + echo "No Python installed; stubbing out RPC test." >&2; \ + echo " "> regress.gen.c; \ + echo "#define NO_PYTHON_EXISTS" > regress.gen.h; \ + fi + +CLEANFILES = rpcgen-attempted DISTCLEANFILES = *~ diff -Nru libevent-2.0.12-stable/test/Makefile.in libevent-2.0.16-stable/test/Makefile.in --- libevent-2.0.12-stable/test/Makefile.in 2011-06-03 20:23:57.000000000 +0000 +++ libevent-2.0.16-stable/test/Makefile.in 2011-11-18 20:20:02.000000000 +0000 @@ -46,7 +46,7 @@ @PTHREADS_TRUE@am__append_3 = ../libevent_pthreads.la @BUILD_WIN32_TRUE@am__append_4 = regress_iocp.c @OPENSSL_TRUE@am__append_5 = regress_ssl.c -@OPENSSL_TRUE@am__append_6 = ../libevent_openssl.la +@OPENSSL_TRUE@am__append_6 = ../libevent_openssl.la -lssl -lcrypto subdir = test DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in @@ -102,8 +102,10 @@ $(am__objects_2) $(am__objects_3) $(am__objects_4) regress_OBJECTS = $(am_regress_OBJECTS) am__DEPENDENCIES_2 = $(am__append_3) +@OPENSSL_TRUE@am__DEPENDENCIES_3 = ../libevent_openssl.la regress_DEPENDENCIES = $(am__DEPENDENCIES_1) ../libevent.la \ - $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) $(am__append_6) + $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_3) regress_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(regress_LDFLAGS) \ $(LDFLAGS) -o $@ @@ -281,7 +283,7 @@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat -I$(top_srcdir)/include -I../include -DTINYTEST_LOCAL -EXTRA_DIST = regress.rpc regress.gen.h regress.gen.c test.sh +EXTRA_DIST = regress.rpc regress.gen.h regress.gen.c rpcgen_wrapper.sh test.sh noinst_HEADERS = tinytest.h tinytest_macros.h regress.h tinytest_local.h TESTS = $(top_srcdir)/test/test.sh BUILT_SOURCES = $(am__append_2) @@ -319,6 +321,7 @@ bench_http_LDADD = $(LIBEVENT_GC_SECTIONS) ../libevent.la bench_httpclient_SOURCES = bench_httpclient.c bench_httpclient_LDADD = $(LIBEVENT_GC_SECTIONS) ../libevent_core.la +CLEANFILES = rpcgen-attempted DISTCLEANFILES = *~ all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am @@ -910,6 +913,7 @@ mostlyclean-generic: clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -1008,8 +1012,17 @@ tags uninstall uninstall-am -regress.gen.c regress.gen.h: regress.rpc $(top_srcdir)/event_rpcgen.py - $(top_srcdir)/event_rpcgen.py $(srcdir)/regress.rpc || echo "No Python installed" +regress.gen.c regress.gen.h: rpcgen-attempted + +rpcgen-attempted: $(srcdir)/regress.rpc $(srcdir)/../event_rpcgen.py $(srcdir)/rpcgen_wrapper.sh + date -u > $@ + if $(srcdir)/rpcgen_wrapper.sh $(srcdir); then \ + echo "rpcgen okay"; \ + else \ + echo "No Python installed; stubbing out RPC test." >&2; \ + echo " "> regress.gen.c; \ + echo "#define NO_PYTHON_EXISTS" > regress.gen.h; \ + fi verify: check diff -Nru libevent-2.0.12-stable/test/Makefile.nmake libevent-2.0.16-stable/test/Makefile.nmake --- libevent-2.0.12-stable/test/Makefile.nmake 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/test/Makefile.nmake 2011-06-14 19:08:21.000000000 +0000 @@ -50,6 +50,11 @@ bench_httpclient.exe: bench_httpclient.obj $(CC) $(CFLAGS) $(LIBS) bench_httpclient.obj +regress.gen.c regress.gen.h: regress.rpc ../event_rpcgen.py + echo // > regress.gen.c + echo #define NO_PYTHON_EXISTS > regress.gen.h + -python ..\event_rpcgen.py regress.rpc + clean: -del $(REGRESS_OBJS) -del $(OTHER_OBJS) diff -Nru libevent-2.0.12-stable/test/regress_buffer.c libevent-2.0.16-stable/test/regress_buffer.c --- libevent-2.0.12-stable/test/regress_buffer.c 2011-04-23 05:47:04.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_buffer.c 2011-11-14 17:15:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2003-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -285,6 +285,43 @@ } static void +no_cleanup(const void *data, size_t datalen, void *extra) +{ +} + +static void +test_evbuffer_remove_buffer_with_empty(void *ptr) +{ + struct evbuffer *src = evbuffer_new(); + struct evbuffer *dst = evbuffer_new(); + char buf[2]; + + evbuffer_validate(src); + evbuffer_validate(dst); + + /* setup the buffers */ + /* we need more data in src than we will move later */ + evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL); + evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL); + /* we need one buffer in dst and one empty buffer at the end */ + evbuffer_add(dst, buf, sizeof(buf)); + evbuffer_add_reference(dst, buf, 0, no_cleanup, NULL); + + evbuffer_validate(src); + evbuffer_validate(dst); + + /* move three bytes over */ + evbuffer_remove_buffer(src, dst, 3); + + evbuffer_validate(src); + evbuffer_validate(dst); + +end: + evbuffer_free(src); + evbuffer_free(dst); +} + +static void test_evbuffer_reserve2(void *ptr) { /* Test the two-vector cases of reserve/commit. */ @@ -618,6 +655,9 @@ TT_DIE(("Didn't recognize the implementation")); } + /* Say that it drains to a fd so that we can use sendfile. */ + evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD); + #if defined(_EVENT_HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__) /* We need to use a pair of AF_INET sockets, since Solaris doesn't support sendfile() over AF_UNIX. */ @@ -881,7 +921,6 @@ free(cp); cp = NULL; evbuffer_validate(evb); - test_ok = 1; end: evbuffer_free(evb); evbuffer_free(evb_tmp); @@ -889,6 +928,57 @@ } static void +test_evbuffer_search_eol(void *ptr) +{ + struct evbuffer *buf = evbuffer_new(); + struct evbuffer_ptr ptr1, ptr2; + const char *s; + size_t eol_len; + + s = "string! \r\n\r\nx\n"; + evbuffer_add(buf, s, strlen(s)); + eol_len = -1; + ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_CRLF); + tt_int_op(ptr1.pos, ==, 8); + tt_int_op(eol_len, ==, 2); + + eol_len = -1; + ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF); + tt_int_op(ptr2.pos, ==, 8); + tt_int_op(eol_len, ==, 2); + + evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD); + eol_len = -1; + ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF); + tt_int_op(ptr2.pos, ==, 9); + tt_int_op(eol_len, ==, 1); + + eol_len = -1; + ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF_STRICT); + tt_int_op(ptr2.pos, ==, 10); + tt_int_op(eol_len, ==, 2); + + eol_len = -1; + ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_LF); + tt_int_op(ptr1.pos, ==, 9); + tt_int_op(eol_len, ==, 1); + + eol_len = -1; + ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF); + tt_int_op(ptr2.pos, ==, 9); + tt_int_op(eol_len, ==, 1); + + evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD); + eol_len = -1; + ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF); + tt_int_op(ptr2.pos, ==, 11); + tt_int_op(eol_len, ==, 1); + +end: + evbuffer_free(buf); +} + +static void test_evbuffer_iterative(void *ptr) { struct evbuffer *buf = evbuffer_new(); @@ -1074,6 +1164,7 @@ pos = evbuffer_search_range(buf, "ack", 3, NULL, &end); tt_int_op(pos.pos, ==, -1); + end: if (buf) evbuffer_free(buf); @@ -1540,6 +1631,7 @@ struct testcase_t evbuffer_testcases[] = { { "evbuffer", test_evbuffer, 0, NULL, NULL }, + { "remove_buffer_with_empty", test_evbuffer_remove_buffer_with_empty, 0, NULL, NULL }, { "reserve2", test_evbuffer_reserve2, 0, NULL, NULL }, { "reserve_many", test_evbuffer_reserve_many, 0, NULL, NULL }, { "reserve_many2", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"add" }, @@ -1548,6 +1640,7 @@ { "reference", test_evbuffer_reference, 0, NULL, NULL }, { "iterative", test_evbuffer_iterative, 0, NULL, NULL }, { "readln", test_evbuffer_readln, TT_NO_LOGS, &basic_setup, NULL }, + { "search_eol", test_evbuffer_search_eol, 0, NULL, NULL }, { "find", test_evbuffer_find, 0, NULL, NULL }, { "ptr_set", test_evbuffer_ptr_set, 0, NULL, NULL }, { "search", test_evbuffer_search, 0, NULL, NULL }, diff -Nru libevent-2.0.12-stable/test/regress_bufferevent.c libevent-2.0.16-stable/test/regress_bufferevent.c --- libevent-2.0.12-stable/test/regress_bufferevent.c 2011-05-25 20:46:32.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_bufferevent.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2003-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/regress.c libevent-2.0.16-stable/test/regress.c --- libevent-2.0.12-stable/test/regress.c 2011-05-27 19:05:17.000000000 +0000 +++ libevent-2.0.16-stable/test/regress.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2003-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -316,7 +316,10 @@ /* Very simple read test */ setup_test("Simple read: "); - write(pair[0], TEST1, strlen(TEST1)+1); + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { + tt_fail_perror("write"); + } + shutdown(pair[0], SHUT_WR); event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev); @@ -358,7 +361,10 @@ /* Very simple read test */ setup_test("Simple read to multiple evens: "); - write(pair[0], TEST1, strlen(TEST1)+1); + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { + tt_fail_perror("write"); + } + shutdown(pair[0], SHUT_WR); event_set(&one, pair[1], EV_READ, simpleread_multiple_cb, NULL); @@ -807,7 +813,9 @@ tt_assert(current_base); evthread_make_base_notifiable(current_base); - write(pair[0], TEST1, strlen(TEST1)+1); + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { + tt_fail_perror("write"); + } event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev); if (event_add(&ev, NULL) == -1) @@ -840,7 +848,9 @@ /* wait for the child to read the data */ sleep(1); - write(pair[0], TEST1, strlen(TEST1)+1); + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { + tt_fail_perror("write"); + } if (waitpid(pid, &status, 0) == -1) { fprintf(stdout, "FAILED (fork)\n"); @@ -853,7 +863,10 @@ } /* test that the current event loop still works */ - write(pair[0], TEST1, strlen(TEST1)+1); + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { + fprintf(stderr, "%s: write\n", __func__); + } + shutdown(pair[0], SHUT_WR); event_dispatch(); @@ -1413,7 +1426,11 @@ char buf[256]; struct event *ev_other = arg; readd_test_event_last_added = ev_other; - (void) read(fd, buf, sizeof(buf)); + + if (read(fd, buf, sizeof(buf)) < 0) { + tt_fail_perror("read"); + } + event_add(ev_other, NULL); ++test_ok; } @@ -1426,8 +1443,15 @@ setup_test("Re-add nonpersistent events: "); event_set(&ev1, pair[0], EV_READ, re_add_read_cb, &ev2); event_set(&ev2, pair[1], EV_READ, re_add_read_cb, &ev1); - (void) write(pair[0], "Hello", 5); - (void) write(pair[1], "Hello", 5); + + if (write(pair[0], "Hello", 5) < 0) { + tt_fail_perror("write(pair[0])"); + } + + if (write(pair[1], "Hello", 5) < 0) { + tt_fail_perror("write(pair[1])\n"); + } + if (event_add(&ev1, NULL) == -1 || event_add(&ev2, NULL) == -1) { test_ok = 0; @@ -1565,7 +1589,11 @@ event_add(&e2, NULL); event_loop(EVLOOP_ONCE); event_del(&e2); - write(pair[1], TEST1, strlen(TEST1)+1); + + if (write(pair[1], TEST1, strlen(TEST1)+1) < 0) { + tt_fail_perror("write"); + } + event_loop(EVLOOP_ONCE); event_del(&e1); @@ -1592,8 +1620,12 @@ test_ok = 0; } else if (len) { /* Assumes global pair[0] can be used for writing */ - write(pair[0], TEST1, strlen(TEST1)+1); - test_ok = 1; + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { + tt_fail_perror("write"); + test_ok = 0; + } else { + test_ok = 1; + } } called++; @@ -1608,7 +1640,9 @@ /* Very simple read test */ setup_test("Want read only once: "); - write(pair[0], TEST1, strlen(TEST1)+1); + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { + tt_fail_perror("write"); + } /* Setup the loop termination */ evutil_timerclear(&tv); @@ -2003,7 +2037,10 @@ r = event_base_once(data->base, -1, 0, NULL, NULL, NULL); tt_int_op(r, <, 0); - write(data->pair[1], TEST1, strlen(TEST1)+1); + if (write(data->pair[1], TEST1, strlen(TEST1)+1) < 0) { + tt_fail_perror("write"); + } + shutdown(data->pair[1], SHUT_WR); event_base_dispatch(data->base); diff -Nru libevent-2.0.12-stable/test/regress_dns.c libevent-2.0.16-stable/test/regress_dns.c --- libevent-2.0.12-stable/test/regress_dns.c 2011-04-23 05:47:04.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_dns.c 2011-11-15 21:45:10.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2003-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -495,6 +495,9 @@ { "host2.a.example.com", "err", "3", 0 }, { "host2.b.example.com", "A", "200.100.0.100", 0 }, { "host2.c.example.com", "err", "3", 0 }, + { "hostn.a.example.com", "errsoa", "0", 0 }, + { "hostn.b.example.com", "errsoa", "3", 0 }, + { "hostn.c.example.com", "err", "0", 0 }, { "host", "err", "3", 0 }, { "host2", "err", "3", 0 }, @@ -511,7 +514,7 @@ ev_uint16_t portnum = 0; char buf[64]; - struct generic_dns_callback_result r1, r2, r3, r4, r5; + struct generic_dns_callback_result r[8]; tt_assert(regress_dnsserver(base, &portnum, search_table)); evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); @@ -523,26 +526,35 @@ evdns_base_search_add(dns, "b.example.com"); evdns_base_search_add(dns, "c.example.com"); - n_replies_left = 5; + n_replies_left = sizeof(r)/sizeof(r[0]); exit_base = base; - evdns_base_resolve_ipv4(dns, "host", 0, generic_dns_callback, &r1); - evdns_base_resolve_ipv4(dns, "host2", 0, generic_dns_callback, &r2); - evdns_base_resolve_ipv4(dns, "host", DNS_NO_SEARCH, generic_dns_callback, &r3); - evdns_base_resolve_ipv4(dns, "host2", DNS_NO_SEARCH, generic_dns_callback, &r4); - evdns_base_resolve_ipv4(dns, "host3", 0, generic_dns_callback, &r5); + evdns_base_resolve_ipv4(dns, "host", 0, generic_dns_callback, &r[0]); + evdns_base_resolve_ipv4(dns, "host2", 0, generic_dns_callback, &r[1]); + evdns_base_resolve_ipv4(dns, "host", DNS_NO_SEARCH, generic_dns_callback, &r[2]); + evdns_base_resolve_ipv4(dns, "host2", DNS_NO_SEARCH, generic_dns_callback, &r[3]); + evdns_base_resolve_ipv4(dns, "host3", 0, generic_dns_callback, &r[4]); + evdns_base_resolve_ipv4(dns, "hostn.a.example.com", DNS_NO_SEARCH, generic_dns_callback, &r[5]); + evdns_base_resolve_ipv4(dns, "hostn.b.example.com", DNS_NO_SEARCH, generic_dns_callback, &r[6]); + evdns_base_resolve_ipv4(dns, "hostn.c.example.com", DNS_NO_SEARCH, generic_dns_callback, &r[7]); event_base_dispatch(base); - tt_int_op(r1.type, ==, DNS_IPv4_A); - tt_int_op(r1.count, ==, 1); - tt_int_op(((ev_uint32_t*)r1.addrs)[0], ==, htonl(0x0b16212c)); - tt_int_op(r2.type, ==, DNS_IPv4_A); - tt_int_op(r2.count, ==, 1); - tt_int_op(((ev_uint32_t*)r2.addrs)[0], ==, htonl(0xc8640064)); - tt_int_op(r3.result, ==, DNS_ERR_NOTEXIST); - tt_int_op(r4.result, ==, DNS_ERR_NOTEXIST); - tt_int_op(r5.result, ==, DNS_ERR_NOTEXIST); + tt_int_op(r[0].type, ==, DNS_IPv4_A); + tt_int_op(r[0].count, ==, 1); + tt_int_op(((ev_uint32_t*)r[0].addrs)[0], ==, htonl(0x0b16212c)); + tt_int_op(r[1].type, ==, DNS_IPv4_A); + tt_int_op(r[1].count, ==, 1); + tt_int_op(((ev_uint32_t*)r[1].addrs)[0], ==, htonl(0xc8640064)); + tt_int_op(r[2].result, ==, DNS_ERR_NOTEXIST); + tt_int_op(r[3].result, ==, DNS_ERR_NOTEXIST); + tt_int_op(r[4].result, ==, DNS_ERR_NOTEXIST); + tt_int_op(r[5].result, ==, DNS_ERR_NODATA); + tt_int_op(r[5].ttl, ==, 42); + tt_int_op(r[6].result, ==, DNS_ERR_NOTEXIST); + tt_int_op(r[6].ttl, ==, 42); + tt_int_op(r[7].result, ==, DNS_ERR_NODATA); + tt_int_op(r[7].ttl, ==, 0); end: if (dns) @@ -1625,6 +1637,130 @@ ++pending; } +#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED +/* FIXME: We should move this to regress_main.c if anything else needs it.*/ + +/* Trivial replacements for malloc/free/realloc to check for memory leaks. + * Not threadsafe. */ +static int allocated_chunks = 0; + +static void * +cnt_malloc(size_t sz) +{ + allocated_chunks += 1; + return malloc(sz); +} + +static void * +cnt_realloc(void *old, size_t sz) +{ + if (!old) + allocated_chunks += 1; + if (!sz) + allocated_chunks -= 1; + return realloc(old, sz); +} + +static void +cnt_free(void *ptr) +{ + allocated_chunks -= 1; + return free(ptr); +} + +struct testleak_env_t { + struct event_base *base; + struct evdns_base *dns_base; + struct evdns_request *req; + struct generic_dns_callback_result r; +}; + +static void * +testleak_setup(const struct testcase_t *testcase) +{ + struct testleak_env_t *env; + + allocated_chunks = 0; + event_set_mem_functions(cnt_malloc, cnt_realloc, cnt_free); + event_enable_debug_mode(); + + /* not mm_calloc: we don't want to mess with the count. */ + env = calloc(1, sizeof(struct testleak_env_t)); + env->base = event_base_new(); + env->dns_base = evdns_base_new(env->base, 0); + env->req = evdns_base_resolve_ipv4( + env->dns_base, "example.com", DNS_QUERY_NO_SEARCH, + generic_dns_callback, &env->r); + return env; +} + +static int +testleak_cleanup(const struct testcase_t *testcase, void *env_) +{ + int ok = 0; + struct testleak_env_t *env = env_; +#ifdef _EVENT_DISABLE_DEBUG_MODE + tt_int_op(allocated_chunks, ==, 0); +#else + /* FIXME: that's `1' because of event_debug_map_HT_GROW */ + tt_int_op(allocated_chunks, ==, 1); +#endif + ok = 1; +end: + if (env->dns_base) + evdns_base_free(env->dns_base, 0); + if (env->base) + event_base_free(env->base); + if (env) + free(env); + return ok; +} + +static struct testcase_setup_t testleak_funcs = { + testleak_setup, testleak_cleanup +}; + +static void +test_dbg_leak_cancel(void *env_) +{ + /* cancel, loop, free/dns, free/base */ + struct testleak_env_t *env = env_; + int send_err_shutdown = 1; + evdns_cancel_request(env->dns_base, env->req); + env->req = 0; + + /* `req` is freed in callback, that's why one loop is required. */ + event_base_loop(env->base, EVLOOP_NONBLOCK); + + /* send_err_shutdown means nothing as soon as our request is + * already canceled */ + evdns_base_free(env->dns_base, send_err_shutdown); + env->dns_base = 0; + event_base_free(env->base); + env->base = 0; +} + +static void +test_dbg_leak_shutdown(void *env_) +{ + /* free/dns, loop, free/base */ + struct testleak_env_t *env = env_; + int send_err_shutdown = 1; + + /* `req` is freed both with `send_err_shutdown` and without it, + * the only difference is `evdns_callback` call */ + env->req = 0; + + evdns_base_free(env->dns_base, send_err_shutdown); + env->dns_base = 0; + + /* `req` is freed in callback, that's why one loop is required */ + event_base_loop(env->base, EVLOOP_NONBLOCK); + event_base_free(env->base); + env->base = 0; +} +#endif + static void test_getaddrinfo_async_cancel_stress(void *ptr) { @@ -1702,6 +1838,11 @@ { "getaddrinfo_cancel_stress", test_getaddrinfo_async_cancel_stress, TT_FORK, NULL, NULL }, +#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED + { "leak_shutdown", test_dbg_leak_shutdown, TT_FORK, &testleak_funcs, NULL }, + { "leak_cancel", test_dbg_leak_cancel, TT_FORK, &testleak_funcs, NULL }, +#endif + END_OF_TESTCASES }; diff -Nru libevent-2.0.12-stable/test/regress_et.c libevent-2.0.16-stable/test/regress_et.c --- libevent-2.0.12-stable/test/regress_et.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_et.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/regress.h libevent-2.0.16-stable/test/regress.h --- libevent-2.0.12-stable/test/regress.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/test/regress.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/regress_http.c libevent-2.0.16-stable/test/regress_http.c --- libevent-2.0.12-stable/test/regress_http.c 2011-05-28 03:21:50.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_http.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2003-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/regress_iocp.c libevent-2.0.16-stable/test/regress_iocp.c --- libevent-2.0.12-stable/test/regress_iocp.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_iocp.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/regress_listener.c libevent-2.0.16-stable/test/regress_listener.c --- libevent-2.0.12-stable/test/regress_listener.c 2011-03-03 17:55:15.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_listener.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/regress_main.c libevent-2.0.16-stable/test/regress_main.c --- libevent-2.0.12-stable/test/regress_main.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_main.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2003-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/regress_minheap.c libevent-2.0.16-stable/test/regress_minheap.c --- libevent-2.0.12-stable/test/regress_minheap.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_minheap.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/regress_rpc.c libevent-2.0.16-stable/test/regress_rpc.c --- libevent-2.0.12-stable/test/regress_rpc.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_rpc.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2003-2007 Niels Provos - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -71,6 +71,8 @@ #include "regress.h" #include "regress_testutils.h" +#ifndef NO_PYTHON_EXISTS + static struct evhttp * http_setup(ev_uint16_t *pport) { @@ -870,6 +872,13 @@ { #name, run_legacy_test_fn, TT_FORK|TT_NEED_BASE|TT_LEGACY, \ &legacy_setup, \ rpc_##name } +#else +/* NO_PYTHON_EXISTS */ + +#define RPC_LEGACY(name) \ + { #name, NULL, TT_SKIP, NULL, NULL } + +#endif struct testcase_t rpc_testcases[] = { RPC_LEGACY(basic_test), diff -Nru libevent-2.0.12-stable/test/regress_ssl.c libevent-2.0.16-stable/test/regress_ssl.c --- libevent-2.0.12-stable/test/regress_ssl.c 2011-06-03 21:05:16.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_ssl.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/regress_testutils.c libevent-2.0.16-stable/test/regress_testutils.c --- libevent-2.0.12-stable/test/regress_testutils.c 2011-03-03 17:55:15.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_testutils.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Niels Provos and Nick Mathewson + * Copyright (c) 2010-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -159,6 +159,23 @@ int err = atoi(tab->ans); tt_assert(! evdns_server_request_respond(req, err)); return; + } else if (!strcmp(tab->anstype, "errsoa")) { + int err = atoi(tab->ans); + char soa_record[] = + "\x04" "dns1" "\x05" "icann" "\x03" "org" "\0" + "\x0a" "hostmaster" "\x05" "icann" "\x03" "org" "\0" + "\x77\xde\x5e\xba" /* serial */ + "\x00\x00\x1c\x20" /* refreshtime = 2h */ + "\x00\x00\x0e\x10" /* retry = 1h */ + "\x00\x12\x75\x00" /* expiration = 14d */ + "\x00\x00\x0e\x10" /* min.ttl = 1h */ + ; + evdns_server_request_add_reply( + req, EVDNS_AUTHORITY_SECTION, + "example.com", EVDNS_TYPE_SOA, EVDNS_CLASS_INET, + 42, sizeof(soa_record) - 1, 0, soa_record); + tt_assert(! evdns_server_request_respond(req, err)); + return; } else if (!strcmp(tab->anstype, "A")) { struct in_addr in; evutil_inet_pton(AF_INET, tab->ans, &in); diff -Nru libevent-2.0.12-stable/test/regress_testutils.h libevent-2.0.16-stable/test/regress_testutils.h --- libevent-2.0.12-stable/test/regress_testutils.h 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_testutils.h 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Niels Provos and Nick Mathewson + * Copyright (c) 2010-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/regress_thread.c libevent-2.0.16-stable/test/regress_thread.c --- libevent-2.0.12-stable/test/regress_thread.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_thread.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/regress_util.c libevent-2.0.16-stable/test/regress_util.c --- libevent-2.0.12-stable/test/regress_util.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_util.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Nick Mathewson and Niels Provos + * Copyright (c) 2009-2011 Nick Mathewson and Niels Provos * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -380,6 +380,11 @@ { char buf[16]; int r; + ev_uint64_t u64 = ((ev_uint64_t)1000000000)*200; + ev_int64_t i64 = -1 * (ev_int64_t) u64; + size_t size = 8000; + ev_ssize_t ssize = -9000; + r = evutil_snprintf(buf, sizeof(buf), "%d %d", 50, 100); tt_str_op(buf, ==, "50 100"); tt_int_op(r, ==, 6); @@ -388,6 +393,19 @@ tt_str_op(buf, ==, "longish 1234567"); tt_int_op(r, ==, 18); + r = evutil_snprintf(buf, sizeof(buf), EV_U64_FMT, EV_U64_ARG(u64)); + tt_str_op(buf, ==, "200000000000"); + tt_int_op(r, ==, 12); + + r = evutil_snprintf(buf, sizeof(buf), EV_I64_FMT, EV_I64_ARG(i64)); + tt_str_op(buf, ==, "-200000000000"); + tt_int_op(r, ==, 13); + + r = evutil_snprintf(buf, sizeof(buf), EV_SIZE_FMT" "EV_SSIZE_FMT, + EV_SIZE_ARG(size), EV_SSIZE_ARG(ssize)); + tt_str_op(buf, ==, "8000 -9000"); + tt_int_op(r, ==, 10); + end: ; } diff -Nru libevent-2.0.12-stable/test/regress_zlib.c libevent-2.0.16-stable/test/regress_zlib.c --- libevent-2.0.12-stable/test/regress_zlib.c 2011-05-23 21:45:50.000000000 +0000 +++ libevent-2.0.16-stable/test/regress_zlib.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2008-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff -Nru libevent-2.0.12-stable/test/rpcgen_wrapper.sh libevent-2.0.16-stable/test/rpcgen_wrapper.sh --- libevent-2.0.12-stable/test/rpcgen_wrapper.sh 1970-01-01 00:00:00.000000000 +0000 +++ libevent-2.0.16-stable/test/rpcgen_wrapper.sh 2011-08-18 19:06:29.000000000 +0000 @@ -0,0 +1,41 @@ +#!/bin/sh +# libevent rpcgen_wrapper.sh +# Transforms event_rpcgen.py failure into success for make, only if +# regress.gen.c and regress.gen.h already exist in $srcdir. This +# is needed for "make distcheck" to pass the read-only $srcdir build, +# as with read-only sources fresh from tarball, regress.gen.[ch] will +# be correct in $srcdir but unwritable. This previously triggered +# Makefile.am to create stub regress.gen.c and regress.gen.h in the +# distcheck _build directory, which were then detected as leftover +# files in the build tree after distclean, breaking distcheck. +# Note that regress.gen.[ch] are not in fresh git clones, making +# working Python a requirement for make distcheck of a git tree. + +exit_updated() { + echo "Updated ${srcdir}\regress.gen.c and ${srcdir}\regress.gen.h" + exit 0 +} + +exit_reuse() { + echo "event_rpcgen.py failed, ${srcdir}\regress.gen.\[ch\] will be reused." >&2 + exit 0 +} + +exit_failed() { + echo "Could not generate regress.gen.\[ch\] using event_rpcgen.sh" >&2 + exit 1 +} + +srcdir=$1 +srcdir=${srcdir:-.} +${srcdir}/../event_rpcgen.py ${srcdir}/regress.rpc +case "$?" in + 0) + exit_updated + ;; + *) + test -r ${srcdir}/regress.gen.c -a -r ${srcdir}/regress.gen.h && \ + exit_reuse + exit_failed + ;; +esac diff -Nru libevent-2.0.12-stable/test/test-ratelim.c libevent-2.0.16-stable/test/test-ratelim.c --- libevent-2.0.12-stable/test/test-ratelim.c 2011-03-03 17:55:15.000000000 +0000 +++ libevent-2.0.16-stable/test/test-ratelim.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2009-2011 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -65,6 +65,10 @@ static int cfg_grouplimit_tolerance = -1; static int cfg_stddev_tolerance = -1; +#ifdef _WIN32 +static int cfg_enable_iocp = 0; +#endif + static struct timeval cfg_tick = { 0, 500*1000 }; static struct ev_token_bucket_cfg *conn_bucket_cfg = NULL; @@ -186,6 +190,7 @@ double variance; double expected_total_persec = -1.0, expected_avg_persec = -1.0; int ok = 1; + struct event_config *base_cfg; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; @@ -195,7 +200,16 @@ if (0) event_enable_debug_mode(); - base = event_base_new(); + base_cfg = event_config_new(); + +#ifdef _WIN32 + if (cfg_enable_iocp) { + evthread_use_windows_threads(); + event_config_set_flag(base_cfg, EVENT_BASE_FLAG_STARTUP_IOCP); + } +#endif + + base = event_base_new_with_config(base_cfg); listener = evconnlistener_new_bind(base, echo_listenercb, base, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1, @@ -349,6 +363,9 @@ { "--check-connlimit", &cfg_connlimit_tolerance, 0, 0 }, { "--check-grouplimit", &cfg_grouplimit_tolerance, 0, 0 }, { "--check-stddev", &cfg_stddev_tolerance, 0, 0 }, +#ifdef _WIN32 + { "--iocp", &cfg_enable_iocp, 0, 1 }, +#endif { NULL, NULL, -1, 0 }, }; diff -Nru libevent-2.0.12-stable/test/tinytest.c libevent-2.0.16-stable/test/tinytest.c --- libevent-2.0.12-stable/test/tinytest.c 2011-05-25 20:51:16.000000000 +0000 +++ libevent-2.0.16-stable/test/tinytest.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,4 +1,4 @@ -/* tinytest.c -- Copyright 2009-2010 Nick Mathewson +/* tinytest.c -- Copyright 2009-2011 Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -66,8 +66,8 @@ const char *cur_test_name = NULL; #ifdef WIN32 -/** Pointer to argv[0] for win32. */ -static const char *commandname = NULL; +/* Copy of argv[0] for win32. */ +static char commandname[MAX_PATH+1]; #endif static void usage(struct testgroup_t *groups, int list_groups) @@ -291,7 +291,12 @@ int i, j, n=0; #ifdef WIN32 - commandname = v[0]; + const char *sp = strrchr(v[0], '.'); + const char *extension = ""; + if (!sp || stricmp(sp, ".exe")) + extension = ".exe"; /* Add an exe so CreateProcess will work */ + snprintf(commandname, sizeof(commandname), "%s%s", v[0], extension); + commandname[MAX_PATH]='\0'; #endif for (i=1; i= 199901L) +#define EV_SIZE_FMT "%zu" +#define EV_SSIZE_FMT "%zd" +#define EV_SIZE_ARG(x) (x) +#define EV_SSIZE_ARG(x) (x) +#endif +#endif + +#ifndef EV_SIZE_FMT +#if (_EVENT_SIZEOF_SIZE_T <= _EVENT_SIZEOF_LONG) +#define EV_SIZE_FMT "%lu" +#define EV_SSIZE_FMT "%ld" +#define EV_SIZE_ARG(x) ((unsigned long)(x)) +#define EV_SSIZE_ARG(x) ((long)(x)) +#else +#define EV_SIZE_FMT EV_U64_FMT +#define EV_SSIZE_FMT EV_I64_FMT +#define EV_SIZE_ARG(x) EV_U64_ARG(x) +#define EV_SSIZE_ARG(x) EV_I64_ARG(x) +#endif +#endif + #ifdef __cplusplus } #endif diff -Nru libevent-2.0.12-stable/whatsnew-2.0.txt libevent-2.0.16-stable/whatsnew-2.0.txt --- libevent-2.0.12-stable/whatsnew-2.0.txt 2011-03-03 17:55:15.000000000 +0000 +++ libevent-2.0.16-stable/whatsnew-2.0.txt 2011-11-14 17:15:09.000000000 +0000 @@ -24,7 +24,7 @@ COMPATIBILITY: - Nearly all existing code that worked with should Libevent 1.4 should still + Nearly all existing code that worked with Libevent 1.4 should still work correctly with Libevent 2.0. However, if you are writing new code, or if you want to port old code, we strongly recommend using the new APIs and avoiding deprecated APIs as much as possible. diff -Nru libevent-2.0.12-stable/WIN32-Code/event2/event-config.h libevent-2.0.16-stable/WIN32-Code/event2/event-config.h --- libevent-2.0.12-stable/WIN32-Code/event2/event-config.h 2011-06-03 19:43:57.000000000 +0000 +++ libevent-2.0.16-stable/WIN32-Code/event2/event-config.h 2011-11-18 20:17:31.000000000 +0000 @@ -277,7 +277,7 @@ /* #undef _EVENT_HAVE_WORKING_KQUEUE */ /* Numeric representation of the version */ -#define _EVENT_NUMERIC_VERSION 0x02000c00 +#define _EVENT_NUMERIC_VERSION 0x02001000 /* Name of package */ #define _EVENT_PACKAGE "libevent" @@ -334,7 +334,7 @@ #define _EVENT_TIME_WITH_SYS_TIME 1 /* Version number of package */ -#define _EVENT_VERSION "2.0.12-stable" +#define _EVENT_VERSION "2.0.16-stable" /* Define to appropriate substitue if compiler doesnt have __func__ */ #define _EVENT___func__ __FUNCTION__ diff -Nru libevent-2.0.12-stable/win32select.c libevent-2.0.16-stable/win32select.c --- libevent-2.0.12-stable/win32select.c 2010-12-16 18:05:27.000000000 +0000 +++ libevent-2.0.16-stable/win32select.c 2011-10-26 14:16:09.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright 2007-2010 Niels Provos and Nick Mathewson + * Copyright 2007-2011 Niels Provos and Nick Mathewson * Copyright 2000-2007 Niels Provos * Copyright 2003 Michael A. Davis *