Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/asyncpp/io/detail/io_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ namespace asyncpp::io::detail {
virtual void socket_multicast_set_send_interface(socket_handle_t socket, address iface) = 0;
virtual void socket_multicast_set_ttl(socket_handle_t socket, size_t ttl) = 0;
virtual void socket_multicast_set_loopback(socket_handle_t socket, bool enabled) = 0;
virtual void socket_allow_reuse_address(socket_handle_t socket, bool enabled) = 0;
virtual void socket_shutdown(socket_handle_t socket, bool receive, bool send) = 0;
virtual bool enqueue_connect(socket_handle_t socket, endpoint ep, completion_data* cd) = 0;
virtual bool enqueue_accept(socket_handle_t socket, completion_data* cd) = 0;
Expand Down
2 changes: 2 additions & 0 deletions include/asyncpp/io/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ namespace asyncpp::io {
void multicast_set_ttl(size_t ttl);
void multicast_set_loopback(bool enabled);

void allow_reuse_address(bool enabled);

[[nodiscard]] detail::io_engine::socket_handle_t native_handle() const noexcept { return m_fd; }
[[nodiscard]] detail::io_engine::socket_handle_t release() noexcept {
if (m_io != nullptr && m_fd != detail::io_engine::invalid_socket_handle)
Expand Down
6 changes: 6 additions & 0 deletions src/io_engine_generic_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,12 @@ namespace asyncpp::io::detail {
}
}

void io_engine_generic_unix::socket_allow_reuse_address(socket_handle_t socket, bool enabled) {
int val = enabled ? 1 : 0;
auto res = setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&val), sizeof(val));
if (res < 0) throw std::system_error(errno, std::system_category(), "setsockopt failed");
}

void io_engine_generic_unix::socket_shutdown(socket_handle_t socket, bool receive, bool send) {
int mode = 0;
if (receive && send)
Expand Down
1 change: 1 addition & 0 deletions src/io_engine_generic_unix.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace asyncpp::io::detail {
void socket_multicast_set_send_interface(socket_handle_t socket, address iface) override;
void socket_multicast_set_ttl(socket_handle_t socket, size_t ttl) override;
void socket_multicast_set_loopback(socket_handle_t socket, bool enabled) override;
void socket_allow_reuse_address(socket_handle_t socket, bool enabled) override;
void socket_shutdown(socket_handle_t socket, bool receive, bool send) override;

file_handle_t file_open(const char* filename, std::ios_base::openmode mode) override;
Expand Down
7 changes: 7 additions & 0 deletions src/io_engine_iocp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ namespace asyncpp::io::detail {
void socket_multicast_set_send_interface(socket_handle_t socket, address iface) override;
void socket_multicast_set_ttl(socket_handle_t socket, size_t ttl) override;
void socket_multicast_set_loopback(socket_handle_t socket, bool enabled) override;
void socket_allow_reuse_address(socket_handle_t socket, bool enabled) override;
void socket_shutdown(socket_handle_t socket, bool receive, bool send) override;
bool enqueue_connect(socket_handle_t socket, endpoint ep, completion_data* cd) override;
bool enqueue_accept(socket_handle_t socket, completion_data* cd) override;
Expand Down Expand Up @@ -452,6 +453,12 @@ namespace asyncpp::io::detail {
}
}

void io_engine_iocp::socket_allow_reuse_address(socket_handle_t socket, bool enabled) {
int val = enabled ? 1 : 0;
auto res = setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char*>(&val), sizeof(val));
if (res < 0) throw std::system_error(WSAGetLastError(), std::system_category(), "setsockopt failed");
}

void io_engine_iocp::socket_shutdown(socket_handle_t socket, bool receive, bool send) {
int mode = 0;
if (receive && send)
Expand Down
5 changes: 5 additions & 0 deletions src/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ namespace asyncpp::io {
m_io->engine()->socket_multicast_set_loopback(m_fd, enabled);
}

void socket::allow_reuse_address(bool enabled) {
if (m_fd == detail::io_engine::invalid_socket_handle) throw std::logic_error("invalid socket");
m_io->engine()->socket_allow_reuse_address(m_fd, enabled);
}

void socket::close_send() {
if (m_fd == detail::io_engine::invalid_socket_handle) throw std::logic_error("invalid socket");
m_io->engine()->socket_shutdown(m_fd, false, true);
Expand Down
Loading