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
2 changes: 1 addition & 1 deletion .github/compilers.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
"latest_cxxstd": "20",
"cxx": "g++",
"cc": "gcc",
"runs_on": "windows-2022",
"runs_on": "windows-2025",
"b2_toolset": "gcc",
"generator": "MinGW Makefiles",
"shared": false,
Expand Down
17 changes: 10 additions & 7 deletions doc/modules/ROOT/pages/4.guide/4p.unix-sockets.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Code snippets assume:
#include <boost/corosio/local_stream_socket.hpp>
#include <boost/corosio/local_stream_acceptor.hpp>
#include <boost/corosio/local_datagram_socket.hpp>
#include <boost/corosio/local_socket_pair.hpp>
#include <boost/corosio/local_connect_pair.hpp>
#include <boost/corosio/local_endpoint.hpp>
#include <boost/capy/buffers.hpp>

Expand Down Expand Up @@ -123,11 +123,15 @@ capy::task<> client(corosio::io_context& ioc)
=== Socket Pairs

For bidirectional IPC between a parent and child (or two coroutines),
use `make_local_stream_pair()` which calls the `socketpair()` system call:
use `connect_pair()`. On POSIX it uses a single `socketpair()` syscall;
on Windows it performs a private bind/listen/accept/connect rendezvous
on a worker thread.

[source,cpp]
----
auto [s1, s2] = corosio::make_local_stream_pair(ioc);
corosio::local_stream_socket s1(ioc), s2(ioc);
if (auto ec = corosio::connect_pair(s1, s2))
throw std::system_error(ec, "connect_pair");

// Data written to s1 can be read from s2, and vice versa.
co_await s1.write_some(capy::const_buffer("ping", 4));
Expand All @@ -138,9 +142,6 @@ auto [ec, n] = co_await s2.read_some(
// buf contains "ping"
----

This is the fastest way to create a connected pair — it uses a single
`socketpair()` syscall with no filesystem paths involved.

== Datagram Sockets

Datagram sockets preserve message boundaries. Each `send` delivers exactly
Expand Down Expand Up @@ -173,7 +174,9 @@ After calling `connect()`, use `send`/`recv` without specifying the peer:

[source,cpp]
----
auto [s1, s2] = corosio::make_local_datagram_pair(ioc);
corosio::local_datagram_socket s1(ioc), s2(ioc);
if (auto ec = corosio::connect_pair(s1, s2))
throw std::system_error(ec, "connect_pair");

co_await s1.send(capy::const_buffer("msg", 3));

Expand Down
8 changes: 7 additions & 1 deletion include/boost/corosio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,19 @@
#include <boost/corosio/timer.hpp>
#include <boost/corosio/udp_socket.hpp>

#include <boost/corosio/local_connect_pair.hpp>
#include <boost/corosio/local_endpoint.hpp>
#include <boost/corosio/local_stream.hpp>
#include <boost/corosio/local_stream_socket.hpp>
#include <boost/corosio/local_stream_acceptor.hpp>

// local_datagram.hpp and local_datagram_socket.hpp are POSIX-only;
// Windows does not support AF_UNIX datagram sockets (SOCK_DGRAM).
#include <boost/corosio/detail/platform.hpp>
#if BOOST_COROSIO_POSIX
#include <boost/corosio/local_datagram.hpp>
#include <boost/corosio/local_datagram_socket.hpp>
#include <boost/corosio/local_socket_pair.hpp>
#endif

#include <boost/corosio/tls_context.hpp>
#include <boost/corosio/openssl_stream.hpp>
Expand Down
4 changes: 0 additions & 4 deletions include/boost/corosio/backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,6 @@ class win_local_stream_socket;
class win_local_stream_service;
class win_local_stream_acceptor;
class win_local_stream_acceptor_service;
class win_local_dgram_socket;
class win_local_dgram_service;

class win_signal;
class win_signals;
Expand Down Expand Up @@ -278,8 +276,6 @@ struct iocp_t
using local_stream_service_type = detail::win_local_stream_service;
using local_stream_acceptor_type = detail::win_local_stream_acceptor;
using local_stream_acceptor_service_type = detail::win_local_stream_acceptor_service;
using local_datagram_socket_type = detail::win_local_dgram_socket;
using local_datagram_service_type = detail::win_local_dgram_service;
/// @}

using signal_type = detail::win_signal;
Expand Down
6 changes: 6 additions & 0 deletions include/boost/corosio/detail/local_datagram_service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#define BOOST_COROSIO_DETAIL_LOCAL_DATAGRAM_SERVICE_HPP

#include <boost/corosio/detail/config.hpp>
#include <boost/corosio/detail/platform.hpp>

#if BOOST_COROSIO_POSIX

#include <boost/corosio/local_datagram_socket.hpp>
#include <boost/corosio/local_endpoint.hpp>
#include <boost/capy/ex/execution_context.hpp>
Expand Down Expand Up @@ -90,4 +94,6 @@ class BOOST_COROSIO_DECL local_datagram_service

} // namespace boost::corosio::detail

#endif // BOOST_COROSIO_POSIX

