<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Possible race in std::packaged_task"
   href="https://bugs.llvm.org/show_bug.cgi?id=43228">43228</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Possible race in std::packaged_task
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>labath@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Running the following piece of code under tsan:
=====
  auto task = std::make_shared<std::packaged_task<void()>>(
      [] { std::cout << "XXX" << std::endl; });
  std::thread([task] { (*task)(); }).detach();
  task->get_future().wait();
=====
Gives the following error message:
=====
  Read of size 4 at 0x7b200000c2f0 by thread T5:
    #0 std::__1::__assoc_sub_state::__has_value() const
include/c++/v1/future:551:18
    #1 std::__1::packaged_task<void ()>::operator()()
include/c++/v1/future:2207:24
    #2 main()::$_1::operator()() const
    #3 ...

  Previous write of size 4 at 0x7b200000c2f0 by main thread (mutexes: write
M2410):
    #0 std::__1::__assoc_sub_state::__attach_future()
include/c++/v1/future:560:18
    #1 std::__1::future<void>::future(std::__tsan::__assoc_sub_state*)
llvm/projects/libcxx/src/future.cpp:181:15
    #2 std::__1::promise<void>::get_future()
llvm/projects/libcxx/src/future.cpp:223:12
    #3 std::__1::packaged_task<void ()>::get_future()
include/c++/v1/future:2192:51
    #4 main()
    #5 ...
=====

Looking at the code, once of the threads is doing "return __state_ &
__constructed", and the other one does a "__state_ |= __future_attached".

Now, I am not completely sure that what this snippet of code (obtained by
reduction from some code in LLDB) is doing is absolutely correct. I have looked
at the standard, and I could not find evidence either way (though it's possible
I am just not looking at the right place). However, there are some hints which
lead me to believe that this might not be intentional:
a) this code is "almost" race free. The only reason we are getting an error is
because the two threads are accessing different bits in the same integer. If
these were two integers everything would be ok.
b) cppreference.com
<<a href="https://en.cppreference.com/w/cpp/thread/promise/get_future">https://en.cppreference.com/w/cpp/thread/promise/get_future</a>> explicitly says
that promise::get_future does not race with promise::set_value. That said, I am
not sure what is the basis of this claim of their, and also cppreference is
suspiciously quiet about the packaged_task class.

I'd appreciate it if someone with more experience experience reading the c++
standard could take a look at this and confirm whether this is a libc++ bug, or
an lldb bug.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>