interprocess/
local_socket.rs

1//! Local sockets, an IPC primitive featuring a server and multiple clients connecting to that
2//! server using a filesystem path or an identifier inside a special namespace, each having a
3//! private connection to that server.
4//!
5//! ## Implementation types
6//! Local sockets are not a real IPC method implemented by the OS – they exist to paper over the
7//! differences between the two underlying implementations currently in use: Unix domain sockets and
8//! Windows named pipes.
9//!
10//! Interprocess defines [traits] that implementations of local sockets implement, and enums that
11//! constitute devirtualized trait objects (not unlike those provided by the `enum_dispatch` crate)
12//! for those traits. The implementation used, in cases where multiple options apply, is chosen at
13//! construction via the [name](Name) and [name type](NameType) infrastructure.
14//!
15//! ## Differences from regular sockets
16//! A few missing features, primarily on Windows, require local sockets to omit some important
17//! functionality, because code relying on it wouldn't be portable. Some notable differences are:
18//! - No `.shutdown()` – your communication protocol must manually negotiate end of transmission.
19//!   Notably, `.read_to_string()` and `.read_all()` will always block indefinitely at some point.
20//! - No datagram sockets – the difference in semantics between connectionless datagram Unix-domain
21//!   sockets and connection-based named message pipes on Windows does not allow bridging those two
22//!   into a common API. You can emulate datagrams on top of streams anyway, so no big deal, right?
23
24#[macro_use]
25mod enumdef;
26
27mod name;
28mod stream {
29    pub(super) mod r#enum;
30    pub(super) mod r#trait;
31}
32mod listener {
33    pub(super) mod r#enum;
34    pub(super) mod options;
35    pub(super) mod r#trait;
36}
37
38/// Traits representing the interface of local sockets.
39pub mod traits {
40    pub use super::{
41        listener::r#trait::{Listener, ListenerExt, ListenerNonblockingMode},
42        stream::r#trait::*,
43    };
44    /// Traits for the Tokio variants of local socket objects.
45    #[cfg(feature = "tokio")]
46    #[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "tokio")))]
47    pub mod tokio {
48        pub use super::super::tokio::{listener::r#trait::*, stream::r#trait::*};
49    }
50}
51
52pub use {
53    listener::{options::ListenerOptions, r#enum::*, r#trait::Incoming},
54    name::*,
55    stream::r#enum::*,
56    traits::ListenerNonblockingMode,
57};
58
59/// Re-exports of [traits] done in a way that doesn't pollute the scope, as well as of the
60/// enum-dispatch types with their names prefixed with `LocalSocket`.
61pub mod prelude {
62    pub use super::{
63        name::{NameType as _, ToFsName as _, ToNsName as _},
64        traits::{Listener as _, ListenerExt as _, Stream as _},
65        Listener as LocalSocketListener, Stream as LocalSocketStream,
66    };
67}
68
69/// Asynchronous local sockets which work with the Tokio runtime and event loop.
70///
71/// The Tokio integration allows the local socket streams and listeners to be notified by the OS
72/// kernel whenever they're ready to be received from of sent to, instead of spawning threads just
73/// to put them in a wait state of blocking on the I/O.
74///
75/// Types from this module will *not* work with other async runtimes, such as `async-std` or `smol`,
76/// since the Tokio types' methods will panic whenever they're called outside of a Tokio runtime
77/// context. Open an issue if you'd like to see other runtimes supported as well.
78#[cfg(feature = "tokio")]
79#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "tokio")))]
80pub mod tokio {
81    pub(super) mod listener {
82        pub(in super::super) mod r#enum;
83        pub(in super::super) mod r#trait;
84    }
85    pub(super) mod stream {
86        pub(in super::super) mod r#enum;
87        pub(in super::super) mod r#trait;
88    }
89    pub use {listener::r#enum::*, stream::r#enum::*};
90
91    /// Like the [sync local socket prelude](super::prelude), but for Tokio local sockets.
92    pub mod prelude {
93        pub use super::{
94            super::{
95                name::{NameType as _, ToFsName as _, ToNsName as _},
96                traits::tokio::{Listener as _, Stream as _},
97            },
98            Listener as LocalSocketListener, Stream as LocalSocketStream,
99        };
100    }
101}
102
103mod concurrency_detector;
104pub(crate) use concurrency_detector::*;