#endif // BOOST_COROSIO_DETAIL_LOCAL_DATAGRAM_SERVICE_HPP
80 changes: 80 additions & 0 deletions include/boost/corosio/local_connect_pair.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//
// Copyright (c) 2026 Steve Gerbino
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/cppalliance/corosio
//

#ifndef BOOST_COROSIO_LOCAL_CONNECT_PAIR_HPP
#define BOOST_COROSIO_LOCAL_CONNECT_PAIR_HPP

#include <boost/corosio/detail/config.hpp>
#include <boost/corosio/detail/platform.hpp>
#include <boost/corosio/local_stream_socket.hpp>

#if BOOST_COROSIO_POSIX
#include <boost/corosio/local_datagram_socket.hpp>
#endif

#include <system_error>

namespace boost::corosio {

/** Synchronously connect two AF_UNIX stream sockets as a connected pair.

On POSIX the implementation uses `socketpair(AF_UNIX, SOCK_STREAM)`
and adopts the descriptors via `assign()`. On Windows it performs a
private bind/listen/accept on the calling thread paired with a
`connect()` on a short-lived worker thread; the caller's
`io_context` is never driven, so it may be running on another
thread.

Either socket may be a `native_local_stream_socket<Backend>`; the
base reference selects the backend's `assign_socket` through normal
virtual dispatch.

@par Preconditions
Both sockets must be in the closed state.

@par Exception Safety
Nothrow. On failure both sockets remain closed and any underlying
resources are released.

@param a Receives the accepted/first endpoint of the pair.
@param b Receives the connected/second endpoint of the pair.

@return Empty on success; otherwise the underlying system error.
*/
BOOST_COROSIO_DECL
std::error_code
connect_pair(local_stream_socket& a, local_stream_socket& b) noexcept;

#if BOOST_COROSIO_POSIX

/** Synchronously connect two AF_UNIX datagram sockets as a connected pair.

POSIX only. Uses `socketpair(AF_UNIX, SOCK_DGRAM)` and adopts the
descriptors via `assign()`.

@par Preconditions
Both sockets must be in the closed state.

@par Exception Safety
Nothrow.

@param a First socket of the pair.
@param b Second socket of the pair.

@return Empty on success; otherwise the underlying system error.
*/
BOOST_COROSIO_DECL
std::error_code
connect_pair(local_datagram_socket& a, local_datagram_socket& b) noexcept;

#endif // BOOST_COROSIO_POSIX

} // namespace boost::corosio

#endif
8 changes: 8 additions & 0 deletions include/boost/corosio/local_datagram.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#define BOOST_COROSIO_LOCAL_DATAGRAM_HPP

#include <boost/corosio/detail/config.hpp>
#include <boost/corosio/detail/platform.hpp>

#if BOOST_COROSIO_POSIX

namespace boost::corosio {

Expand All @@ -25,6 +28,9 @@ class local_datagram_socket;
in the compiled library to avoid exposing platform socket
headers.

@note Not available on Windows. Windows does not support
AF_UNIX datagram sockets (SOCK_DGRAM).

@see local_datagram_socket
*/
class BOOST_COROSIO_DECL local_datagram
Expand All @@ -45,4 +51,6 @@ class BOOST_COROSIO_DECL local_datagram

} // namespace boost::corosio

#endif // BOOST_COROSIO_POSIX

#endif // BOOST_COROSIO_LOCAL_DATAGRAM_HPP
9 changes: 9 additions & 0 deletions include/boost/corosio/local_datagram_socket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

#include <boost/corosio/detail/config.hpp>
#include <boost/corosio/detail/platform.hpp>

#if BOOST_COROSIO_POSIX

#include <boost/corosio/detail/except.hpp>
#include <boost/corosio/detail/native_handle.hpp>
#include <boost/corosio/detail/op_base.hpp>
Expand Down Expand Up @@ -56,6 +59,10 @@ namespace boost::corosio {
kernel filters incoming datagrams to those from the
connected peer.

@note Not available on Windows. Windows does not support
AF_UNIX datagram sockets (SOCK_DGRAM). Attempting to
open this socket on Windows will fail.

@par Cancellation
All asynchronous operations support cancellation through
`std::stop_token` via the affine protocol, or explicitly
Expand Down Expand Up @@ -871,4 +878,6 @@ class BOOST_COROSIO_DECL local_datagram_socket : public io_object

} // namespace boost::corosio

#endif // BOOST_COROSIO_POSIX

#endif // BOOST_COROSIO_LOCAL_DATAGRAM_SOCKET_HPP
60 changes: 0 additions & 60 deletions include/boost/corosio/local_socket_pair.hpp

This file was deleted.

2 changes: 1 addition & 1 deletion include/boost/corosio/local_stream_socket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ class BOOST_COROSIO_DECL local_stream_socket : public io_stream

The socket must not already be open. The fd is adopted
and registered with the platform reactor. Used by
make_local_stream_pair() to wrap socketpair() fds.
connect_pair() to wrap socketpair() fds.

@param fd The file descriptor to adopt. Must be a valid,
open, non-blocking Unix stream socket.
Expand Down
Loading
Loading