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.
_______________________________________________ libev mailing list [email protected] http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
