文本文件  |  769行  |  32.6 KB

                         What's new in Libevent 2.1
                             Nick Mathewson

0. Before we start

0.1. About this document

  This document describes the key differences between Libevent 2.0 and
  Libevent 2.1, from a user's point of view.  It's a work in progress.

  For better documentation about libevent, see the links at
  http://libevent.org/

  Libevent 2.1 would not be possible without the generous help of
  numerous volunteers.  For a list of who did what in Libevent 2.1,
  please see the ChangeLog!

  NOTE: I am very sure that I missed some thing on this list.  Caveat
  haxxor.

0.2. Where to get help

  Try looking at the other documentation too.  All of the header files
  have documentation in the doxygen format; this gets turned into nice
  HTML and linked to from the libevent.org website.

  There is a work-in-progress book with reference manual at
  http://www.wangafu.net/~nickm/libevent-book/ .

  You can ask questions on the #libevent IRC channel at irc.oftc.net or
  on the mailing list at libevent-users@freehaven.net.  The mailing list
  is subscribers-only, so you will need to subscribe before you post.

0.3. Compatibility

  Our source-compatibility policy is that correct code (that is to say,
  code that uses public interfaces of Libevent and relies only on their
  documented behavior) should have forward source compatibility: any
  such code that worked with a previous version of Libevent should work
  with this version too.

  We don't try to do binary compatibility except within stable release
  series, so binaries linked against any version of Libevent 2.0 will
  probably need to be recompiled against Libevent 2.1.4-alpha if you
  want to use it.  It is probable that we'll break binary compatibility
  again before Libevent 2.1 is stable.

1. New APIs and features

1.1. New ways to build libevent

  We now provide an --enable-gcc-hardening configure option to turn on
  GCC features designed for increased code security.

  There is also an --enable-silent-rules configure option to make
  compilation run more quietly with automake 1.11 or later.

  You no longer need to use the --enable-gcc-warnings option to turn on
  all of the GCC warnings that Libevent uses.  The only change from
  using that option now is to turn warnings into errors.

  For IDE users, files that are not supposed to be built are now
  surrounded with appropriate #ifdef lines to keep your IDE from getting
  upset.

  There is now an alternative cmake-based build process; cmake users
  should see the relevant sections in the README.


1.2. New functions for events and the event loop

  If you're running Libevent with multiple event priorities, you might
  want to make sure that Libevent checks for new events frequently, so
  that time-consuming or numerous low-priority events don't keep it from
  checking for new high-priority events.  You can now use the
  event_config_set_max_dispatch_interval() interface to ensure that the
  loop checks for new events either every N microseconds, every M
  callbacks, or both.

  When configuring an event base, you can now choose whether you want
  timers to be more efficient, or more precise.  (This only has effect
  on Linux for now.)  Timers are efficient by default: to select more
  precise timers, use the EVENT_BASE_FLAG_PRECISE_TIMER flag when
  constructing the event_config, or set the EVENT_PRECISE_TIMER
  environment variable to a non-empty string.

  There is an EVLOOP_NO_EXIT_ON_EMPTY flag that tells event_base_loop()
  to keep looping even when there are no pending events.  (Ordinarily,
  event_base_loop() will exit as soon as no events are pending.)

  Past versions of Libevent have been annoying to use with some
  memory-leak-checking tools, because Libevent allocated some global
  singletons but provided no means to free them.  There is now a
  function, libevent_global_shutdown(), that you can use to free all
  globally held resources before exiting, so that your leak-check tools
  don't complain.  (Note: this function doesn't free non-global things
  like events, bufferevents, and so on; and it doesn't free anything
  that wouldn't otherwise get cleaned up by the operating system when
  your process exit()s.  If you aren't using a leak-checking tool, there
  is not much reason to call libevent_global_shutdown().)

  There is a new event_base_get_npriorities() function to return the
  number of priorities set in the event base.

  Libevent 2.0 added an event_new() function to construct a new struct
  event on the heap.  Unfortunately, with event_new(), there was no
  equivalent for:

         struct event ev;
         event_assign(&ev, base, fd, EV_READ, callback, &ev);

  In other words, there was no easy way for event_new() to set up an
  event so that the event itself would be its callback argument.
  Libevent 2.1 lets you do this by passing "event_self_cbarg()" as the
  callback argument:

         struct event *evp;
         evp = event_new(base, fd, EV_READ, callback,
         event_self_cbarg());

  There's also a new event_base_get_running_event() function you can
  call from within a Libevent callback to get a pointer to the current
  event.  This should never be strictly necessary, but it's sometimes
  convenient.

  The event_base_once() function used to leak some memory if the event
  that it added was never actually triggered.  Now, its memory is
  tracked in the event_base and freed when the event_base is freed.
  Note however that Libevent doesn't know how to free any information
  passed as the callback argument to event_base_once is still something
  you'll might need a way to de-allocate yourself.

  There is an event_get_priority() function to return an event's
  priority.

  By analogy to event_base_loopbreak(), there is now an
  event_base_loopcontinue() that tells Libevent to stop processing
  active event callbacks, and re-scan for new events right away.

  There's a function, event_base_foreach_event(), that can iterate over
  every event currently pending or active on an event base, and invoke a
  user-supplied callback on each. The callback must not alter the events
  or add or remove anything to the event base.

  We now have an event_remove_timer() function to remove the timeout on
  an event while leaving its socket and/or signal triggers unchanged.
  (If we were designing the API from scratch, this would be the behavior
  of "event_add(ev, NULL)" on an already-added event with a timeout. But
  that's a no-op in past versions of Libevent, and we don't want to
  break compatibility.)

  You can use the new event_base_get_num_events() function to find the
  number of events active or pending on an event_base. To find the
  largest number of events that there have been since the last call, use
  event_base_get_max_events().

  You can now activate all the events waiting for a given fd or signal
  using the event_base_active_by_fd() and event_base_active_by_signal()
  APIs.

  On backends that support it (currently epoll), there is now an
  EV_CLOSED flag that programs can use to detect when a socket has
  closed without having to read all the bytes until receiving an EOF.

