432 Commits

Author SHA1 Message Date
Azat Khuzhin
23c2914f6b Notify event base if there are no more events, so it can exit without delay
Fixes: #623
2018-04-26 01:14:49 +03:00
Azat Khuzhin
08a0d36607 Fix base unlocking in event_del() if event_base_set() runned in another thread
Image next situation:
  T1:                                        T2:
   event_del_()
     lock the event.ev_base.th_base_lock
     event_del_nolock_()                     event_set_base()
     unlock the event.ev_base.th_base_lock

In this case we will unlock the wrong base after event_del_nolock_()
returns, and deadlock is likely to happens, since event_base_set() do
not check any mutexes (due to it is possible to do this only if event is
not inserted anywhere).

So event_del_() has to cache the base before removing the event, and
cached base.th_base_lock after.
2018-02-28 07:26:11 +03:00
Azat Khuzhin
f0fd92f2c4 Convert event_debug_*() helpers from macros to static functions 2018-02-27 21:08:35 +03:00
yongqing.jiao
6cce7458d0 If precise_time is false, we should not set EVENT_BASE_FLAG_PRECISE_TIMER
Fixes: 630f077c296de61c7b99ed83bf30de11e75e2740 ("Simple unit tests for
monotonic timers")
2017-12-11 00:10:23 +03:00
James Synge
27934f0b39 Fix race in access to ev_res from event loop with event_active()
Detected using ThreadSanitizer, resolved by capturing the value
of ev_res in a local variable while the event is locked, then
passing that captured variable to the callback.

TSAN report:
  I0728 14:35:09.822118   WARNING: ThreadSanitizer: data race (pid=815501)
  I0728 14:35:09.822186     Write of size 2 at 0x7b2c00001bf2 by thread T80 (mutexes: write M1110835549570434736):
  I0728 14:35:09.822248       #0 event_active_nolock_ libevent/event.c:2893:14 (0a2b90577e830d775300664df77d0b91+0x1fdab28)
  I0728 14:35:09.822316       #1 event_active libevent/event.c:2858:2 (0a2b90577e830d775300664df77d0b91+0x1fdd10e)
  I0728 14:35:09.822379       #2 Envoy::Event::TimerImpl::enableTimer(std::chrono::duration<long, std::ratio<1l, 1000l> > const&) envoy/source/common/event/timer_impl.cc:24:5 (0a2b90577e830d775300664df77d0b91+0x459fa0)
  ...

  I0728 14:35:09.824146     Previous read of size 2 at 0x7b2c00001bf2 by main thread:
  I0728 14:35:09.824232       #0 event_process_active_single_queue libevent/event.c:1646:33 (0a2b90577e830d775300664df77d0b91+0x1fdf83d)
  I0728 14:35:09.824350       #1 event_process_active libevent/event.c (0a2b90577e830d775300664df77d0b91+0x1fd9ad8)
  I0728 14:35:09.824445       #2 event_base_loop libevent/event.c:1961 (0a2b90577e830d775300664df77d0b91+0x1fd9ad8)
  I0728 14:35:09.824550       #3 Envoy::Event::DispatcherImpl::run(Envoy::Event::Dispatcher::RunType) envoy/source/common/event/dispatcher_impl.cc:166:3 (0a2b90577e830d775300664df77d0b91+0x4576d9)
  ...

Fixes: #543 (pull-request)
2017-08-15 00:09:04 +03:00
José Luis Millán
0b4b0efdb8 Return from event_del() after the last event callback termination
Delete the event from the queue before blocking for the current
event callback termination.

Ensures that no callback is being executed when event_del() returns,
hence making this function a secure mechanism to access data which is
handled in the event callack.

Fixes: #236
Fixes: #225
Refs: 6b4b77a
Fixes: del_wait
2017-04-30 01:40:42 +03:00
Azat Khuzhin
177e2171cb Make event_count macros cleaner
Fixes: #489
2017-03-26 21:42:19 +03:00
Azat Khuzhin
9081b66c9c Export symbols for -fvisibility=hidden (under cmake)
Fixes: #442
2017-03-13 12:57:22 +03:00
Azat Khuzhin
94e7dcebc3 Fix -Werror=implicit-fallthrough (fixes gcc-7)
Fixes: #447
2017-01-29 17:58:31 +03:00
Nicholas Marriott
88640aa1ca event_reinit: make signals works after fork() without evsig_add()
event_reinit() removes the event, but only evsig_add puts it back. So any
signals set up before event_reinit will be ignored until another signal is
added.

Fixes: #307
2015-12-27 02:51:43 +03:00
Nicholas Marriott
ad0c237bc0 event_reinit: always re-init signal's socketpair
Before this patch event_reinit() only closes the signal socketpair fds and
recreates them if signals have been added, but this is wrong, since socketpair
fds created on backend init, and if we will not re-create them bad things in
child/parent signal handling will happens (and indeed this is what happens for
non-reinit backends like select).

Fixes: #307
2015-12-27 02:51:24 +03:00
Azat Khuzhin
7c8d0152dd Free event queues even for recursive finalizers
For finalizers we can register yet another finalizer out from finalizer, and
iff finalizer will be in active_later_queue we can add finalizer to
activequeues, and we will have events in activequeues after event_base_free()
returns, which is not what we want (we even have an assertion for this).

A simple case is bufferevent with underlying (i.e. filters) in inactive queue.

Fixes: regress bufferevent/bufferevent_socket_filter_inactive
2015-10-30 14:48:14 +03:00
Azat Khuzhin
f337296a5c Fix checking for make_base_notifiable()
Fixes: a068f2e5 ("event_debug_created_threadable_ctx_: fix compilation without
debug mode")
Found-after: 3e56da23 ("travis: add builds without debug mode into matrix")
2015-10-04 03:37:26 +03:00
Azat Khuzhin
a068f2e594 event_debug_created_threadable_ctx_: fix compilation without debug mode
The following command failed before:
$ ./configure --disable-debug-mode

Fixes: dcfb19a27b7760299bc9e7291c9abd88c59fd91a ("Debug mode option to error on
evthread init AFTER other event calls.")
2015-09-29 20:42:45 +03:00
Mark Ellzey
dcfb19a27b Debug mode option to error on evthread init AFTER other event calls.
- A handy event_enable_debug_mode() feature which will error and abort the
  application if any thread-aware libevent functions are called BEFORE the
  evthread API has been initialized (manually, or through
  evthread_use_windows_threads() / evthread_use_pthreads()

- This is done by setting the global debug variable
  'event_debug_created_threadable_ctx_' whenever the following functions
  are called:

     evthreadimpl_lock_alloc_()
     evthreadimpl_cond_alloc_()
     event_base_new_with_config() <- this checks to see if the thread
                                     callbacks are enabled first, so we
                                     have to manually set the variable.

- Example:

int main(int argc, char ** argv) {
    struct event_base * base;

    event_enable_debug_mode();

    base = event_base_new();

    evthread_use_pthreads();

    return 0;
}

When executed, the program will throw an error and exit:

[err] evthread initialization must be called BEFORE anything else!
2015-05-15 02:58:14 -07:00
Greg Hazel
6e7a580c15 tab 2015-03-24 17:45:52 -07:00
Greg Hazel
38cef641c4 fix the return value of event_deferred_cb_schedule_ 2015-03-24 17:29:40 -07:00
Nick Mathewson
a77a82a03f Merge remote-tracking branch 'azat/be-pair-fix-freeing-shared-lock-v5' 2015-02-04 08:37:32 -05:00
Azat Khuzhin
e5c87d18b0 event_free_debug_globals_locks(): disable lock debugging
This will allow to use library event after
event_free_debug_globals_locks()/libevent_global_shutdown() without
invalid read/write's.
2015-01-26 00:40:09 +03:00
Azat Khuzhin
941faaed39 event: call event_disable_debug_mode() in libevent_global_shutdown()
This will avoid leaking of event_debug_map_HT_GROW

I buildin it into libevent_glboal_shutdown() because
event_disable_debug_mode() -> event_free_debug_globals() ->
event_free_debug_globals_locks() will clean event_debug_map_lock_ that
used in event_disable_debug_mode().
2015-01-08 04:49:28 +03:00
Andrea Shepard
f2645f80c1 Implement new/free for struct evutil_monotonic_timer and export monotonic time functions 2014-12-04 09:30:20 -05:00
Nick Mathewson
37145c5659 Merge remote-tracking branch 'public/patches-2.0'
Conflicts:
	ChangeLog
	event.c
2014-11-30 21:07:55 -05:00
vjpai
3c7d6fcaff Fix race caused by event_active
There is a race between manual event_active and natural event activation. If both happen at the same time on the same FD, they would both be protected by the same event base lock except for 1 LoC where the fields of struct event are read without any kind of lock. This commit does those reads into local variables inside the lock and then invokes the callback with those local arguments outside the lock. In 2.0-stable, none of this is inside the lock; in HEAD, only the callback is read inside the lock. This gets the callback and all 3 arguments inside the lock before calling it outside the lock.
2014-11-30 19:24:15 -05:00
John Ohl
3cc0eace2e Fix use-after-free error in EV_CLOSURE_EVENT callback 2014-09-18 11:37:28 -04:00
Nick Mathewson
ec99dd82e4 Fix a use-after-free error on EV_CLOSURE_EVENT_FINALIZE callbacks
After running the callback, we were checking evcb->evcb_closure to
decide whether to call mm_free(ev).  But the callback itself might
have freed ev, so we need to grab that field first

Found with AddressSanitizer
2014-03-18 11:27:08 -04:00
Nick Mathewson
980597215d Move assert(ev) to before we use ev in EV_CLOSURE_EVENT_FINALIZE case
Based on a patch from Harlan Stenn.
2014-03-06 10:09:03 -05:00
John Ohl
2ea15ed0f6 Tweaked callbacks to prevent race condition (https://github.com/libevent/libevent/issues/104) 2014-01-27 14:54:55 -05:00
John Ohl
40830f1644 Tweaked callbacks to prevent race condition (https://github.com/libevent/libevent/issues/104) 2014-01-27 13:03:36 -05:00
Diego Giagio
b1b69ac7c1 Implemented EV_CLOSED event for epoll backend (EPOLLRDHUP).
- Added new EV_CLOSED event - detects premature connection close
  by clients without the necessity of reading all the pending
  data. Does not depend on EV_READ and/or EV_WRITE.

- Added new EV_FEATURE_EARLY_CLOSED feature for epoll.
  Must be supported for listening to EV_CLOSED event.

- Added new regression test: test-closed.c

- All regression tests passed (test/regress and test/test.sh)

- strace output of test-closed using EV_CLOSED:
    socketpair(PF_LOCAL, SOCK_STREAM, 0, [6, 7]) = 0
    sendto(6, "test string\0", 12, 0, NULL, 0) = 12
    shutdown(6, SHUT_WR)                    = 0
    epoll_ctl(3, EPOLL_CTL_ADD, 7, {EPOLLRDHUP, {u32=7, u64=7}}) = 0
    epoll_wait(3, {{EPOLLRDHUP, {u32=7, u64=7}}}, 32, 3000) = 1
    epoll_ctl(3, EPOLL_CTL_MOD, 7, {EPOLLRDHUP, {u32=7, u64=7}}) = 0
    fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4), ...})
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYM...
    write(1, "closed_cb: detected connection close "..., 45) = 45
2014-01-17 23:20:42 -02:00
Nick Mathewson
f9e091bf4e Merge remote-tracking branch 'asweeny86/event-count-max' 2014-01-06 12:11:30 -05:00
Andrew Sweeney
efbd3dcf28 Fixed bug using wrong variable in max event compare 2014-01-05 16:29:52 -05:00
Andrew Sweeney
5173bef50f Add access to max event count stats
This commit provides an interface for accessing and resetting the maximum
number of events in a given period.  This information provides better insight
into event queue pressure.
2013-12-30 14:06:20 -05:00
Nick Mathewson
87fa2b004a Unit tests for active_by_fd; unsupport active_by_fd(TIMEOUT)
[It turns out that event_base_active_by_fd(TIMEOUT) didn't actually
work right. Feel free to add it back in as a patch.]
2013-12-23 20:46:38 -05:00
Nick Mathewson
486594337a Add event_base_active_by_signal by analogy 2013-12-21 23:32:10 -05:00
Nick Mathewson
5c9da9a8a8 Sanity-check arguments to event_base_active_by_fd() 2013-12-21 23:21:33 -05:00
Nick Mathewson
93369ff4e9 Merge remote-tracking branch 'ghazel/event_base_active_by_fd' 2013-12-21 23:15:41 -05:00
Nick Mathewson
1c06985a01 Add an assertion for another of the complaints from coverity. See 1b065d07df196 2013-08-06 20:00:53 -04:00
Nick Mathewson
69b5c64704 Move event_debug_note_teardown_ before mm_free.
This isn't a bug, since only the pointer value of ev was used, but
it's probably best not to tempt fate.  Found by coverity.
2013-08-06 19:10:13 -04:00
Nick Mathewson
1b065d07df Add some assertions to please coverity.
In event_process_active_single_queue, EVLIST_INIT must be set on any
event that uses one of the event-only closures, and so "ev" will be
set in those cases.  But coverity's worried here (CIDs numerous).  So
instead, just add the assertions that should make it happy.
2013-08-06 19:10:13 -04:00
Mobai Zhang
0fa107d8cb Added event_base_get_num_events() 2013-07-02 16:01:02 -04:00
Nick Mathewson
3dc2d8ab83 Remove a debugging assert that should not have been left in 2013-05-28 10:14:51 -04:00
Azat Khuzhin
d3d999a116 Missed lock acquire/release in event_base_cancel_single_callback_()
Call backtrace:
...
event_queue_remove_active()
event_callback_cancel_nolock_()
event_base_cancel_single_callback_()
event_base_free_()
event_base_free()
...

Fix for e9ebef83
2013-05-10 21:40:45 -04:00
Nick Mathewson
f2925d78b6 Fix a windows compilation regression
This is github issue #57; reported by "efekty". I assume the compiler
is MSVC.
2013-04-30 22:57:25 -04:00
Nick Mathewson
3555befd1c Merge branch '21_deadlock_fix_v2' 2013-04-26 12:27:05 -04:00
Nick Mathewson
5d11f4f39a Make the event_finalize* functions return an error code 2013-04-26 12:18:38 -04:00
Nick Mathewson
a800b913ac More documentation for finalization feature 2013-04-26 12:18:38 -04:00
Nick Mathewson
e9ebef83a0 Always run pending finalizers when event_base_free() is called
There was actually a bug in the original version of this: it tried to
run the finalizers after (potentially) setting current_base to NULL;
but those finalizers could themselves (potentially) be invoking stuff
that needed to know about the current event_base.  So the right time to
do it is _before_ clearing current_base.
2013-04-26 12:18:07 -04:00
Nick Mathewson
8eedeabe50 Implement event_finalize() and related functions to avoid certain deadlocks 2013-04-26 12:18:07 -04:00
Nick Mathewson
5e6fa2a3ab event_base_update_cache_time should be a no-op if the loop isn't running 2013-04-24 13:23:15 -04:00
Nate Rosenblum
9443868d55 Double-check next timeout when adding events
When resuming the system from a suspended state, the ev_timeout field
of a scheduled timer event may be in the past. This leads to
unexpected behavior when scheduling a short-duration timer event
immediately after returning from suspension, because the new event
does not land on top of the timeout minheap and so the event loop
(blocked on a possibly long-duration timeout) is not notified.

This patch checks for this condition and, if it obtains, notifies the
event loop.
2013-03-05 11:29:33 -08:00