libstdc++: Assigning to a joinable std::jthread calls std::terminate
Move assigning to a std::jthread that represents a thread of execution needs to send a stop request and join that running thread. Otherwise the std::thread data member will terminate in its assignment operator. Co-authored-by: Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ChangeLog: * include/std/thread (jthread::operator=(jthread&&)): Transfer any existing state to a temporary that will request a stop and then join. * testsuite/30_threads/jthread/jthread.cc: Test move assignment.
This commit is contained in:
parent
43f9e5aff0
commit
0ebaea3b66
@ -456,7 +456,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
operator=(const jthread&) = delete;
|
||||
|
||||
jthread&
|
||||
operator=(jthread&&) noexcept = default;
|
||||
operator=(jthread&& __other) noexcept
|
||||
{
|
||||
std::jthread(std::move(__other)).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
swap(jthread& __other) noexcept
|
||||
|
@ -187,6 +187,25 @@ void test_detach()
|
||||
VERIFY(t1FinallyInterrupted.load());
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
void test_move_assignment()
|
||||
{
|
||||
std::jthread thread1([]{});
|
||||
std::jthread thread2([]{});
|
||||
|
||||
const auto id2 = thread2.get_id();
|
||||
const auto ssource2 = thread2.get_stop_source();
|
||||
|
||||
thread1 = std::move(thread2);
|
||||
|
||||
VERIFY(thread1.get_id() == id2);
|
||||
VERIFY(thread2.get_id() == std::jthread::id());
|
||||
|
||||
VERIFY(thread1.get_stop_source() == ssource2);
|
||||
VERIFY(!thread2.get_stop_source().stop_possible());
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::set_terminate([](){
|
||||
@ -197,4 +216,5 @@ int main()
|
||||
test_stop_token();
|
||||
test_join();
|
||||
test_detach();
|
||||
test_move_assignment();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user