1.3. Event finalization

1.3.1. Why event finalization?

  Libevent 2.1 now supports an API for safely "finalizing" events that
  might be running in multiple threads, and provides a way to slightly
  change the semantics of event_del() to prevent deadlocks in
  multithreaded programs.

  To motivate this feature, consider the following code, in the context
  of a mulithreaded Libevent application:

        struct connection *conn = event_get_callback_arg(ev);
        event_del(ev);
        connection_free(conn);

  Suppose that the event's callback might be running in another thread,
  and using the value of "conn" concurrently.  We wouldn't want to
  execute the connection_free() call until "conn" is no longer in use.
  How can we make this code safe?

  Libevent 2.0 answered that question by saying that the event_del()
  call should block if the event's callback is running in another
  thread.  That way, we can be sure that event_del() has canceled the
  callback (if the callback hadn't started running yet), or has waited
  for the callback to finish.

  But now suppose that the data structure is protected by a lock, and we
  have the following code:

        void check_disable(struct connection *connection) {
            lock(connection);
            if (should_stop_reading(connection))
                    event_del(connection->read_event);
            unlock(connection);
        }

  What happens when we call check_disable() from a callback and from
  another thread?  Let's say that the other thread gets the lock
  first.  If it decides to call event_del(), it will wait for the
  callback to finish.  But meanwhile, the callback will be waiting for
  the lock on the connection.  Since each threads is waiting for the
  other one to release a resource, the program will deadlock.

  This bug showed up in multithreaded bufferevent programs in 2.1,
  particularly when freeing bufferevents.  (For more information, see
  the "Deadlock when calling bufferevent_free from an other thread"
  thread on libevent-users starting on 6 August 2012 and running through
  February of 2013.  You might also like to read my earlier writeup at
  http://archives.seul.org/libevent/users/Feb-2012/msg00053.html and
  the ensuing discussion.)

1.3.2. The EV_FINALIZE flag and avoiding deadlock

  To prevent the deadlock condition described above, Libevent
  2.1.3-alpha adds a new flag, "EV_FINALIZE".  You can pass it to
  event_new() and event_assign() along with EV_READ, EV_WRITE, and the
  other event flags.

  When an event is constructed with the EV_FINALIZE flag, event_del()
  will not block on that event, even when the event's callback is
  running in another thread.  By using EV_FINALIZE, you are therefore
  promising not to use the "event_del(ev); free(event_get_callback_arg(ev));"
  pattern, but rather to use one of the finalization functions below to
  clean up the event.

  EV_FINALIZE has no effect on a single-threaded program, or on a
  program where events are only used from one thread.


  There are also two new variants of event_del() that you can use for
  more fine-grained control:
     event_del_noblock(ev)
     event_del_block(ev)
  The event_del_noblock() function will never block, even if the event
  callback is running in another thread and doesn't have the EV_FINALIZE
  flag.  The event_del_block() function will _always_ block if the event
  callback is running in another thread, even if the event _does_ have
  the EV_FINALIZE flag.

  [A future version of Libevent may have a way to make the EV_FINALIZE
  flag the default.]

1.3.3. Safely finalizing events

  To safely tear down an event that may be running, Libevent 2.1.3-alpha
  introduces event_finalize() and event_free_finalize(). You call them
  on an event, and provide a finalizer callback to be run on the event
  and its callback argument once the event is definitely no longer
  running.

  With event_free_finalize(), the event is also freed once the finalizer
  callback has been invoked.

  A finalized event cannot be re-added or activated.  The finalizer
  callback must not add events, activate events, or attempt to
  "resucitate" the event being finalized in any way.

  If any finalizer callbacks are pending as the event_base is being
  freed, they will be invoked.  You can override this behavior with the
  new function event_base_free_nofinalize().

1.4. New debugging features

  You can now turn on debug logs at runtime using a new function,
  event_enable_debug_logging().

  The event_enable_lock_debugging() function is now spelled correctly.
  You can still use the old "event_enable_lock_debuging" name, though,
  so your old programs shouldnt' break.

  There's also been some work done to try to make the debugging logs
  more generally useful.

1.5. New evbuffer functions

  In Libevent 2.0, we introduced evbuffer_add_file() to add an entire
  file's contents to an evbuffer, and then send them using sendfile() or
  mmap() as appropriate.  This API had some drawbacks, however.
  Notably, it created one mapping or fd for every instance of the same
  file added to any evbuffer.  Also, adding a file to an evbuffer could
  make that buffer unusable with SSL bufferevents, filtering
  bufferevents, and any code that tried to read the contents of the
  evbuffer.

  Libevent 2.1 adds a new evbuffer_file_segment API to solve these
  problems.  Now, you can use evbuffer_file_segment_new() to construct a
  file-segment object, and evbuffer_add_file_segment() to insert it (or
  part of it) into an evbuffer.  These segments avoid creating redundant
  maps or fds.  Better still, the code is smart enough (when the OS
  supports sendfile) to map the file when that's necessary, and use
  sendfile() otherwise.

  File segments can receive callback functions that are invoked when the
  file segments are freed.

  The evbuffer_ptr interface has been extended so that an evbuffer_ptr
  can now yield a point just after the end of the buffer.  This makes
  many algorithms simpler to implement.

  There's a new evbuffer_add_buffer() interface that you can use to add
  one buffer to another nondestructively.  When you say
  evbuffer_add_buffer_reference(outbuf, inbuf), outbuf now contains a
  reference to the contents of inbuf.

  To aid in adding data in bulk while minimizing evbuffer calls, there
  is an evbuffer_add_iovec() function.

  There's a new evbuffer_copyout_from() variant function to enable
  copying data nondestructively from the middle of a buffer.

  evbuffer_readln() now supports an EVBUFFER_EOL_NUL argument to fetch
  NUL-terminated strings from buffers.

  There's a new evbuffer_set_flags()/evbuffer_clear_flags() that you can use to
  set EVBUFFER_FLAG_DRAINS_TO_FD.

1.6. New functions and features: bufferevents

  You can now use the bufferevent_getcb() function to find out a
  bufferevent's callbacks.  Previously, there was no supported way to do
  that.

  The largest chunk readable or writeable in a single bufferevent
  callback is no longer hardcoded; it's now configurable with
  the new functions bufferevent_set_max_single_read() and
  bufferevent_set_max_single_write().

  For consistency, OpenSSL bufferevents now make sure to always set one
  of BEV_EVENT_READING or BEV_EVENT_WRITING when invoking an event
  callback.

  Calling bufferevent_set_timeouts(bev, NULL, NULL) now removes the
  timeouts from socket and ssl bufferevents correctly.

  You can find the priority at which a bufferevent runs with
  bufferevent_get_priority().

  The function bufferevent_get_token_bucket_cfg() can retrieve the
  rate-limit settings for a bufferevent; bufferevent_getwatermark() can
  return a bufferevent's current watermark settings.

  You can manually trigger a bufferevent's callbacks via
  bufferevent_trigger() and bufferevent_trigger_event().

  Also you can manually increment/decrement reference for bufferevent with
  bufferevent_incref()/bufferevent_decref(), it is useful in situations where a
  user may reference the bufferevent somewhere else.

  Now bufferevent_openssl supports "dirty" shutdown (when the peer closes the
  TCP connection before closing the SSL channel), see
  bufferevent_openssl_get_allow_dirty_shutdown() and
  bufferevent_openssl_set_allow_dirty_shutdown().

  And also libevent supports openssl 1.1.

1.7. New functions and features: evdns

  The previous evdns interface used an "open a test UDP socket" trick in
  order to detect IPv6 support.  This was a hack, since it would
  sometimes badly confuse people's firewall software, even though no
  packets were sent.  The current evdns interface-detection code uses
  the appropriate OS functions to see which interfaces are configured.

  The evdns_base_new() function now has multiple possible values for its
  second (flags) argument.  Using 1 and 0 have their old meanings, though the
  1 flag now has a symbolic name of EVDNS_BASE_INITIALIZE_NAMESERVERS.
  A second flag is now supported too: the EVDNS_BASE_DISABLE_WHEN_INACTIVE
  flag, which tells the evdns_base that it should not prevent Libevent from
  exiting while it has no DNS requests in progress.

  There is a new evdns_base_clear_host_addresses() function to remove
  all the /etc/hosts addresses registered with an evdns instance.

  Also there is evdns_base_get_nameserver_addr() for retrieve the address of
  the 'idx'th configured nameserver.

1.8. New functions and features: evconnlistener

  Libevent 2.1 adds the following evconnlistener flags:

    LEV_OPT_DEFERRED_ACCEPT -- Tells the OS that it doesn't need to
    report sockets as having arrived until the initiator has sent some
    data too.  This can greatly improve performance with protocols like
    HTTP where the client always speaks first.  On operating systems
    that don't support this functionality, this option has no effect.

    LEV_OPT_REUSEABLE_PORT -- Indicates that we ask to allow multiple servers
    to bind to the same port if they each set the option Ionly on Linux and
    >=3.9)

    LEV_OPT_DISABLED -- Creates an evconnlistener in the disabled (not
    listening) state.

  Libevent 2.1 changes the behavior of the LEV_OPT_CLOSE_ON_EXEC
  flag.  Previously, it would apply to the listener sockets, but not to
  the accepted sockets themselves.  That's almost never what you want.
  Now, it applies both to the listener and the accepted sockets.

