io
C++ I/O scheduling library with asynchronous socket operations
Loading...
Searching...
No Matches
socket_handle.cpp
1/* Copyright 2025 Kevin Exton
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include "socket_handle.hpp"
16#include "../error.hpp"
17
18#include <system_error>
19
20// generic helper functions
21static auto throw_system_error(const char *message) -> void {
22 throw std::system_error(errno, std::generic_category(), message);
23}
24
25namespace io::socket {
26
27static auto is_valid_socket(native_socket_type handle) -> bool {
28 if (handle == INVALID_SOCKET)
29 return false;
30
31 int type = 0;
32 socklen_type len = sizeof(type);
33
34 return ::getsockopt(handle, SOL_SOCKET, SO_TYPE, &type, &len) == 0;
35}
36
37} // namespace io::socket
38
39// socket_handle implementation
40namespace io::socket {
41
43 swap(*this, other);
44}
45
47 -> socket_handle & {
48 swap(*this, other);
49 return *this;
50}
51
53 if (!is_valid_socket(handle))
54 throw_system_error(IO_ERROR_MESSAGE("Invalid socket handle."));
55}
56
57socket_handle::socket_handle(int domain, int type, int protocol)
58 : socket_{::socket(domain, type, protocol)} {
59 if (socket_ == INVALID_SOCKET)
60 throw_system_error(IO_ERROR_MESSAGE("Failed to create socket."));
61}
62
63socket_handle::operator native_socket_type() const noexcept {
64 return socket_.load(std::memory_order_relaxed);
65}
66
67auto swap(socket_handle &lhs, socket_handle &rhs) noexcept -> void {
68 if (&lhs == &rhs)
69 return;
70
71 std::scoped_lock lock(lhs.mtx_, rhs.mtx_);
72
73 using std::swap;
74 auto temp = lhs.socket_.exchange(rhs.socket_);
75 rhs.socket_.store(temp);
76}
77
78socket_handle::operator bool() const noexcept {
79 return socket_ != INVALID_SOCKET;
80}
81
82auto socket_handle::operator<=>(const socket_handle &other) const noexcept
83 -> std::strong_ordering {
84 return socket_ <=> other.socket_;
85}
86
87auto socket_handle::operator==(const socket_handle &other) const noexcept
88 -> bool {
89 return (*this <=> other) == 0;
90}
91
93 -> std::strong_ordering {
94 return socket_ <=> other;
95}
96
98 -> bool {
99 return (*this <=> other) == 0;
100}
101
103
104auto socket_handle::close() noexcept -> void {
105 std::lock_guard lock{mtx_};
106 if (socket_ != INVALID_SOCKET) {
107 ::io::socket::close(socket_);
108 socket_ = INVALID_SOCKET;
109 }
110}
111
112} // namespace io::socket
A thread-safe, move-only RAII wrapper for a native socket handle.
auto operator=(const socket_handle &other) -> socket_handle &=delete
Deleted copy assignment operator.
socket_handle()=default
Default constructor. Initializes an invalid socket handle.
auto operator==(const socket_handle &other) const noexcept -> bool
Checks for equality between two socket_handle objects.
auto operator<=>(const socket_handle &other) const noexcept -> std::strong_ordering
Three-way compares two socket_handle objects.
#define IO_ERROR_MESSAGE(msg)
Constructs a formatted error message with the file and line number.
Definition error.hpp:62
The io::socket namespace provides a cross-platform abstraction for socket-level I/O operations.
Definition socket.hpp:31
auto close(native_socket_type socket) noexcept -> int
Closes a socket descriptor on POSIX systems.
Definition socket.hpp:74
int native_socket_type
The native socket handle type for POSIX systems.
Definition socket.hpp:38
auto swap(socket_handle &lhs, socket_handle &rhs) noexcept -> void
socklen_t socklen_type
The type used to represent socket-related sizes on POSIX systems.
Definition socket.hpp:155
This file defines the socket_handle class, a cross-platform, thread-safe RAII wrapper for native sock...