Skip to content

Commit

Permalink
Merge branch 'master' of git://github.com/nmathewson/libevent-book
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Ellzey committed Dec 3, 2012
2 parents d99cc00 + 2efcf1c commit ef3b31e
Show file tree
Hide file tree
Showing 13 changed files with 153 additions and 35 deletions.
2 changes: 1 addition & 1 deletion 00_about.txt
Expand Up @@ -5,7 +5,7 @@ include::license.txt[]
About this document
-------------------

This document will teach you how to use Libevent 2.0 to write fast
This document will teach you how to use Libevent 2.0 (and later) to write fast
portable asynchronous network IO programs in C. We assume:

* That you already know C.
Expand Down
12 changes: 8 additions & 4 deletions Ref1_libsetup.txt
Expand Up @@ -412,7 +412,7 @@ EVTHREAD_WRITE::
writing.

EVTHREAD_TRY::
For locking only: acquire the lock only if the lock can't be
For locking only: acquire the lock only if the lock can be
acquired immediately.

The id_fn argument must be a function returning an unsigned long
Expand Down Expand Up @@ -479,13 +479,17 @@ If one of these lock errors occurs, Libevent exits with an assertion failure.
.Interface
[code,C]
-----
void evthread_enable_lock_debuging(void);
void evthread_enable_lock_debugging(void);
#define evthread_enable_lock_debuging() evthread_enable_lock_debugging()
-----

NOTE: This function MUST be called before any locks are created or used. To
be safe, call it just after you set your threading functions.

This function is new in Libevent 2.0.4-alpha.
This function was new in Libevent 2.0.4-alpha with the misspelled name
"evthread_enable_lock_debuging()." The spelling was fixed to
evthread_enable_lock_debugging() in 2.1.2-alpha; both names are currently
supported.

Debugging event usage
~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -702,7 +706,7 @@ Libevent has released all internal library-global data structures, you can
call:

.Interface
[Code,C]
[code,C]
--------
void libevent_global_shutdown(void);
--------
Expand Down
4 changes: 3 additions & 1 deletion Ref2_eventbase.txt
Expand Up @@ -94,6 +94,8 @@ enum event_base_config_flag {
EVENT_BASE_FLAG_IGNORE_ENV = 0x02,
EVENT_BASE_FLAG_STARTUP_IOCP = 0x04,
EVENT_BASE_FLAG_NO_CACHE_TIME = 0x08,
EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST = 0x10,
EVENT_BASE_FLAG_PRECISE_TIMER = 0x20
};
int event_config_set_flag(struct event_config *cfg,
enum event_base_config_flag flag);
Expand Down Expand Up @@ -133,7 +135,7 @@ EVENT_BASE_FLAG_IGNORE_ENV::
between your program and Libevent.

EVENT_BASE_FLAG_STARTUP_IOCP::
On Window only, this flag makes Libevent
On Windows only, this flag makes Libevent
enable any necessary IOCP dispatch logic on startup, rather than
on-demand.

Expand Down
60 changes: 59 additions & 1 deletion Ref3_eventloop.txt
Expand Up @@ -39,7 +39,7 @@ any events are ready to trigger immediately, and run their callbacks if so.
Ordinarily, the loop will exit as soon as it has no pending events. You can
override this behavior by passing the EVLOOP_NO_EXIT_ON_EMPTY flag---for
example, if you're going to be adding events from some other thread. If you
do set EVLOO_NO_EXIT_ON_EMPTY, the loop will keep running until somebody
do set EVLOOP_NO_EXIT_ON_EMPTY, the loop will keep running until somebody
calls event_base_loopbreak(), or calls event_base_loopexit(), or an error
occurs.

Expand Down Expand Up @@ -198,6 +198,28 @@ These functions are declared in <event2/event.h>. The event_break_loopexit()
function was first implemented in Libevent 1.0c; event_break_loopbreak() was
first implemented in Libevent 1.4.3.

Re-checking for events
~~~~~~~~~~~~~~~~~~~~~~

Ordinarily, Libevent checks for events, then runs all the active events
with the highest priority, then checks for events again, and so on. But
sometimes you might want to stop Libevent right after the current
callback has been run, and tell it to scan again. By analogy to
event_base_loopbreak(), you can do this with the function
event_base_loopcontinue().