1.9. New functions and features: evhttp

  **********************************************************************
  NOTE: The evhttp module will eventually be deprecated in favor of Mark
  Ellzey's libevhtp library.  Don't worry -- this won't happen until
  libevhtp provides every feature that evhttp does, and provides a
  compatible interface that applications can use to migrate.
  **********************************************************************

  Previously, you could only set evhttp timeouts in increments of one
  second.  Now, you can use evhttp_set_timeout_tv() and
  evhttp_connection_set_timeout_tv() to configure
  microsecond-granularity timeouts.

  Also there is evhttp_connection_set_initial_retry_tv() to change initial
  retry timeout.

  There are a new pair of functions: evhttp_set_bevcb() and
  evhttp_connection_base_bufferevent_new(), that you can use to
  configure which bufferevents will be used for incoming and outgoing
  http connections respectively.  These functions, combined with SSL
  bufferevents, should enable HTTPS support.

  There's a new evhttp_foreach_bound_socket() function to iterate over
  every listener on an evhttp object.

  Whitespace between lines in headers is now folded into a single space;
  whitespace at the end of a header is now removed.

  The socket errno value is now preserved when invoking an http error
  callback.

  There's a new kind of request callback for errors; you can set it with
  evhttp_request_set_error_cb(). It gets called when there's a request error,
  and actually reports the error code and lets you figure out which request
  failed.

  You can navigate from an evhttp_connection back to its evhttp with the
  new evhttp_connection_get_server() function.

  You can override the default HTTP Content-Type with the new
  evhttp_set_default_content_type() function

  There's a new evhttp_connection_get_addr() API to return the peer
  address of an evhttp_connection.

  The new evhttp_send_reply_chunk_with_cb() is a variant of
  evhttp_send_reply_chunk() with a callback to be invoked when the
  chunk is sent.

  The evhttp_request_set_header_cb() facility adds a callback to be
  invoked while parsing headers.

  The evhttp_request_set_on_complete_cb() facility adds a callback to be
  invoked on request completion.

  You can add linger-close for http server by passing
  EVHTTP_SERVER_LINGERING_CLOSE to evhttp_set_flags(), with this flag server
  read all the clients body, and only after this respond with an error if the
  clients body exceed max_body_size (since some clients cannot read response
  otherwise).

  The evhttp_connection_set_family() can bypass family hint to evdns.

  There are some flags available for connections, which can be installed with
  evhttp_connection_set_flags():
  - EVHTTP_CON_REUSE_CONNECTED_ADDR -- reuse connection address on retry (avoid
    extra DNS request).
  - EVHTTP_CON_READ_ON_WRITE_ERROR - try read error, since server may already
    close the connection.

  The evhttp_connection_free_on_completion() can be used to tell libevent to
  free the connection object after the last request has completed or failed.

  There is evhttp_request_get_response_code_line() if
  evhttp_request_get_response_code() is not enough for you.

  There are *evhttp_uri_parse_with_flags() that accepts
  EVHTTP_URI_NONCONFORMANT to tolerate URIs that do not conform to RFC3986.
  The evhttp_uri_set_flags() can changes the flags on URI.

