From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id C96A43987919 for ; Wed, 11 Nov 2020 11:16:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C96A43987919 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-416-Tqvf8A2jM8-b9dXzmxuIUA-1; Wed, 11 Nov 2020 06:16:01 -0500 X-MC-Unique: Tqvf8A2jM8-b9dXzmxuIUA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 76E3E802B71; Wed, 11 Nov 2020 11:16:00 +0000 (UTC) Received: from localhost (unknown [10.33.36.62]) by smtp.corp.redhat.com (Postfix) with ESMTP id 27CDC7366A; Wed, 11 Nov 2020 11:16:00 +0000 (UTC) Date: Wed, 11 Nov 2020 11:15:59 +0000 From: Jonathan Wakely To: Paul Scharnofske Cc: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: Re: std::jthread::operator=(std::jthread&&) calls std::terminate if *this has an associated running thread. Message-ID: <20201111111559.GU503596@redhat.com> References: <20201106220252.GM503596@redhat.com> <7388faf6-f5e9-1328-cbe5-e8634e092561@gmail.com> <5fa7f7cf.1c69fb81.d14a.c5c9@mx.google.com> MIME-Version: 1.0 In-Reply-To: <5fa7f7cf.1c69fb81.d14a.c5c9@mx.google.com> X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline X-Spam-Status: No, score=-14.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=unavailable autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Nov 2020 11:16:08 -0000 On 08/11/20 14:51 +0100, Paul Scharnofske via Libstdc++ wrote: >>I think this would work: >> >> jthread& operator=(jthread&& __x) noexcept >> { >> std::jthread(std::move(__x)).swap(*this); >> return *this; >> } > >That looks a lot better than what I did, it's also consistent with other >places like std::stop_token::operator=(std::stop_token&&). > >I updated my patch and also created a test that checks the post >conditions described in the standard. Thanks, I've committed the patch and will also backport it to the gcc-10 branch. This patch is small enough to not require a copyright assignment, but if you would like to make further contritbutions please contact me off-list to discuss the legal prerequisites as described at https://gcc.gnu.org/contribute.html Thanks again for contributing to GCC! >--- > libstdc++-v3/include/std/thread | 6 +++++- > .../testsuite/30_threads/jthread/jthread.cc | 20 +++++++++++++++++++ > 2 files changed, 25 insertions(+), 1 deletion(-) > >diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread >index 887ee579962..080036e2609 100644 >--- a/libstdc++-v3/include/std/thread >+++ b/libstdc++-v3/include/std/thread >@@ -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 >diff --git a/libstdc++-v3/testsuite/30_threads/jthread/jthread.cc b/libstdc++-v3/testsuite/30_threads/jthread/jthread.cc >index 746ff437c1d..b8ba62f6df2 100644 >--- a/libstdc++-v3/testsuite/30_threads/jthread/jthread.cc >+++ b/libstdc++-v3/testsuite/30_threads/jthread/jthread.cc >@@ -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(); > } >-- >2.29.2 >