From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1534) id 8CD763898529; Wed, 10 Jun 2020 10:31:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8CD763898529 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1591785104; bh=HboKOvyCx52+DJjnLCO5dPwnmwyE9F3G32mKYKSaBt4=; h=From:To:Subject:Date:From; b=TFuMtCsnxSMEWcJegqbX0m/gE7fm0aCfLuPvfYIsV0Wau1M5B4xy5QeKpbO/9rNpW H0GmfcH529z51fHTEm21InstX3DGg5wj9Vifpa14JCe/7054oLS74qpjh2dESkLD4S +4nKZ1s/70opx9buxEy4t1hk3q2Q/HdhbXE6fSSA= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Tobias Burnus To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc/devel/omp/gcc-10] libstdc++: Fix net::basic_socket::close(error_code&) X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/devel/omp/gcc-10 X-Git-Oldrev: 566ba72126288272607374a32ac646dcd36fe584 X-Git-Newrev: e3eec8a14601177a9facda5629a80c2d7204a3a3 Message-Id: <20200610103144.8CD763898529@sourceware.org> Date: Wed, 10 Jun 2020 10:31:44 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Jun 2020 10:31:44 -0000 https://gcc.gnu.org/g:e3eec8a14601177a9facda5629a80c2d7204a3a3 commit e3eec8a14601177a9facda5629a80c2d7204a3a3 Author: Jonathan Wakely Date: Thu May 21 08:08:27 2020 +0100 libstdc++: Fix net::basic_socket::close(error_code&) Also add some missing member functions, nodiscard attributes, and noexcept-specifiers. Backport from mainline 2020-05-21 Jonathan Wakely * include/experimental/executor (use_future_t::use_future_t()): Fix incorrect noexcept-specifier. * include/experimental/internet (basic_resolver_results): Adjust whitespace. * include/experimental/socket (__basic_socket_impl::release): Add member function. (basic_socket(io_context&, const endpoint_type&)): Fix argument to target constructor. (basic_socket::release(), basic_socket::release(error_code&)): Add missing member functions. (basic_socket::is_open()): Add nodiscard attribute. (basic_socket::close(error_code&)): Pass argument to base function. (basic_socket_acceptor::release()) (basic_socket_acceptor::release(error_code&)): Add missing member functions. (basic_socket_acceptor::is_open()): Add nodiscard attribute. (basic_socket_streambuf::error()): Add noexcept. (basic_socket_iostream::error()): Likewise. * testsuite/experimental/net/socket/basic_socket.cc: New test. Diff: --- libstdc++-v3/ChangeLog | 25 ++++ libstdc++-v3/include/experimental/executor | 5 +- libstdc++-v3/include/experimental/internet | 4 +- libstdc++-v3/include/experimental/socket | 45 +++++-- .../experimental/net/socket/basic_socket.cc | 129 +++++++++++++++++++++ 5 files changed, 194 insertions(+), 14 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b53ddacb574..f06ebaaa109 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,28 @@ +2020-05-21 Jonathan Wakely + + Backport from mainline + 2020-05-21 Jonathan Wakely + + * include/experimental/executor (use_future_t::use_future_t()): Fix + incorrect noexcept-specifier. + * include/experimental/internet (basic_resolver_results): Adjust + whitespace. + * include/experimental/socket (__basic_socket_impl::release): Add + member function. + (basic_socket(io_context&, const endpoint_type&)): Fix argument to + target constructor. + (basic_socket::release(), basic_socket::release(error_code&)): Add + missing member functions. + (basic_socket::is_open()): Add nodiscard attribute. + (basic_socket::close(error_code&)): Pass argument to base function. + (basic_socket_acceptor::release()) + (basic_socket_acceptor::release(error_code&)): Add missing member + functions. + (basic_socket_acceptor::is_open()): Add nodiscard attribute. + (basic_socket_streambuf::error()): Add noexcept. + (basic_socket_iostream::error()): Likewise. + * testsuite/experimental/net/socket/basic_socket.cc: New test. + 2020-05-21 Jonathan Wakely Backport from mainline diff --git a/libstdc++-v3/include/experimental/executor b/libstdc++-v3/include/experimental/executor index 3560e345e8a..1d5b5b3afb0 100644 --- a/libstdc++-v3/include/experimental/executor +++ b/libstdc++-v3/include/experimental/executor @@ -1601,7 +1601,10 @@ inline namespace v1 using allocator_type = _ProtoAllocator; // use_future_t members: - constexpr use_future_t() noexcept : _M_alloc() { } + constexpr + use_future_t() + noexcept(is_nothrow_default_constructible<_ProtoAllocator>::value) + : _M_alloc() { } explicit use_future_t(const _ProtoAllocator& __a) noexcept : _M_alloc(__a) { } diff --git a/libstdc++-v3/include/experimental/internet b/libstdc++-v3/include/experimental/internet index 1aa81095009..2e5abf322ac 100644 --- a/libstdc++-v3/include/experimental/internet +++ b/libstdc++-v3/include/experimental/internet @@ -1726,7 +1726,9 @@ namespace ip // size: size_type size() const noexcept { return _M_size; } size_type max_size() const noexcept { return _M_results.max_size(); } - _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_results.empty(); } + + _GLIBCXX_NODISCARD bool + empty() const noexcept { return _M_results.empty(); } // element access: const_iterator begin() const { return _M_results.begin(); } diff --git a/libstdc++-v3/include/experimental/socket b/libstdc++-v3/include/experimental/socket index 81b1d15b654..4c47348373b 100644 --- a/libstdc++-v3/include/experimental/socket +++ b/libstdc++-v3/include/experimental/socket @@ -153,8 +153,8 @@ inline namespace v1 // TODO SettableSocket reqs // TODO BooleanSocketOption reqs // TODO IntegerSocketOption reqs - // TODO _IoControlCommand reqs - // TODO _ConnectCondition reqs + // TODO IoControlCommand reqs + // TODO ConnectCondition reqs /** @brief Sockets * @{ @@ -598,6 +598,13 @@ inline namespace v1 } } + native_handle_type release(error_code& __ec) + { + __glibcxx_assert(is_open()); + cancel(__ec); + return std::exchange(_M_sockfd, -1); + } + template void set_option(const _SettableSocketOption& __option, error_code& __ec) @@ -649,7 +656,7 @@ inline namespace v1 #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socklen_t __endpoint_len = __endpoint.capacity(); if (::getsockname(_M_sockfd, (sockaddr*)__endpoint.data(), - &__endpoint_len) == -1) + &__endpoint_len) == -1) { __ec.assign(errno, generic_category()); return endpoint_type{}; @@ -735,11 +742,18 @@ inline namespace v1 error_code& __ec) { __base::assign(__protocol, __native_socket, __ec); } - bool is_open() const noexcept { return __base::is_open(); } + native_handle_type release() + { return release(__throw_on_error{"basic_socket::release"}); } + + native_handle_type release(error_code& __ec) + { return __base::release(__ec); } + + _GLIBCXX_NODISCARD bool + is_open() const noexcept { return __base::is_open(); } void close() { close(__throw_on_error{"basic_socket::close"}); } - void close(error_code& __ec) { __base::close(); } + void close(error_code& __ec) { __base::close(__ec); } void cancel() { cancel(__throw_on_error{"basic_socket::cancel"}); } @@ -898,7 +912,7 @@ inline namespace v1 #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H socklen_t __endpoint_len = __endpoint.capacity(); if (::getpeername(this->_M_sockfd, (sockaddr*)__endpoint.data(), - &__endpoint_len) + &__endpoint_len) == -1) { __ec.assign(errno, generic_category()); @@ -921,13 +935,13 @@ inline namespace v1 void connect(const endpoint_type& __endpoint, error_code& __ec) { +#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H if (!is_open()) { open(__endpoint.protocol(), __ec); if (__ec) return; } -#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H if (::connect(native_handle(), (const sockaddr*)__endpoint.data(), __endpoint.size()) == -1) __ec.assign(errno, generic_category()); @@ -956,7 +970,7 @@ inline namespace v1 auto __a = get_associated_allocator( __init.completion_handler, std::allocator()); __ex.post( - [__h=std::move(__init.completion_handler), __ec] + [__h = std::move(__init.completion_handler), __ec] () mutable { __h(__ec); }, __a); return __init.result.get(); @@ -1029,7 +1043,7 @@ inline namespace v1 { open(__protocol); } basic_socket(io_context& __ctx, const endpoint_type& __endpoint) - : basic_socket(std::addressof(__ctx), __endpoint.protocol()) + : basic_socket(__ctx, __endpoint.protocol()) { bind(__endpoint); } basic_socket(io_context& __ctx, const protocol_type& __protocol, @@ -1918,7 +1932,13 @@ inline namespace v1 error_code& __ec) { __base::assign(__protocol, __native_acceptor, __ec); } - bool + native_handle_type release() + { return release(__throw_on_error{"basic_socket_acceptor::release"}); } + + native_handle_type release(error_code& __ec) + { return __base::release(__ec); } + + _GLIBCXX_NODISCARD bool is_open() const noexcept { return __base::is_open(); } void @@ -2313,7 +2333,8 @@ inline namespace v1 basic_socket_streambuf* close(); // TODO basic_socket& socket() { return _M_socket; } - error_code error() const { return _M_ec; } + + error_code error() const noexcept { return _M_ec; } time_point expiry() const { return _M_expiry; } @@ -2425,7 +2446,7 @@ inline namespace v1 { return const_cast<__streambuf_type*>(std::addressof(_M_sb)); } basic_socket& socket() { return rdbuf()->socket(); } - error_code error() const { return rdbuf()->error(); } + error_code error() const noexcept { return rdbuf()->error(); } time_point expiry() const { return rdbuf()->expiry(); } void expires_at(const time_point& __t) { rdbuf()->expires_at(__t); } diff --git a/libstdc++-v3/testsuite/experimental/net/socket/basic_socket.cc b/libstdc++-v3/testsuite/experimental/net/socket/basic_socket.cc new file mode 100644 index 00000000000..14dbff6659d --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/net/socket/basic_socket.cc @@ -0,0 +1,129 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile { target c++14 } } + +#include + +namespace net = std::experimental::net; +using namespace std; + +namespace test +{ +} + +void +test01(net::io_context& io) +{ + struct proto + { + struct endpoint + { + using protocol_type = proto; + protocol_type protocol() const { return {}; } + + void* data() { return nullptr; } + const void* data() const { return nullptr; } + std::size_t size() const { return 0; } + void resize(std::size_t) { } + std::size_t capacity() const { return 0; } + }; + + int family() const { return 0; } + int type() const { return 0; } + int protocol() const { return 0; } + }; + + static_assert( ! is_default_constructible>::value, + "no default ctor" ); + static_assert( ! is_copy_constructible>::value, + "copy ctor is deleted" ); + static_assert( ! is_move_constructible>::value, + "move ctor is protected" ); + static_assert( ! is_move_assignable>::value, + "move assignment op is protected" ); + + struct socket : net::basic_socket + { + explicit + socket(net::io_context& io) + : basic_socket(io) { } + + socket(net::io_context& io, const proto& p) + : basic_socket(io, p) { } + + socket(net::io_context& io, const proto::endpoint& e) + : basic_socket(io, e) { } + + socket(net::io_context& io, const proto& p, int n) + : basic_socket(io, p, n) { } + }; + + static_assert( ! is_copy_constructible::value, "deleted" ); + static_assert( is_move_constructible::value, "" ); + static_assert( is_move_assignable::value, "" ); + + error_code ec; + proto p; + proto::endpoint e; + + socket s(io); + s = socket(io, p); + s = socket(io, e); + s = socket(io, p, s.release()); + + static_assert( is_same::value, "" ); + static_assert( noexcept(s.get_executor()), "" ); + static_assert( is_same::value, "" ); + static_assert( noexcept(s.native_handle()), "GNU extension" ); + + s.open(); + s.open(p); + s.open(p, ec); + + s.assign(p, s.release()); + s.assign(p, s.release(ec), ec); + + static_assert( is_same(s).is_open()), + bool>::value, "" ); + static_assert( noexcept(const_cast(s).is_open()), "" ); + + s.close(); + s.close(ec); + + s.cancel(); + s.cancel(ec); + + s.bind(e); + s.bind(e, ec); + + s.shutdown(net::socket_base::shutdown_both); + s.shutdown(net::socket_base::shutdown_both, ec); + + e = s.local_endpoint(); + e = s.local_endpoint(ec); + e = s.remote_endpoint(); + e = s.remote_endpoint(ec); + + s.connect(e); + s.connect(e, ec); + + s.wait(net::socket_base::wait_read); + s.wait(net::socket_base::wait_read, ec); +}