1.10. New functions and features: evutil

  There's a function "evutil_secure_rng_set_urandom_device_file()" that
  you can use to override the default file that Libevent uses to seed
  its (sort-of) secure RNG.

  The evutil_date_rfc1123() returns date in RFC1123

  There are new API to work with monotonic timer -- monotonic time is
  guaranteed never to run in reverse, but is not necessarily epoch-based. Use
  it to make reliable measurements of elapsed time between events even when the
  system time may be changed:
  - evutil_monotonic_timer_new()/evutil_monotonic_timer_free()
  - evutil_configure_monotonic_time()
  - evutil_gettime_monotonic()

  Use evutil_make_listen_socket_reuseable_port() to set SO_REUSEPORT (linux >=
  3.9)

  The evutil_make_tcp_listen_socket_deferred() can make a tcp listener socket
  defer accept()s until there is data to read (TCP_DEFER_ACCEPT).

2. Cross-platform performance improvements

2.1. Better data structures

  We replaced several users of the sys/queue.h "TAILQ" data structure
  with the "LIST" data structure.  Because this data type doesn't
  require FIFO access, it requires fewer pointer checks and
  manipulations to keep it in line.

  All previous versions of Libevent have kept every pending (added)
  event in an "eventqueue" data structure.  Starting in Libevent 2.0,
  however, this structure became redundant: every pending timeout event
  is stored in the timeout heap or in one of the common_timeout queues,
  and every pending fd or signal event is stored in an evmap.  Libevent
  2.1 removes this data structure, and thereby saves all of the code
  that we'd been using to keep it updated.

