include/boost/corosio/native/detail/iocp/win_dissociate.hpp

83.3% Lines (10/12) 100.0% List of functions (2/2) 62.5% Branches (5/8)
win_dissociate.hpp
f(x) Functions (2)
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Steve Gerbino
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_DISSOCIATE_HPP
11 #define BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_DISSOCIATE_HPP
12
13 #include <boost/corosio/detail/platform.hpp>
14
15 #if BOOST_COROSIO_HAS_IOCP
16
17 #include <boost/corosio/native/detail/iocp/win_windows.hpp>
18
19 namespace boost::corosio::detail {
20
21 /** Detach a socket from its I/O completion port.
22
23 The documented API keeps a handle bound to its completion port for
24 the handle's lifetime; `NtSetInformationFile` with the
25 `FileReplaceCompletionInformation` class is the only way to sever
26 the association. Without this, a released socket can never be
27 adopted into an io_context again: re-association fails with
28 `ERROR_INVALID_PARAMETER`.
29
30 @param s The socket to detach.
31
32 @return `true` if the association was removed.
33 */
34 inline bool
35 13x dissociate_from_iocp(SOCKET s) noexcept
36 {
37 using nt_set_information_file_fn =
38 LONG(NTAPI*)(HANDLE, ULONG_PTR*, void*, ULONG, ULONG);
39
40 static nt_set_information_file_fn const fn =
41 4x []() noexcept -> nt_set_information_file_fn {
42
1/2
✓ Branch 3 → 4 taken 4 times.
✗ Branch 3 → 6 not taken.
4x if (HMODULE h = ::GetModuleHandleW(L"ntdll.dll"))
43 {
44 // The two-step cast through void(*)() is the sanctioned
45 // FARPROC conversion; a direct cast trips
46 // -Wcast-function-type.
47 return reinterpret_cast<nt_set_information_file_fn>(
48 reinterpret_cast<void (*)()>(
49 4x ::GetProcAddress(h, "NtSetInformationFile")));
50 }
51 return nullptr;
52
3/4
✓ Branch 2 → 3 taken 4 times.
✓ Branch 2 → 8 taken 9 times.
✓ Branch 4 → 5 taken 4 times.
✗ Branch 4 → 8 not taken.
13x }();
53
1/2
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 13 times.
13x if (!fn)
54 return false;
55
56 // FILE_COMPLETION_INFORMATION{ nullptr, nullptr } under info
57 // class FileReplaceCompletionInformation (61).
58 13x ULONG_PTR iosb[2] = {0, 0};
59 13x void* info[2] = {nullptr, nullptr};
60 13x return fn(reinterpret_cast<HANDLE>(s), iosb, &info, sizeof(info), 61) ==
61 13x 0;
62 }
63
64 } // namespace boost::corosio::detail
65
66 #endif // BOOST_COROSIO_HAS_IOCP
67
68 #endif // BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_DISSOCIATE_HPP
69