diff options
author | Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com> | 2022-04-17 02:05:46 +0300 |
---|---|---|
committer | Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com> | 2022-04-17 02:05:46 +0300 |
commit | ceeaddba4c571291d42690a54424e8bf8cf4d5dd (patch) | |
tree | 33f60cb4bf96ad04f608fe8d718750771181b1bb | |
parent | 621d1a7907e51ff06a52462a85d4bc8702bc1acb (diff) |
Hopefully fix all remaining CI failures in networking.
-rw-r--r-- | .github/workflows/installability.yml | 4 | ||||
-rw-r--r-- | include/llfio/revision.hpp | 6 | ||||
-rw-r--r-- | include/llfio/v2.0/detail/impl/tls_socket_sources/openssl.ipp | 4 | ||||
-rw-r--r-- | include/llfio/v2.0/detail/impl/windows/byte_io_handle.ipp | 32 | ||||
-rw-r--r-- | include/llfio/v2.0/handle.hpp | 3 | ||||
-rw-r--r-- | include/llfio/v2.0/native_handle_type.hpp | 8 | ||||
-rw-r--r-- | test/tests/tls_socket_handle.cpp | 18 |
7 files changed, 57 insertions, 18 deletions
diff --git a/.github/workflows/installability.yml b/.github/workflows/installability.yml index 8fbe2289..22bfc8b1 100644 --- a/.github/workflows/installability.yml +++ b/.github/workflows/installability.yml @@ -34,7 +34,9 @@ jobs: run: | git config --global core.longpaths true if [ "${{ matrix.configuration }}" = "status_code" ]; then - export CMAKE_CONFIGURE_OPTIONS="-DLLFIO_USE_EXPERIMENTAL_SG14_STATUS_CODE=ON;-DLLFIO_FORCE_OPENSSL_OFF=ON" + export CMAKE_CONFIGURE_OPTIONS="-DLLFIO_FORCE_OPENSSL_OFF=ON -DLLFIO_USE_EXPERIMENTAL_SG14_STATUS_CODE=ON" + else + export CMAKE_CONFIGURE_OPTIONS="-DLLFIO_FORCE_OPENSSL_OFF=ON" fi git clone --depth 1 https://github.com/ned14/quickcpplib.git pip install --user gitpython diff --git a/include/llfio/revision.hpp b/include/llfio/revision.hpp index 9e150cc6..03a5dc43 100644 --- a/include/llfio/revision.hpp +++ b/include/llfio/revision.hpp @@ -1,4 +1,4 @@ // Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time -#define LLFIO_PREVIOUS_COMMIT_REF ac897294b2e9a0383a754527efbbbcc30a582b21 -#define LLFIO_PREVIOUS_COMMIT_DATE "2022-04-16 19:00:45 +00:00" -#define LLFIO_PREVIOUS_COMMIT_UNIQUE ac897294 +#define LLFIO_PREVIOUS_COMMIT_REF 621d1a7907e51ff06a52462a85d4bc8702bc1acb +#define LLFIO_PREVIOUS_COMMIT_DATE "2022-04-16 21:39:20 +00:00" +#define LLFIO_PREVIOUS_COMMIT_UNIQUE 621d1a79 diff --git a/include/llfio/v2.0/detail/impl/tls_socket_sources/openssl.ipp b/include/llfio/v2.0/detail/impl/tls_socket_sources/openssl.ipp index a1c22b46..8b9793a9 100644 --- a/include/llfio/v2.0/detail/impl/tls_socket_sources/openssl.ipp +++ b/include/llfio/v2.0/detail/impl/tls_socket_sources/openssl.ipp @@ -1468,11 +1468,13 @@ protected: } listening_byte_socket_handle::buffer_type b; OUTCOME_TRY(auto &&read, _underlying_read<listening_byte_socket_handle>({b}, d)); + assert(this->is_nonblocking() == b.first.is_nonblocking()); auto *p = new(std::nothrow) openssl_socket_handle(std::move(read.connected_socket().first)); if(p == nullptr) { return errc::not_enough_memory; } + assert(this->is_nonblocking() == p->is_nonblocking()); req.buffers.connected_socket() = {tls_socket_handle_ptr(p), read.connected_socket().second}; OUTCOME_TRY(p->set_registered_buffer_chunk_size(_registered_buffer_chunk_size)); OUTCOME_TRY(p->_init(false, _authentication_certificates_path)); @@ -1488,11 +1490,13 @@ protected: } listening_byte_socket_handle::buffer_type b; OUTCOME_TRY(auto &&read, _underlying_read<listening_byte_socket_handle>({b}, d)); + assert(this->is_nonblocking() == b.first.is_nonblocking()); auto *p = new(std::nothrow) openssl_socket_handle(std::move(read.connected_socket().first)); if(p == nullptr) { return errc::not_enough_memory; } + assert(this->is_nonblocking() == p->is_nonblocking()); req.buffers.connected_socket() = {tls_socket_handle_ptr(p), read.connected_socket().second}; OUTCOME_TRY(p->set_registered_buffer_chunk_size(_registered_buffer_chunk_size)); OUTCOME_TRY(p->_init(false, _authentication_certificates_path)); diff --git a/include/llfio/v2.0/detail/impl/windows/byte_io_handle.ipp b/include/llfio/v2.0/detail/impl/windows/byte_io_handle.ipp index d4307c6e..3314e7e6 100644 --- a/include/llfio/v2.0/detail/impl/windows/byte_io_handle.ipp +++ b/include/llfio/v2.0/detail/impl/windows/byte_io_handle.ipp @@ -213,25 +213,37 @@ retry: WSAOVERLAPPED ol; memset(&ol, 0, sizeof(ol)); ol.Internal = (ULONG_PTR) -1; - if(SOCKET_ERROR == syscall(nativeh.sock, bufs.data(), (DWORD) reqs.buffers.size(), &transferred, flags, d ? &ol : nullptr, nullptr)) + const bool op_errored = (SOCKET_ERROR == syscall(nativeh.sock, bufs.data(), (DWORD) reqs.buffers.size(), &transferred, flags, d ? &ol : nullptr, nullptr)); + // It would seem that sometimes Winsock returns zero bytes transferred and no error for nonblocking overlapped sockets + // In fairness, the Windows documentation does warn in the strongest possible terms to not combine nonblocking semantics + // with overlapped i/o, however it is so very much easier for this implementation if we do. + if(op_errored || (transferred == 0 && nativeh.is_nonblocking() && blocking)) { - auto retcode = WSAGetLastError(); - if(WSA_IO_PENDING != retcode && WSAEWOULDBLOCK != retcode) + bool io_pending = false; + if(op_errored) { - if(WSAESHUTDOWN == retcode) + auto retcode = WSAGetLastError(); + if(WSA_IO_PENDING == retcode) { - // Emulate POSIX here - transferred = 0; - goto exit_now; + io_pending = true; + } + if(!io_pending && WSAEWOULDBLOCK != retcode) + { + if(WSAESHUTDOWN == retcode) + { + // Emulate POSIX here + transferred = 0; + goto exit_now; + } + ret = win32_error(retcode); + return true; } - ret = win32_error(retcode); - return true; } if(nativeh.is_nonblocking() && blocking) { deadline nd; LLFIO_DEADLINE_TO_PARTIAL_DEADLINE(nd, d); - if(WSA_IO_PENDING == retcode) + if(io_pending) { if(STATUS_TIMEOUT == ntwait(nativeh.h, ol, nd)) { diff --git a/include/llfio/v2.0/handle.hpp b/include/llfio/v2.0/handle.hpp index 88bb2ce9..a6234e28 100644 --- a/include/llfio/v2.0/handle.hpp +++ b/include/llfio/v2.0/handle.hpp @@ -226,9 +226,8 @@ public: } // NOLINT //! Construct a handle from a supplied native handle explicit constexpr handle(native_handle_type h, flag flags = flag::none) noexcept - : _v(std::move(h)) + : _v(std::move(h), /* special move constructor to work around a constexpr bug in clang*/ uint16_t(flags)) { - _.flags = flags; } LLFIO_HEADERS_ONLY_VIRTUAL_SPEC ~handle(); //! No copy construction (use clone()) diff --git a/include/llfio/v2.0/native_handle_type.hpp b/include/llfio/v2.0/native_handle_type.hpp index 10f60801..f14d3875 100644 --- a/include/llfio/v2.0/native_handle_type.hpp +++ b/include/llfio/v2.0/native_handle_type.hpp @@ -130,6 +130,14 @@ struct native_handle_type // NOLINT o.behaviour = disposition(); o._init = -1; } + //! Special move constructor to work around a constexpr bug in clang + constexpr native_handle_type(native_handle_type &&o, uint16_t flags) noexcept // NOLINT + : _init(o._init) + , behaviour(uint64_t(o.behaviour) | (uint64_t(flags) << 32)) + { + o.behaviour = disposition(); + o._init = -1; + } //! Copy assign native_handle_type &operator=(const native_handle_type &) = default; //! Move assign diff --git a/test/tests/tls_socket_handle.cpp b/test/tests/tls_socket_handle.cpp index cade8a91..12980e2a 100644 --- a/test/tests/tls_socket_handle.cpp +++ b/test/tests/tls_socket_handle.cpp @@ -186,20 +186,34 @@ static inline void TestNonBlockingTLSSocketHandles() BOOST_REQUIRE(!r); BOOST_REQUIRE(r.error() == llfio::errc::timed_out); // can't possibly connect immediately } + BOOST_REQUIRE(serversocket->is_nonblocking()); serversocket->read({reader}, std::chrono::seconds(1)).value(); + // clang seems to be losing the nonblocking bit??? + BOOST_REQUIRE(reader.first->is_nonblocking()); std::cout << "Server socket sees incoming connection from " << reader.second << std::endl; // The TLS negotiation needs to do various reading and writing until the connection goes up bool connected = false; - for(size_t count=0;count<1024;count++) + for(size_t count = 0; count < 16; count++) { auto r1 = writer->connect(endpoint, std::chrono::milliseconds(0)); auto r2 = reader.first->read({{nullptr, 0}}, std::chrono::milliseconds(0)); - (void) r2; if(r1) { connected = true; break; } + BOOST_REQUIRE(r2 || r2.error() != llfio::errc::not_supported); + if(count == 8) + { + if(r2) + { + std::cout << "\nread() returns success " << r2.value() << std::endl; + } + else + { + std::cout << "\nread() returns failure " << r2.error().message() << std::endl; + } + } std::cout << "*" << std::flush; std::this_thread::sleep_for(std::chrono::milliseconds(1)); } |