2.2. Faster activations and timeouts

  It's a common pattern in older code to use event_base_once() with a
  0-second timeout to ensure that a callback will get run 'as soon as
  possible' in the current iteration of the Libevent loop.  We optimize
  this case by calling event_active() directly, and bypassing the
  timeout pool.  (People who are using this pattern should also consider
  using event_active() themselves.)

  Libevent 2.0 would wake up a polling event loop whenever the first
  timeout in the event loop was adjusted--whether it had become earlier
  or later.  We now only notify the event loop when a change causes the
  expiration time to become _sooner_ than it would have been otherwise.

  The timeout heap code is now optimized to perform fewer comparisons
  and shifts when changing or removing a timeout.

  Instead of checking for a wall-clock time jump every time we call
  clock_gettime(), we now check only every 5 seconds.  This should save
  a huge number of gettimeofday() calls.

2.3. Microoptimizations

  Internal event list maintainance no longer use the antipattern where
  we have one function with multiple totally independent behaviors
  depending on an argument:
      #define OP1 1
      #define OP2 2
      #define OP3 3
      void func(int operation, struct event *ev) {
        switch (op) {
          ...
        }
      }
  Instead, these functions are now split into separate functions for
  each operation:
      void func_op1(struct event *ev) { ... }
      void func_op2(struct event *ev) { ... }
      void func_op3(struct event *ev) { ... }

  This produces better code generation and inlining decisions on some
  compilers, and makes the code easier to read and check.

