SwiftChannel is a high-performance inter-process communication (IPC) library designed for low-latency, high-throughput message passing between processes.
The sender side is completely header-only. This means:
- ✅ Zero friction integration - just include headers
- ✅ No linking required for sender-only apps
- ✅ Inline optimizations for maximum performance
- ✅ Direct ring buffer writes with no syscalls
The receiver and infrastructure are compiled into a library:
- ✅ ABI stability
- ✅ Shared memory lifecycle management
- ✅ Platform abstraction (Windows/POSIX)
- ✅ Easy to ship prebuilt binaries
- Single Producer Single Consumer (SPSC) ring buffer
- Atomic operations for synchronization
- Cache-line aligned data structures to prevent false sharing
- Zero-copy message passing through shared memory
- CMake 3.20 or later
- C++20 compatible compiler (MSVC 2019+, GCC 10+, Clang 11+)
- Windows or POSIX-compatible OS (Linux, macOS, *BSD)
# Clone or extract the repository
cd SwiftChannel
# Create build directory
mkdir build
cd build
# Configure
cmake ..
# Build
cmake --build . --config Release
# Optional: Run tests
ctest -C Release
# Optional: Install
cmake --install . --prefix /your/install/pathmkdir build
cd build
cmake .. -G "Visual Studio 16 2019" -A x64
cmake --build . --config Releasemain.cpp:
#include <swiftchannel/swiftchannel.hpp>
struct MyMessage {
int id;
double value;
};
int main() {
// Create a sender
swiftchannel::Sender sender("my_channel");
// Send messages
MyMessage msg{42, 3.14};
auto result = sender.send(msg);
if (result.is_ok()) {
// Success!
}
return 0;
}CMakeLists.txt:
add_executable(my_sender main.cpp)
target_include_directories(my_sender PRIVATE
/path/to/swiftchannel/include)That's it! No linking required for sender-only apps.
main.cpp:
#include <swiftchannel/swiftchannel.hpp>
#include <swiftchannel/receiver/receiver.hpp>
struct MyMessage {
int id;
double value;
};
int main() {
swiftchannel::Receiver receiver("my_channel");
receiver.start([](const void* data, size_t size) {
auto* msg = static_cast<const MyMessage*>(data);
// Process message
});
return 0;
}CMakeLists.txt:
add_executable(my_receiver main.cpp)
target_link_libraries(my_receiver PRIVATE swiftchannel)swiftchannel::ChannelConfig config;
config.ring_buffer_size = 1024 * 1024; // 1MB (must be power of 2)
config.max_message_size = 64 * 1024; // 64KB
config.enable_checksum = false; // Optional checksum validation
config.overwrite_on_full = false; // Overwrite old messages when full
swiftchannel::Sender sender("channel", config);- Must be a power of 2
- Larger = fewer buffer-full events, but more memory
- Typical values: 64KB - 16MB
By default, SwiftChannel uses 64-byte cache lines. Override at compile time:
add_compile_definitions(SWIFTCHANNEL_CACHE_LINE_SIZE=128)For maximum performance:
- Use Release builds (
-O3or/O2) - Enable LTO (Link-Time Optimization)
- Consider
-march=nativefor CPU-specific optimizations
// Create sender
Sender(const std::string& channel_name,
const ChannelConfig& config = {});
// Send a message
template<Sendable T>
Result<void> send(const T& message);
// Check if ready
bool is_ready() const;
// Get available space
size_t available_space() const;// Create receiver
Receiver(const std::string& channel_name,
const ChannelConfig& config = {});
// Start receiving (blocking)
Result<void> start(MessageHandler handler);
// Start receiving (async)
Result<void> start_async(MessageHandler handler);
// Stop receiving
void stop();
// Poll for one message
Result<bool> poll_one(MessageHandler handler);
// Get statistics
Stats get_stats() const;SwiftChannel uses a Result<T> type for error handling:
auto result = sender.send(msg);
if (result.is_ok()) {
// Success
} else {
ErrorCode error = result.error();
std::string msg = error_to_string(error);
// Handle error
}Common error codes:
ErrorCode::ChannelFull- Ring buffer is fullErrorCode::MessageTooLarge- Message exceeds max sizeErrorCode::ChannelNotFound- Channel doesn't existErrorCode::VersionMismatch- Protocol version incompatible
- Uses Named File Mapping for shared memory
- Shared memory name:
Local\SwiftChannel_<channel_name> - Requires no special privileges
- Uses POSIX shared memory (
shm_open) - Shared memory name:
/swiftchannel_<channel_name> - May require
/dev/shmmounted
- Match configurations: Sender and receiver should use the same
ChannelConfig - Handle buffer full: Either increase buffer size or implement backpressure
- Message size: Keep messages reasonably small (< 64KB recommended)
- Trivially copyable: Only send POD types or trivially copyable structs
- Cleanup: Channels are automatically cleaned up, but consider manual cleanup in long-running apps
- Ensure sender creates the channel before receiver connects
- Check channel name matches exactly
- On POSIX, verify
/dev/shmis writable
- Verify both sides use the same
ChannelConfig - Check protocol version compatibility
- Ensure receiver is running before sender sends
- Increase ring buffer size
- Disable checksum validation
- Use Release builds
- Check CPU affinity and thread pinning
- See
examples/directory for complete examples - Read the API documentation in header files
- Check
tests/for usage patterns - Profile your application with the IPC inspector tool
For issues, questions, or contributions:
- Check the existing examples and tests
- Review the header documentation
- Open an issue with detailed reproduction steps
SwiftChannel is released under the MIT License. See LICENSE file for details.