|
|
|||
File indexing completed on 2026-05-10 08:44:33
0001 //===-- llvm/Support/raw_socket_stream.h - Socket streams --*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This file contains raw_ostream implementations for streams to communicate 0010 // via UNIX sockets 0011 // 0012 //===----------------------------------------------------------------------===// 0013 0014 #ifndef LLVM_SUPPORT_RAW_SOCKET_STREAM_H 0015 #define LLVM_SUPPORT_RAW_SOCKET_STREAM_H 0016 0017 #include "llvm/Support/Threading.h" 0018 #include "llvm/Support/raw_ostream.h" 0019 0020 #include <atomic> 0021 #include <chrono> 0022 0023 namespace llvm { 0024 0025 class raw_socket_stream; 0026 0027 #ifdef _WIN32 0028 /// Ensures proper initialization and cleanup of winsock resources 0029 /// 0030 /// Make sure that calls to WSAStartup and WSACleanup are balanced. 0031 class WSABalancer { 0032 public: 0033 WSABalancer(); 0034 ~WSABalancer(); 0035 }; 0036 #endif // _WIN32 0037 0038 /// Manages a passive (i.e., listening) UNIX domain socket 0039 /// 0040 /// The ListeningSocket class encapsulates a UNIX domain socket that can listen 0041 /// and accept incoming connections. ListeningSocket is portable and supports 0042 /// Windows builds begining with Insider Build 17063. ListeningSocket is 0043 /// designed for server-side operations, working alongside \p raw_socket_streams 0044 /// that function as client connections. 0045 /// 0046 /// Usage example: 0047 /// \code{.cpp} 0048 /// std::string Path = "/path/to/socket" 0049 /// Expected<ListeningSocket> S = ListeningSocket::createUnix(Path); 0050 /// 0051 /// if (S) { 0052 /// Expected<std::unique_ptr<raw_socket_stream>> connection = S->accept(); 0053 /// if (connection) { 0054 /// // Use the accepted raw_socket_stream for communication. 0055 /// } 0056 /// } 0057 /// \endcode 0058 /// 0059 class ListeningSocket { 0060 0061 std::atomic<int> FD; 0062 std::string SocketPath; // Not modified after construction 0063 0064 /// If a separate thread calls ListeningSocket::shutdown, the ListeningSocket 0065 /// file descriptor (FD) could be closed while ::poll is waiting for it to be 0066 /// ready to perform a I/O operations. ::poll will continue to block even 0067 /// after FD is closed so use a self-pipe mechanism to get ::poll to return 0068 int PipeFD[2]; // Not modified after construction other then move constructor 0069 0070 ListeningSocket(int SocketFD, StringRef SocketPath, int PipeFD[2]); 0071 0072 #ifdef _WIN32 0073 WSABalancer _; 0074 #endif // _WIN32 0075 0076 public: 0077 ~ListeningSocket(); 0078 ListeningSocket(ListeningSocket &&LS); 0079 ListeningSocket(const ListeningSocket &LS) = delete; 0080 ListeningSocket &operator=(const ListeningSocket &) = delete; 0081 0082 /// Closes the FD, unlinks the socket file, and writes to PipeFD. 0083 /// 0084 /// After the construction of the ListeningSocket, shutdown is signal safe if 0085 /// it is called during the lifetime of the object. shutdown can be called 0086 /// concurrently with ListeningSocket::accept as writing to PipeFD will cause 0087 /// a blocking call to ::poll to return. 0088 /// 0089 /// Once shutdown is called there is no way to reinitialize ListeningSocket. 0090 void shutdown(); 0091 0092 /// Accepts an incoming connection on the listening socket. This method can 0093 /// optionally either block until a connection is available or timeout after a 0094 /// specified amount of time has passed. By default the method will block 0095 /// until the socket has recieved a connection. If the accept timesout this 0096 /// method will return std::errc:timed_out 0097 /// 0098 /// \param Timeout An optional timeout duration in milliseconds. Setting 0099 /// Timeout to a negative number causes ::accept to block indefinitely 0100 /// 0101 Expected<std::unique_ptr<raw_socket_stream>> accept( 0102 const std::chrono::milliseconds &Timeout = std::chrono::milliseconds(-1)); 0103 0104 /// Creates a listening socket bound to the specified file system path. 0105 /// Handles the socket creation, binding, and immediately starts listening for 0106 /// incoming connections. 0107 /// 0108 /// \param SocketPath The file system path where the socket will be created 0109 /// \param MaxBacklog The max number of connections in a socket's backlog 0110 /// 0111 static Expected<ListeningSocket> createUnix( 0112 StringRef SocketPath, 0113 int MaxBacklog = llvm::hardware_concurrency().compute_thread_count()); 0114 }; 0115 0116 //===----------------------------------------------------------------------===// 0117 // raw_socket_stream 0118 //===----------------------------------------------------------------------===// 0119 0120 class raw_socket_stream : public raw_fd_stream { 0121 uint64_t current_pos() const override { return 0; } 0122 #ifdef _WIN32 0123 WSABalancer _; 0124 #endif // _WIN32 0125 0126 public: 0127 raw_socket_stream(int SocketFD); 0128 ~raw_socket_stream(); 0129 0130 /// Create a \p raw_socket_stream connected to the UNIX domain socket at \p 0131 /// SocketPath. 0132 static Expected<std::unique_ptr<raw_socket_stream>> 0133 createConnectedUnix(StringRef SocketPath); 0134 0135 /// Attempt to read from the raw_socket_stream's file descriptor. 0136 /// 0137 /// This method can optionally either block until data is read or an error has 0138 /// occurred or timeout after a specified amount of time has passed. By 0139 /// default the method will block until the socket has read data or 0140 /// encountered an error. If the read times out this method will return 0141 /// std::errc:timed_out 0142 /// 0143 /// \param Ptr The start of the buffer that will hold any read data 0144 /// \param Size The number of bytes to be read 0145 /// \param Timeout An optional timeout duration in milliseconds 0146 /// 0147 ssize_t read( 0148 char *Ptr, size_t Size, 0149 const std::chrono::milliseconds &Timeout = std::chrono::milliseconds(-1)); 0150 }; 0151 0152 } // end namespace llvm 0153 0154 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|