432 Commits

Author SHA1 Message Date
Nick Mathewson
e0972c2138 Use conditions instead of current_event_lock to fix a deadlock.
Avi Bab correctly noted as bug 3044479 the fact that any thread
blocking on current_event_lock will do so while holding
th_base_lock, making it impossible for the currently running event's
callback to call any other functions that require th_base_lock.

This patch switches the current_event_lock code to instead use a
condition variable that we wait on if we're trying to mess with
a currently-executing event, and that we signal when we're done
executing a callback if anybody is waiting on it.
2010-08-17 13:18:18 -04:00
Nick Mathewson
ec347b9225 Move event-config.h to include/event2
This change means that all required include files are in event2, and
all files not in event2/* are optional.
2010-08-06 20:21:27 -04:00
Nick Mathewson
42a8c71112 Build more cleanly with NetBSDs that dislike toupper(char)
To be fair, when char can be signed, if toupper doesn't take negative
characters, toupper(char) is a very bad idea.  So let's just use the
nice safe EVUTIL_TOUPPER instead.  (It explicitly only upcases ASCII,
but we only use it for identifiers that we know to be ASCII anyway).
2010-07-31 17:10:04 -04:00
Nick Mathewson
fc5e0a2344 Don't race when calling event_active/event_add on a running signal event
There was previously no lock protecting the signal event's
ev_ncalls/ev_pncalls fields, which were accessed by all of
event_signal_closure, event_add_internal, event_del_internal, and
event_active_nolock.  This patch fixes this race by using the
current_event_lock in the same way it's used to prevent
event_del_internal from touching an event that's currently running.
2010-07-05 14:39:39 -04:00
Nick Mathewson
61e1eeec6f Tidy up the code in evthread_make_base_notifiable a little
Previously, we had a few conditional statements with the "if (...)"
inside an #ifdef and the body outside.  That kind of thing is hard to
read.
2010-07-05 13:24:45 -04:00
Nick Mathewson
a5bc15b2e1 Drain th_notify_fd[0] more bytes at a time. 2010-07-05 13:24:12 -04:00
Nick Mathewson
17522d2af8 Fix a deadlock related to event-base notification. Diagnosed by Zhou Li, Avi Bab, and Scott Lamb.
The problem was that the thread doing the notification could block on
write in evthread_notify_base_default while holding the th_base_lock.
The main thread would never drain th_notify_fd[0], since it would need
th_base_lock to actually trigger events.
2010-07-05 13:17:47 -04:00
Nick Mathewson
6d195109eb Avoid event_del on uninitialized event in event_base_free
This was mostly harmless, since the event was cleared with calloc, but
still it's not a correct thing to do.
2010-05-13 15:40:43 -04:00
Nick Mathewson
c16e68448c Rename current_base symbol to event_global_current_base_
The "current_base" symbol was never actually declared in an exported
header; it's hideously deprecated, and it was the one remaining
exported symbol (fwict) that was prefixed with neither ev nor
bufferevent nor _ev nor _bufferevent.

codesearch.google.com turns up no actual attempts to use our
current_base from outside libevent.
2010-05-04 13:27:36 -04:00
Nick Mathewson
99e50e90bd Fix symbol conflict between mm_*() macros and libmm
Our mm_malloc, mm_calloc, etc functions were all exported, since C
hasn't got a nice portable way to say "we want to use this function
inside our library but not export it to others".  But they apparently
conflict with anything else that calls its symbols mm_*, as libmm does.

This patch renames the mm_*() functions to event_mm_*_(, and defines
maros in mm_internal so that all the code we have that uses mm_*()
will still work.  New code should also prefer the mm_*() macro names.

Reported by Gernot Tenchio.  Fixes sf bug 2996541
2010-05-04 12:57:40 -04:00
Frank Denis
71afc52580 Fix nonstandard TAILQ_FOREACH_REVERSE() definition
Every current BSD system providing TAILQ_* macros define
TAILQ_FOREACH_REVERSE in this order:

TAILQ_FOREACH_REVERSE(var, head, field, headname)

However, libevent defines it in another order:

TAILQ_FOREACH_REVERSE(var, head, headname, field)

Here's a trivial patch to have libevent compatible with stock queue.h headers.

-Frank.

[From sourceforge patch 2995179. codesearch.google.com confirms that
the only people defining TAILQ_FOREACH_REVERSE our way are people
using it in a compatibility header like us.  Did we copy this from
OpenSSH or something?]

-Nick
2010-05-03 11:40:09 -04:00
Nick Mathewson
9ecf0d486d Catch attempts to enable debug_mode too late
Debug mode needs to be enabled before any event is setup or any
event_base is created.  Otherwise, we will not have recorded when events
were first setup or added, and so it will look like a bug later when we
delete or free them.

I have already confused myself because of this requirement, so let's
make Libevent catch it for the next poor forgetful developer like me.
2010-04-28 12:20:23 -04:00
Nick Mathewson
06a4443abe Unit-test every evbuffer_add_file() implementation.
Previously, we'd only test the default one, even if the others were still
compiled in.
2010-04-09 15:28:26 -04:00
Nick Mathewson
b557b175c0 Detect and refuse reentrant event_base_loop() calls
Calling event_base_loop on a base from inside a callback invoked by
that same base, or from two threads at once, has long been a way to
get exceedingly hard-to-diagnose errors.  This patch adds code to
detect such reentrant invocatinos, and exit quickly with a warning
that should explain what went wrong.
2010-03-21 13:28:48 -04:00
Nick Mathewson
70a44b61bb Avoid a spurious close(-1) on Linux
On Linux, we use only one fd to do main-thread signaling (since we have
eventfd()), so we don't need to close th_notify_fd[1] as we would if we were
using a socketpair.
2010-03-13 00:31:14 -05:00
Nick Mathewson
cdd4c4905b Try to comment some of the event code more 2010-03-12 00:38:50 -05:00
Nick Mathewson
2c2618d858 more whitespace normalization 2010-03-05 13:00:15 -05:00
Nick Mathewson
c7cf6f0049 Replace users of "int fd" with "evutil_socket_t fd" in portable code
Remeber, win32 has a socket type that's actually a handle, so if
there's a chance that code is run on win32, we can't use "int" as the
socket type.

This isn't a blind search-and-replace: sometimes an fd is really in
fact for a file, and not a socket at all.
2010-03-05 12:47:46 -05:00
Nick Mathewson
17efc1cdfa Update all our copyright notices to say "2010" 2010-03-04 01:38:48 -05:00
Nick Mathewson
ad85908a4f Fix compilation with --disable-debug-mode 2010-02-28 12:52:39 -05:00
Nick Mathewson
38ec0a773b Fix a bug in resetting timeouts on persistent events when IO triggers.
When we fixed persistent timeouts to make them reset themselves
based on the previous scheduled time rather than the current
time... we made them do so regardless of whether the event was
triggering because of a timeout or not!

This was of course bogus.  When a _timeout_ triggers, we should
schedule the event for N seconds based on the last
_schedule_ time... but when IO triggers, we should reset the
timeout for N seconds after now.
2010-02-23 15:20:33 -05:00
Nick Mathewson
e2642f0a88 Fix some race conditions in persistent events and event_reinit
I found these by adding an EVENT_BASE_ASSERT_LOCKED() call to most
of the functions in event.c that can only be called while holding
the lock.

event_reinit() never grabbed the lock, but it needed to.

event_persist_closure accessed the base to call event_add_internal()
and gettime() when its caller had already dropped the lock.

event_pending() called gettime() without grabbing the lock.
2010-02-23 15:20:33 -05:00
Nick Mathewson
e5cf98795e Clean up formatting: remove trailing spaces 2010-02-18 17:46:56 -05:00
Nick Mathewson
e5bbd40ad7 Clean up formatting: use tabs, not 8-spaces, to indent. 2010-02-18 17:44:09 -05:00
Nick Mathewson
8fdf09c09d Clean up formatting: Disallow space-before-tab. 2010-02-18 17:08:50 -05:00
Nick Mathewson
d38a7a1931 const-ify a few more functions in event.h 2010-02-02 15:44:10 -05:00
Nick Mathewson
137f2c602f Try to fix a warning in hash_debug_entry
Apparently some 64-bit platforms don't like it when you say

   unsigned hash(void *p)
   {
      return (unsigned)p;
   }

even if you really honestly don't want the high bits of p.  Perhaps
they will tolerate it if I say the equivalent of

   unsigned hash(void *p)
   {
      return (unsigned) (uintptr_t) p;
   }
2010-01-26 12:08:34 -05:00
Nick Mathewson
a66e947b8b Use less memory for each entry in a hashtable
Our hash-table implementation stored a copy of the hash code in each
element.  But as we were using it, all of our hash codes were
ridiculously easy to calculate: most of them were just a matter of a
load and a shift.

This patch lets ht-internal be built in either of two ways: one caches
the hash-code for each element, and one recalculates it each time it's
needed.

This patch also chooses a slightly better hash code for
event_debug_entry.
2010-01-25 13:53:17 -05:00
Nick Mathewson
a19b4a05e6 Call event_debug_unassign on internal events
I don't expect that many users will be so religious about calling
unassign, but we need to be so that it's at least possible to use
debug mode without eating memory.
2010-01-25 13:53:17 -05:00
Nick Mathewson
cd17c3acd5 Add support for a "debug mode" to try to catch common errors.
Right now it only catches cases where we aren't initializing events,
or where we are re-initializing events without deleting them first.
These are however shockingly common.
2010-01-25 13:53:13 -05:00
Nick Mathewson
0683950384 Functions to access more fields of struct event.
Once event_assign() or event_new() had been called, there was no way
to get at a copy of the event's callback, callback argument, or
configured events.  This patch adds an accessor function for each, and
an all-fields accessor for code that wants to re-assign one field of
an event.

This patch also adds a function to return sizeof(struct event), so
that code with intense RAM needs can still retain ABI compatibility
between versions of Libevent without having to heap-allocate every
struct event individually.

The code here was first proposed by Pavel Pisa.
2010-01-19 14:01:36 -05:00
Nick Mathewson
27308aae4d Changelist code to defer event changes until just before dispatch
This is necessary or useful for a few reasons:

    1) Sometimes applications will add and delete the same event more
       than once between calls to dispatch.  Processing these changes
       immediately is needless, and potentially expensive (especially
       if we're on a system that makes one syscall per changed event).

       Yes, this actually happens in practice for nonpathological
       code, such as in cases where the user's callback conditionally
       re-adds a non-persistent event, or where draining a buffer
       turns off writing and invokes a user callback which adds more
       data which in turn re-enabled writing.

    2) Sometimes we can coalesce multiple changes on the same fd into
       a single syscall if we know about them in advance.  For
       example, epoll can do an add and a delete at the same time, but
       only if we have found out about both of them before we tell
       epoll.

    3) Sometimes adding an event that we immediately delete can cause
       unintended consequences: in kqueue, this makes pending events
       get reported spuriously.
2010-01-14 16:31:22 -05:00
Nick Mathewson
47854a802a Expose our cached gettimeofday value with a new interface
I've got a two use case that wants this for a fairly sensible purpose:
one external and on internal.
2009-12-28 16:11:18 -05:00
Nick Mathewson
da1718b289 Fix a locking bug in event_base_loop()
We previously were releasing the lock when we exited the main loop
in some ways, but not in others.
2009-11-27 17:36:51 -05:00
Nick Mathewson
76cd2b70bb Stop passing EVTHREAD_READ and EVTHREAD_WRITE to non-rw locks.
Previously, our default lock model kind of assumed that every lock was
potentially a read-write lock.  This was a poor choice, since
read-write locks are far more expensive than regular locks, and so the
lock API should only use them when we can actually take advantage of
them.  Neither our pthreads or win32 lock implementation provided rw
locks.

Now that we have a way (not currently used!) to	indicate that we
really want a read-write lock, we shouldn't actually say "lock this
for reading" or "lock this for writing" unless we mean it.
2009-11-27 17:36:51 -05:00
Nick Mathewson
347952ffe0 Revise the locking API: deprecate the old locking callbacks and add trylock.
Previously, there was no good way to request different kinds of lock
(say, read/write vs writeonly or recursive vs nonrecursive), or for a
lock function to signal failure (which would be important for a
trylock mode).

This patch revises the lock API to be a bit more useful.  The older
lock calls are still supported for now.

We also add a debugging mode to catch common errors in using the
locking APIs.
2009-11-27 17:36:24 -05:00
Nick Mathewson
91fe23fc08 Tolerate code that returns from a fatal_cb.
Also, replace more abort() calls with EVUTIL_ASSERT() or event_errx.
2009-11-20 15:46:04 -05:00
Nick Mathewson
767eb70f50 Fix compilation with threading disabled.
svn:r1546
2009-11-18 21:16:33 +00:00
Nick Mathewson
18a8cfac39 Prefer calloc(a,b) to malloc(a*b). via openbsd.
svn:r1531
2009-11-15 19:00:12 +00:00
Nick Mathewson
629a613398 When running set[ug]id, don't check the environment.
Idea from OpenBSD, but made a bit more generic to handle uncivilized lands
that do not define issetugid.

svn:r1530
2009-11-15 18:59:59 +00:00
Nick Mathewson
74871cacb8 Change event_base.activequeues to "array of eventlist".
Previously, event_base.activequeues was of type "array of pointers to
eventlist."  This was pointless: none of the eventlists were allowed
to be NULL.  Worse, it was inefficient:

  - It made looking up an active event queue take two pointer
    deferences instead of one, thus risking extra cache misses.
  - It used more RAM than it needed to, because of the extra pointer
    and the malloc overhead.

Also, this patch fixes a bug where we were saying
calloc(N,N*sizeof(X)) instead of calloc(N,sizeof(X)) when allocating
activequeues.  That part, I'll backport.

Also, we warn and return -1 on failure to allocate activequeues,
rather than calling event_err.

svn:r1525
2009-11-09 19:37:27 +00:00
Nick Mathewson
e88079a82c Make persistent timeouts more accurate.
Previously, if the user scheduled a persistent timeout for {1,0}, we
would schedule the first one at "now+one second", and then when we
were about to run its callback, we would schedule it again for one
second after that.  This would introduce creeping delays to the event
that was supposed to run every second.

Now, we schedule the event for one second after it was _last
scheduled_.  To do this, we introduce internal code to add an event at
an _absolute_ tv rather than at now+tv.

svn:r1520
2009-11-09 18:30:57 +00:00
Nick Mathewson
59be8942c9 Make sure that common timeouts are inserted in-order.
This code should be a no-op, except under strange thread contention
situations.

svn:r1519
2009-11-09 18:30:48 +00:00
Nick Mathewson
ab96b5f3f5 Add an option to disable the timeval cache.
svn:r1518
2009-11-09 18:30:33 +00:00
Nick Mathewson
693c24ef9d Implement queued timeouts for case where many timeouts are the same.
Libevent's current timeout code is relatively optimized for the
randomly scattered timeout case, where events are added with their
timeouts in no particular order.  We add and remove timeouts with
O(lg n) behavior.

Frequently, however, an application will want to have many timeouts
of the same value.  For example, we might have 1000 bufferevents,
each with a 2 second timeout on reading or writing.  If we knew this
were always the case, we could just put timeouts in a queue and get
O(1) add and remove behavior.  Of course, a queue would give O(n)
performance for a scattered timeout pattern, so we don't want to
just switch the implementation.

This patch gives the user the ability to explicitly tag certain
timeout values as being "very common".  These timeout values have a
cookie encoded in the high bits of their tv_usec field to indicate
which queue they belong on.  The queues themselves are each
triggered by an entry in the minheap.

See the regress_main.c code for an example use.

svn:r1517
2009-11-09 17:16:30 +00:00
Nick Mathewson
784b8773a4 We do not work any more without an event-config.h; stop pretending that it is meaningful to check for HAVE_CONFIG_H
svn:r1516
2009-11-06 21:46:57 +00:00
Nick Mathewson
0fd0255fa4 Remove compat/sys/_time.h
I've gone through everything that it declared to see where it was used,
and it seems that we probably don't need it anywhere.

Here's what it declared, and why I think we're okay dropping it.

o struct timeval {}
  (Used all over, and we can't really get away with declaring it ourselves;
  we need the same definition the system uses.  If we can't find struct
  timeval, we're pretty much sunk.)

o struct timespec {}
  (Used in event.c, evdns.c, kqueue.c, evport.c.  Of these,
   kqueue.c and event.c include sys/_time.h.  event.c conditions its use on
   _EVENT_HAVE_CLOCK_GETTIME, and kqueue() only works if timespec is defined.)

o TIMEVAL_TO_TIMESPEC
  (Used in kqueue.c, but every place with kqueue has sys/time.h)

o struct timezone {}
  (event2/util.h has a forward declaration; only evutil.c references it and
   doesn't look at its contents.)

o timerclear, timerisset, timercmp, timeradd, timersub
  (Everything now uses the evutil_timer* variants.)

o ITIMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF, struct itemerval
  (These are only used in test/regress.c, which does not include _time.h)

o CLOCK_REALTIME
  (Only used in evdns.c, which does not include _time.h)

o TIMESPEC_TO_TIMEVAL
o DST_*
o timespecclear, timespecisset, timespeccmp, timespecadd, timespecsub
o struct clockinfo {}
o CLOCK_VIRTUAL, CLOCK_PROF
o TIMER_RELTIME, TIMER_ABSTIME
  (unused)

svn:r1494
2009-11-03 19:54:56 +00:00
Nick Mathewson
904b5721cb Avoid calling exit() during event_base_new*()
Previously, each of the three make-an-event-base functions would exit
under different, weird circumstances, but return NULL on others.
  - All three would exit on OOM sometimes.
  - event_base_new() and event_init() would die	if all backends	were
    disabled.
  - None of them would die if the socketpair() call failed.

Now, only event_init() exits on failure, and it exits on every kind of
failure.  event_base_new() and event_base_new_with_config() never do.

svn:r1472
2009-10-27 06:47:25 +00:00
Nick Mathewson
a2a7d1d123 Do not call the locking variant of event_add or event_active in some cases when we know we have the lock.
svn:r1471
2009-10-27 05:16:32 +00:00
Nick Mathewson
d386dc89b5 Refactor event_assing even more to avoid unnecessary calls
svn:r1470
2009-10-27 05:16:23 +00:00