2.4. Evbuffer performance improvements

  The EVBUFFER_EOL_CRLF line-ending type is now much faster, thanks to
  smart optimizations.

2.5. HTTP performance improvements

   o Performance tweak to evhttp_parse_request_line. (aee1a97 Mark Ellzey)
   o Add missing break to evhttp_parse_request_line (0fcc536)

2.6. Coarse timers by default on Linux

  Due to limitations of the epoll interface, Libevent programs using epoll
  have not previously been able to wait for timeouts with accuracy smaller
  than 1 millisecond.  But Libevent had been using CLOCK_MONOTONIC for
  timekeeping on Linux, which is needlessly expensive: CLOCK_MONOTONIC_COARSE
  has approximately the resolution corresponding to epoll, and is much faster
  to invoke than CLOCK_MONOTONIC.

  To disable coarse timers, and get a more plausible precision, use the
  new EVENT_BASE_FLAG_PRECISE_TIMER flag when setting up your event base.

3. Backend/OS-specific improvements

3.1. Linux-specific improvements

  The logic for deciding which arguements to use with epoll_ctl() is now
  a table-driven lookup, rather than the previous pile of cascading
  branches.  This should minimize epoll_ctl() calls and make the epoll
  code run a little faster on change-heavy loads.

  Libevent now takes advantage of Linux's support for enhanced APIs
  (e.g., SOCK_CLOEXEC, SOCK_NONBLOCK, accept4, pipe2) that allow us to
  simultaneously create a socket, make it nonblocking, and make it
  close-on-exec.  This should save syscalls throughout our codebase, and
  avoid race-conditions if an exec() occurs after a socket is socket is
  created but before we can make it close-on-execute on it.

3.2. Windows-specific improvements

  We now use GetSystemTimeAsFileTime to implement gettimeofday.  It's
  significantly faster and more accurate than our old ftime()-based approach.

3.3. Improvements in the solaris evport backend.

  The evport backend has been updated to use many of the infrastructure
  improvements from Libevent 2.0.  Notably, it keeps track of per-fd
  information using the evmap infrastructure, and removes a number of
  linear scans over recently-added events.  This last change makes it
  efficient to receive many more events per evport_getn() call, thereby
  reducing evport overhead in general.

3.4. OSX backend improvements

  The OSX select backend doesn't like to have more than a certain number
  of fds set unless an "unlimited select" option has been set.
  Therefore, we now set it.

3.5. Monotonic clocks on even more platforms

  Libevent previously used a monotonic clock for its internal timekeeping
  only on platforms supporting the POSIX clock_gettime() interface. Now,
  Libevent has support for monotonic clocks on OSX and Windows too, and a
  fallback implementation for systems without monotonic clocks that will at
  least keep time running forwards.

  Using monotonic timers makes Libevent more resilient to changes in the
  system time, as can happen in small amounts due to clock adjustments from
  NTP, or in large amounts due to users who move their system clocks all over
  the timeline in order to keep nagware from nagging them.

3.6. Faster cross-thread notification on kqueue

  When a thread other than the one in which the main event loop is
  running needs to wake the thread running the main event loop, Libevent
  usually writes to a socketpair in order to force the main event loop
  to wake up.  On Linux, we've been able to use eventfd() instead.  Now
  on BSD and OSX systems (any anywhere else that has kqueue with the
  EVFILT_USER extension), we can use EVFILT_USER to wake up the main
  thread from kqueue.  This should be a tiny bit faster than the
  previous approach.

4. Infrastructure improvements

4.1. Faster tests

  I've spent some time to try to make the unit tests run faster in
  Libevent 2.1.  Nearly all of this was a matter of searching slow tests
  for unreasonably long timeouts, and cutting them down to reasonably
  long delays, though on one or two cases I actually had to parallelize
  an operation or improve an algorithm.

  On my desktop, a full "make verify" run of Libevent 2.0.18-stable
  requires about 218 seconds.  Libevent 2.1.1-alpha cuts this down to
  about 78 seconds.

  Faster unit tests are great, since they let programmers test their
  changes without losing their train of thought.

