libev, multiple threads, and ev_async as notification vs valgrind/helgrind

Christian Parpart trapni at gmail.com
Fri May 2 16:12:29 CEST 2014


Hey all,

I am trying to find a race in my threaded app, so I decided to give
valgrind+helgrind a try.

My app is spawning N worker threads. each has its own event loop and nicely
runs in parallel.
Sometimes one worker needs to wakeup another worker in order to make sure
it knows
about something, so I use ev_async_send() for this.

However, even though the man page states (unless I am misreading it) that
ev_async is
for this very purpose and is thread safe without any further doing, I get
tons of
messages by Valgrind's tool "helgrind" about possible data races.

The race basically occures inside ev_async_send() in thread A, a read
operation that is said to
be in conflict to a prior read in the same data region happened inside
ev_invoke_pending()+... in thread B.


The Valgrind output about the data race looks like this:

==5023== Possible data race during write of size 4 at 0x76DBB68 by thread
#1


==5023== Locks held: 1, at address 0x76B9968
==5023==    at 0x6BBAD70: ev_async_send (in
/usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==5023==    by 0x50E6E28: ev::async::send() (ev++.h:798)
==5023==    by 0x5110D8F: x0::HttpWorker::enqueue(std::pair<x0::Socket*,
x0::ServerSocket*>&&) (HttpWorker.cpp:197)
==5023==    by 0x510AAD8: x0::HttpServer::onNewConnection(x0::Socket*,
x0::ServerSocket*) (HttpServer.cpp:145)
==5023==    by 0x510D520: void
x0::ServerSocket::callback_thunk<x0::HttpServer,
&x0::HttpServer::onNewConnection>(x0::Socket*, x0::ServerSocket*)
(ServerSocket.h:130)
==5023==    by 0x4E802EC: x0::ServerSocket::acceptOne()
(ServerSocket.cpp:705)
==5023==    by 0x4E7F9E9: x0::ServerSocket::accept(ev::io&, int)
(ServerSocket.cpp:665)
==5023==    by 0x4E803C2: void ev::base<ev_io,
ev::io>::method_thunk<x0::ServerSocket,
&x0::ServerSocket::accept>(ev_loop*, ev_io*, int) (ev++.h:479)
==5023==    by 0x6BB5E44: ev_invoke_pending (in
/usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==5023==    by 0x510FE34: x0::HttpWorker::invoke_pending(ev_loop*)
(HttpWorker.cpp:51)
==5023==    by 0x6BB8FE6: ev_run (in
/usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==5023==    by 0x5110A3A: ev_loop(ev_loop*, int) (ev.h:826)
==5023==    by 0x51109B2: x0::HttpWorker::run() (HttpWorker.cpp:157)
==5023==    by 0x510ABE3: x0::HttpServer::run() (HttpServer.cpp:225)
==5023==    by 0x4734BD: x0d::XzeroDaemon::run() (XzeroDaemon.cpp:289)
==5023==    by 0x492915: main (x0d.cpp:16)
==5023==
==5023== This conflicts with a previous read of size 4 by thread #2
==5023== Locks held: 1, at address 0x76DAC28
==5023==    at 0x6BB6BF5: ??? (in /usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==5023==    by 0x6BB5E44: ev_invoke_pending (in
/usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==5023==    by 0x510FE34: x0::HttpWorker::invoke_pending(ev_loop*)
(HttpWorker.cpp:51)
==5023==    by 0x6BB8FE6: ev_run (in
/usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==5023==    by 0x5110A3A: ev_loop(ev_loop*, int) (ev.h:826)
==5023==    by 0x51109B2: x0::HttpWorker::run() (HttpWorker.cpp:157)
==5023==    by 0x5110474: x0::HttpWorker::_run(void*) (HttpWorker.cpp:141)
==5023==    by 0x4C30E26: ??? (in
/usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)

I hope somebody can tell me that this is a false positive or what I might
be missing.

>From what I can think of, I should not need any locks at for my threading
model, there watchers are only modified inside their respective worker
threads *except* the fact, that ev_async is used to notify thread A to
thread B to wake up and do some work.

As you may see in the backtrace, I also tried to add a lock around struct
ev_loop uses, as shown in the example of the libev man page, in the hope,
that maybe I need that part there anyways, but appearently that didn't fix
it either.

Any ideas?

Many thanks in advance,
Christian Parpart.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.schmorp.de/pipermail/libev/attachments/20140502/8d54b6b4/attachment.html>


More information about the libev mailing list