.Interface
[code,C]
--------
int event_base_loopcontinue(struct event_base *);
--------

Calling event_base_loopcontinue() has no effect if we aren't currently
running event callbacks.

This function was introduced in Libevent 2.1.2-alpha.


Checking the internal time cache
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -257,6 +279,42 @@ versions of Libevent.

This function was introduced in Libevent 2.0.1-alpha.

Running a function over every event in an event_base
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.Interface
[code,C]
--------
typedef int (*event_base_foreach_event_cb)(const struct event_base *,
const struct event *, void *);

int event_base_foreach_event(struct event_base *base,
event_base_foreach_event_cb fn,
void *arg);
--------

You can use event_base_foreach_event() to iterate over every currently
active or pending event associated with an event_base(). The provided
callback will be invoked exactly once per event, in an unspecified
order. The third argument of event_base_foreach_event() will be passed
as the third argument to each invocation of the callback.

The callback function must return 0 to continue iteration, or some other
integer to stop iterating. Whatever value the callback function finally
returns will then be returned by event_base_foreach_function().

Your callback function *must not* modify any of the events that it
receives, or add or remove any events to the event base, or otherwise
modify any event associated with the event base, or undefined behavior
can occur, up to or including crashes and heap-smashing.

The event_base lock will be held for the duration of the call to
event_base_foreach_event() -- this will block other threads from doing
anything useful with the event_base, so make sure that your callback
doesn't take a long time.

This function was added in Libevent 2.1.2-alpha.

Obsolete event loop functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
46 changes: 36 additions & 10 deletions Ref4_event.txt
Expand Up @@ -181,8 +181,8 @@ Creating an event as its own callback argument

Frequently, you might want to create an event that receives itself as a
callback argument. You can't just pass a pointer to the event as an argument
to event_new(), though, because . To solve this problem, you can use
event_self_cbarg().
to event_new(), though, because it does not exist yet. To solve this problem,
you can use event_self_cbarg().

.Interface
[code,C]
Expand Down Expand Up @@ -490,7 +490,9 @@ Otherwise, 'tv' is the size of the timeout in seconds and
microseconds.

If you call event_add() on an event that is _already_ pending, it will
leave it pending, and reschedule it with the provided timeout.
leave it pending, and reschedule it with the provided timeout. If the
event is already pending, and you re-add it with the timeout NULL,
event_add() will have no effect.

NOTE: Do not set 'tv' to the time at which you want the timeout to
run. If you say "tv->tv_sec = time(NULL)+10;" on 1 January 2010, your
Expand All @@ -510,8 +512,23 @@ NOTE: If you delete an event after it becomes active but before
its callback has a chance to execute, the callback will not be
executed.

These functions are defined in <event2/event.h>; they have existed
since Libevent 0.1.
.Interface
[code,C]
--------
int event_remove_timer(struct event *ev);
---------

Finally, you can remove a pending event's timeout completely without
deleting its IO or signal components. If the event had no timeout
pending, event_remove_timer() has no effect. If the event had only a
timeout but no IO or signal component, event_remove_timer() has the
same effect as event_del(). The return value is 0 on success, -1 on
failure.


These are defined in <event2/event.h>; event_add() and event_del()
have existed since Libevent 0.1; event_remove_timer() was added in
2.1.2-alpha.

Events with priorities
~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -590,6 +607,7 @@ struct event_base *event_get_base(const struct event *ev);
short event_get_events(const struct event *ev);
event_callback_fn event_get_callback(const struct event *ev);
void *event_get_callback_arg(const struct event *ev);
int event_get_priority(const struct event *ev);