4.2. Finicky tests are now off-by-default

  The Tinytest unit testing framework now supports optional tests, and
  Libevent uses them.  By default, Libevent's unit testing framework
  does not run tests that require a working network, and does not run
  tests that tend to fail on heavily loaded systems because of timing
  issues.  To re-enable all tests, run ./test/regress using the "@all"
  alias.

4.3. Modernized use of autotools

  Our autotools-based build system has been updated to build without
  warnings on recent autoconf/automake versions.

  Libevent's autotools makefiles are no longer recursive.  This allows
  make to use the maximum possible parallelism to do the minimally
  necessary amount of work.  See Peter Miller's "Recursive Make
  Considered Harmful" at http://miller.emu.id.au/pmiller/books/rmch/ for
  more information here.

  We now use the "quiet build" option to suppress distracting messages
  about which commandlines are running.  You can get them back with
  "make V=1".

4.4. Portability

  Libevent now uses large-file support internally on platforms where it
  matters.  You shouldn't need to set _LARGEFILE or OFFSET_BITS or
  anything magic before including the Libevent headers, either, since
  Libevent now sets the size of ev_off_t to the size of off_t that it
  received at compile time, not to some (possibly different) size based
  on current macro definitions when your program is building.

  We now also use the Autoconf AC_USE_SYSTEM_EXTENSIONS mechanism to
  enable per-system macros needed to enable not-on-by-default features.
  Unlike the rest of the autoconf macros, we output these to an
  internal-use-only evconfig-private.h header, since their names need to
  survive unmangled.  This lets us build correctly on more platforms,
  and avoid inconsistencies when some files define _GNU_SOURCE and
  others don't.

  Libevent now tries to detect OpenSSL via pkg-config.

4.5. Standards conformance

  Previous Libevent versions had no consistent convention for internal
  vs external identifiers, and used identifiers starting with the "_"
  character throughout the codebase.  That's no good, since the C
  standard says that identifiers beginning with _ are reserved.  I'm not
  aware of having any collisions with system identifiers, but it's best
  to fix these things before they cause trouble.

  We now avoid all use of the _identifiers in the Libevent source code.
  These changes were made *mainly* through the use of automated scripts,
  so there shouldn't be any mistakes, but you never know.

  As an exception, the names _EVENT_LOG_DEBUG, _EVENT_LOG_MSG_,
  _EVENT_LOG_WARN, and _EVENT_LOG_ERR are still exposed in event.h: they
  are now deprecated, but to support older code, they will need to stay
  around for a while.  New code should use EVENT_LOG_DEBUG,
  EVENT_LOG_MSG, EVENT_LOG_WARN, and EVENT_LOG_ERR instead.

4.6. Event and callback refactoring

  As a simplification and optimization to Libevent's "deferred callback"
  logic (introduced in 2.0 to avoid callback recursion), Libevent now
  treats all of its deferrable callback types using the same logic it
  uses for active events.  Now deferred events no longer cause priority
  inversion, no longer require special code to cancel them, and so on.

  Regular events and deferred callbacks now both descend from an
  internal light-weight event_callback supertype, and both support
  priorities and take part in the other anti-priority-inversion
  mechanisms in Libevent.

  To avoid starvation from callback recursion (which was the reason we
  introduced "deferred callbacks" in the first place) the implementation
  now allows an event callback to be scheduled as "active later":
  instead of running in the current iteration of the event loop, it runs
  in the next one.

5. Testing

  Libevent's test coverage level is more or less unchanged since before:
  we still have over 80% line coverage in our tests on Linux, FreeBSD, NetBSD,
  Windows, OSX.
  There are some under-tested modules, though: we need to fix those.

  And now we have CI:
  - https://travis-ci.org/libevent/libevent
  - https://ci.appveyor.com/project/nmathewson/libevent

  And code coverage:
  - https://coveralls.io/github/libevent/libevent

  Plus there is vagrant boxes if you what to test it on more OS'es then
  travis-ci allows, and there is a wrapper (in python) that will parse logs and
  provide report:
  - https://github.com/libevent/libevent-extras/blob/master/tools/vagrant-tests.py

6. Contributing

  From now we have contributing guide and checkpatch.sh.