race conditions with promises

Hello there!

I am running the 'promise' example showed in this link of cplusplus.com using a file called promises.cpp.

http://www.cplusplus.com/reference/future/promise/

When I run the example under the Valgrind tool 'helgrind' it shows these race conditions errors:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
==16376== Possible data race during read of size 8 at 0x5CD9C98 by thread #2
==16376== Locks held: none
==16376==    at 0x403842: std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::get() const (unique_ptr.h:305)
==16376==    by 0x402BEB: std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::operator*() const (unique_ptr.h:291)
==16376==    by 0x4025EC: std::__future_base::_State_baseV2::wait() (future:323)
==16376==    by 0x403BC5: std::__basic_future<int>::_M_get_result() const (future:681)
==16376==    by 0x40324A: std::future<int>::get() (future:760)
==16376==    by 0x401CD4: print_int(std::future<int>&) (promises.cpp:8)
==16376==    by 0x406D86: void std::_Bind_simple<void (*(std::reference_wrapper<std::future<int> >))(std::future<int>&)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) (functional:1531)
==16376==    by 0x406C57: std::_Bind_simple<void (*(std::reference_wrapper<std::future<int> >))(std::future<int>&)>::operator()() (functional:1520)
==16376==    by 0x406AFF: std::thread::_Impl<std::_Bind_simple<void (*(std::reference_wrapper<std::future<int> >))(std::future<int>&)> >::_M_run() (thread:115)
==16376==    by 0x4EF8C7F: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==16376==    by 0x4C34DB6: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==16376==    by 0x53DF6B9: start_thread (pthread_create.c:333)
==16376==
==16376== This conflicts with a previous write of size 8 by thread #1
==16376== Locks held: none
==16376==    at 0x4055FE: void std::swap<std::__future_base::_Result_base*>(std::__future_base::_Result_base*&, std::__future_base::_Result_base*&) (move.h:186)
==16376==    by 0x4050FA: std::_Tuple_impl<0ul, std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>::_M_swap(std::_Tuple_impl<0ul, std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>&) (tuple:332)
==16376==    by 0x404936: std::tuple<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>::swap(std::tuple<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>&) (tuple:742)
==16376==    by 0x403950: void std::swap<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>(std::tuple<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>&, std::tuple<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>&) (tuple:1134)
==16376==    by 0x402F92: std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::swap(std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>&) (unique_ptr.h:352)
==16376==    by 0x40292F: std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) (future:532)
==16376==    by 0x4055A1: void std::_Mem_fn_base<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), true>::operator()<std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*, void>(std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) const (in /home/romerohe/proyects/cpp/tests/promises)
==16376==    by 0x4050B8: void std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> (std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)>::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) (functional:1531)
==16376==  Address 0x5cd9c98 is 24 bytes inside a block of size 48 alloc'd
==16376==    at 0x4C2F50F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==16376==    by 0x4060E2: __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*) (new_allocator.h:104)
==16376==    by 0x405DFA: std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2> > >::allocate(std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2> >&, unsigned long) (alloc_traits.h:491)
==16376==    by 0x405AF1: std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2> > > std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2> > >(std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2> >&) (allocated_ptr.h:102)
==16376==    by 0x4056D4: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>>(std::_Sp_make_shared_tag, std::__future_base::_State_baseV2*, std::allocator<std::__future_base::_State_baseV2> const&) (shared_ptr_base.h:615)
==16376==    by 0x40515D: std::__shared_ptr<std::__future_base::_State_baseV2, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<std::__future_base::_State_baseV2>>(std::_Sp_make_shared_tag, std::allocator<std::__future_base::_State_baseV2> const&) (shared_ptr_base.h:1097)
==16376==    by 0x40499D: std::shared_ptr<std::__future_base::_State_baseV2>::shared_ptr<std::allocator<std::__future_base::_State_baseV2>>(std::_Sp_make_shared_tag, std::allocator<std::__future_base::_State_baseV2> const&) (shared_ptr.h:319)
==16376==    by 0x403A5B: std::shared_ptr<std::__future_base::_State_baseV2> std::allocate_shared<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>>(std::allocator<std::__future_base::_State_baseV2> const&) (shared_ptr.h:620)
==16376==    by 0x4030F8: std::shared_ptr<std::__future_base::_State_baseV2> std::make_shared<std::__future_base::_State_baseV2>() (shared_ptr.h:636)
==16376==    by 0x4032C9: std::promise<int>::promise() (future:1018)
==16376==    by 0x401D2A: main (promises.cpp:14)
==16376==  Block was alloc'd by thread #1 


Do you know why? The website states that promises are thread safe.

My version of gcc is "version 5.4.0"
Thanks a lot!!
Last edited on
It only says "possible data race", it is not a perfect race condition detector.

This seems to point out the problem:
https://stackoverflow.com/questions/41926894/can-helgrind-valgrind-be-used-with-c11-futures
Thanks poteto!!
race conditions with promises:_
JavaScript Demo: Promise.race

var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, 'one');
});

var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then(function(value) {
console.log(value);
// Both resolve, but promise2 is faster
});
// expected output: "two"

The race function returns a Promise that is settled the same way (and takes the same value) as the first promise that settles amongst the promises of the iterable passed as argument. For more coding knowledge click here:- http://www.cetpainfotech.com/technology/unix-training
Topic archived. No new replies allowed.