void event_get_assignment(const struct event *event,
struct event_base **base_out,
Expand All @@ -613,7 +631,8 @@ event_get_base() function returns its configured event_base. The
event_get_events() function returns the event flags (EV_READ, EV_WRITE,
etc) of the event. The event_get_callback() and
event_get_callback_arg() functions return the callback function and
argument pointer.
argument pointer. The event_get_priority() function returns the event's
currently assigned priority.

The event_get_assignment() function copies all of the assigned fields of
the event into the provided pointers. If any of the pointers is NULL,
Expand Down Expand Up @@ -656,10 +675,10 @@ int replace_callback(struct event *ev, event_callback_fn new_callback,
------

These functions are declared in <event2/event.h>. The event_pending()
function has existed since Libevent 0.1. Libevent 2.0.1-alpha
introduced event_get_fd() and event_get_signal(). Libevent 2.0.2-alpha
introduced event_get_base(). The others were new in Libevent
2.0.4-alpha.
function has existed since Libevent 0.1. Libevent 2.0.1-alpha introduced
event_get_fd() and event_get_signal(). Libevent 2.0.2-alpha introduced
event_get_base(). Libevent 2.1.2-alpha added event_get_priority(). The
others were new in Libevent 2.0.4-alpha.

Finding the currently running event
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -704,6 +723,13 @@ Events inserted with event_base_once cannot be deleted or manually
activated: if you want to be able to cancel an event, create it with the
regular event_new() or event_assign() interfaces.

Note also that at up to Libevent 2.0, if the event is never triggered, the
internal memory used to hold it will never be freed. Starting in Libevent
2.1.2-alpha, these events _are_ freed when the event_base is freed, even if
they haven't activated, but still be aware: if there's some storage
associated with their callback arguments, that storage won't be released
unless your program has done something to track and release it.

Manually activating an event
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
14 changes: 10 additions & 4 deletions Ref6_bufferevent.txt
Expand Up @@ -322,7 +322,7 @@ int bufferevent_socket_get_dns_error(struct bufferevent *bev);
This function resolves the DNS name 'hostname', looking for addresses of type
'family'. (Allowable family types are AF_INET, AF_INET6, and AF_UNSPEC.) If
the name resolution fails, it invokes the event callback with an error event.
If it succeeds, it launches a resolution attempt just as bufferevent_connect
If it succeeds, it launches a connection attempt just as bufferevent_connect
would.

The dns_base argument is optional. If it is NULL, then Libevent blocks while
Expand Down Expand Up @@ -424,7 +424,7 @@ field. Any of these pointers set to NULL will be ignored.

The bufferevent_setcb() function was introduced in Libevent 1.4.4. The type
names "bufferevent_data_cb" and "bufferevent_event_cb" were new in Libevent
2.0.2-alpha. The bufferevent_getcb() functino was added in 2.1.1-alpha.
2.0.2-alpha. The bufferevent_getcb() function was added in 2.1.1-alpha.

.Interface
[code,C]
Expand Down Expand Up @@ -708,7 +708,11 @@ void bufferevent_set_timeouts(struct bufferevent *bufev,
const struct timeval *timeout_read, const struct timeval *timeout_write);
--------

Setting a timeout to NULL removes it.
Setting a timeout to NULL is supposed to remove it; however before Libevent
2.1.2-alpha this wouldn't work with all event types. (As a workaround for
older versions, you can try setting the timeout to a multi-day interval
and/or having your eventcb function ignore BEV_TIMEOUT events when you don't
want them.)

The read timeout will trigger if the bufferevent waits at least
'timeout_read' seconds while trying to read read. The write
Expand Down Expand Up @@ -770,6 +774,7 @@ types.
[code,C]
--------
int bufferevent_priority_set(struct bufferevent *bufev, int pri);
int bufferevent_get_priority(struct bufferevent *bufev);
--------

This function adjusts the priority of the events used to implement
Expand All @@ -779,7 +784,8 @@ priorities.
This function returns 0 on success, and -1 on failure. It works on
socket-based bufferevents only.

This function was introduced in Libevent 1.0.
The bufferevent_priority_set() function was introduced in Libevent 1.0;
bufferevent_get_priority() didn't appear until Libevent 2.1.2-alpha.

.Interface
[code,C]
Expand Down
5 changes: 4 additions & 1 deletion Ref6a_advanced_bufferevents.txt
Expand Up @@ -99,7 +99,7 @@ struct bufferevent *bufferevent_filter_new(struct bufferevent *underlying,
--------

The bufferevent_filter_new() function creates a new filtering bufferevent,
wrapped around and existing "underlying" bufferevent. All data received via
wrapped around an existing "underlying" bufferevent. All data received via
the underlying bufferevent is transformed with the "input" filter before
arriving at the filtering bufferevent, and all data sent via the filtering
bufferevent is transformed with an "output" filter before being sent out to
Expand Down Expand Up @@ -488,6 +488,9 @@ The usual options are accepted; BEV_OPT_CLOSE_ON_FREE makes the SSL object
and the underlying fd or bufferevent get closed when the openssl bufferevent
itself is closed.

Once the handshake is complete, the new bufferevent's event callback gets invoked
with BEV_EVENT_CONNECTED in flags.

If you're creating a socket-based bufferevent and the SSL object already
has a socket set, you do not need to provide the socket yourself: just pass
-1. You can also set the fd later with bufferevent_setfd().
Expand Down
22 changes: 19 additions & 3 deletions Ref7_evbuffer.txt
Expand Up @@ -137,7 +137,7 @@ evbuffer_add_printf(buf, "Hello %s %d.%d.%d", "world", 2, 0, 1);

The evbuffer_add() and evbuffer_add_printf() functions were introduced in
Libevent 0.8; evbuffer_expand() was in Libevent 0.9, and
evbuffer_add_printf() first appeared in Libevent 1.1.
evbuffer_add_vprintf() first appeared in Libevent 1.1.

Moving data from one evbuffer to another
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -728,7 +728,7 @@ for (i=0; i<n && n_to_add > 0; ++i) {
if (len > n_to_add) /* Don't write more than n_to_add bytes. */
len = n_to_add;
if (generate_data(v[i].iov_base, len) < 0) {
/* If there was a data during data generation, we can just stop
/* If there was a problem during data generation, we can just stop
here; no data will be committed to the buffer. */
return;
}
Expand Down Expand Up @@ -1153,7 +1153,23 @@ When you no longer want to use a file segment, you can free it with
evbuffer_file_segment_free(). The actual storage won't be released until no
evbuffer any longer holds a reference to a piece of the file segment.

These file-segment functions first appeared in Libevent 2.1.1-alpha.
.Interface
[code,C]
--------
typedef void (*evbuffer_file_segment_cleanup_cb)(
struct evbuffer_file_segment const *seg, int flags, void *arg);

void evbuffer_file_segment_add_cleanup_cb(struct evbuffer_file_segment *seg,
evbuffer_file_segment_cleanup_cb cb, void *arg);
--------

You can add a callback function to a file segment that will be invoked when
the final reference to the file segment has been released and the file
segment is about to get freed. This callback *must not* attempt to revivify
the file segment, add it to any buffers, or so on.

These file-segment functions first appeared in Libevent 2.1.1-alpha;
evbuffer_file_segment_add_cleanup_cb() was added in 2.1.2-alpha.

Adding an evbuffer to another by reference
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
4 changes: 2 additions & 2 deletions Ref8_listener.txt
Expand Up @@ -29,7 +29,7 @@ void evconnlistener_free(struct evconnlistener *lev);

The two evconnlistener_new*() functions both allocate and return a new
connection listener object. A connection listener uses an event_base to
note when a there is a new TCP connection on a given listener socket.
note when there is a new TCP connection on a given listener socket.
When a new connection arrives, it invokes the callback function you give it.

In both functions, the 'base' parameter is an event_base that the listener
Expand Down Expand Up @@ -94,7 +94,7 @@ LEV_OPT_THREADSAFE::

LEV_OPT_DISABLED::
Initialize the listener to be disabled, not enabled. You can
turn it on manually with evconnlistener_disable(). New in Libevent
turn it on manually with evconnlistener_enable(). New in Libevent
2.1.1-alpha.

LEV_OPT_DEFERRED_ACCEPT::
Expand Down
6 changes: 3 additions & 3 deletions Ref9_dns.txt
Expand Up @@ -357,7 +357,7 @@ Otherwise, it leaves the evdns_base empty, with no nameservers or
options configured.

When you no longer need an evdns_base, you can free it with
evdns_base_free. If its 'fail_request' argument is true, it will
evdns_base_free. If its 'fail_requests' argument is true, it will
make all in-flight requests get their callbacks invoked with a
'canceled' error code before it frees the base.

Expand Down Expand Up @@ -468,10 +468,10 @@ options::
How many DNS requests do we allow to be pending at once? (If
we try to do more requests than this, the extras will stall
until the earlier ones are answered or time out.) Defaults to
XXX.
64.
attempts:INT;;
How many times to we re-transmit a DNS request before giving up
on it? Defaults to XXX.
on it? Defaults to 3.
randomize-case:INT;;
If nonzero, we randomize the case on outgoing DNS requests and
make sure that replies have the same case as our requests. This
Expand Down

0 comments on commit ef3b31e

Please sign in to comment.