@@ -71,36 +71,40 @@ static sockaddr_un setSocketAddr(StringRef SocketPath) {
71
71
72
72
static Expected<int > getSocketFD (StringRef SocketPath) {
73
73
#ifdef _WIN32
74
- SOCKET MaybeSocket = socket (AF_UNIX, SOCK_STREAM, 0 );
75
- if (MaybeSocket == INVALID_SOCKET) {
74
+ SOCKET Socket = socket (AF_UNIX, SOCK_STREAM, 0 );
75
+ if (Socket == INVALID_SOCKET) {
76
76
#else
77
- int MaybeSocket = socket (AF_UNIX, SOCK_STREAM, 0 );
78
- if (MaybeSocket == -1 ) {
77
+ int Socket = socket (AF_UNIX, SOCK_STREAM, 0 );
78
+ if (Socket == -1 ) {
79
79
#endif // _WIN32
80
80
return llvm::make_error<StringError>(getLastSocketErrorCode (),
81
81
" Create socket failed" );
82
82
}
83
83
84
84
struct sockaddr_un Addr = setSocketAddr (SocketPath);
85
- if (::connect (MaybeSocket , (struct sockaddr *)&Addr, sizeof (Addr)) == -1 )
85
+ if (::connect (Socket , (struct sockaddr *)&Addr, sizeof (Addr)) == -1 )
86
86
return llvm::make_error<StringError>(getLastSocketErrorCode (),
87
87
" Connect socket failed" );
88
88
89
89
#ifdef _WIN32
90
- return _open_osfhandle (MaybeWinsocket , 0 );
90
+ return _open_osfhandle (Socket , 0 );
91
91
#else
92
- return MaybeSocket ;
92
+ return Socket ;
93
93
#endif // _WIN32
94
94
}
95
95
96
- ListeningSocket::ListeningSocket (int SocketFD, StringRef SocketPath)
97
- : FD (SocketFD), SocketPath (SocketPath) {}
96
+ ListeningSocket::ListeningSocket (int SocketFD, StringRef SocketPath,
97
+ int PipeFD[2 ])
98
+ : FD (SocketFD), SocketPath (SocketPath), PipeFD{PipeFD[0 ], PipeFD[1 ]} {}
98
99
99
100
ListeningSocket::ListeningSocket (ListeningSocket &&LS)
100
- : FD (LS.FD .load ()), SocketPath (LS.SocketPath ) {
101
+ : FD (LS.FD .load ()),
102
+ SocketPath (LS.SocketPath ), PipeFD{LS.PipeFD [0 ], LS.PipeFD [1 ]} {
101
103
102
- LS.SocketPath .clear ();
103
104
LS.FD = -1 ;
105
+ LS.SocketPath .clear ();
106
+ LS.PipeFD [0 ] = -1 ;
107
+ LS.PipeFD [1 ] = -1 ;
104
108
}
105
109
106
110
Expected<ListeningSocket>
@@ -135,36 +139,38 @@ ListeningSocket::createListeningUnixSocket(StringRef SocketPath,
135
139
136
140
#ifdef _WIN32
137
141
WSABalancer _;
138
- SOCKET MaybeSocket = socket (AF_UNIX, SOCK_STREAM, 0 );
139
- if (MaybeSocket == INVALID_SOCKET) {
142
+ SOCKET Socket = socket (AF_UNIX, SOCK_STREAM, 0 );
143
+ if (Socket == INVALID_SOCKET) {
140
144
#else
141
- int MaybeSocket = socket (AF_UNIX, SOCK_STREAM, 0 );
142
- if (MaybeSocket == -1 ) {
145
+ int Socket = socket (AF_UNIX, SOCK_STREAM, 0 );
146
+ if (Socket == -1 )
143
147
#endif
144
148
return llvm::make_error<StringError>(getLastSocketErrorCode (),
145
149
" socket create failed" );
146
- }
147
150
148
151
struct sockaddr_un Addr = setSocketAddr (SocketPath);
149
- if (::bind (MaybeSocket , (struct sockaddr *)&Addr, sizeof (Addr)) == -1 ) {
152
+ if (::bind (Socket , (struct sockaddr *)&Addr, sizeof (Addr)) == -1 ) {
150
153
// Grab error code from call to ::bind before calling ::close
151
154
std::error_code EC = getLastSocketErrorCode ();
152
- ::close (MaybeSocket );
155
+ ::close (Socket );
153
156
return llvm::make_error<StringError>(EC, " Bind error" );
154
157
}
155
158
156
159
// Mark socket as passive so incoming connections can be accepted
157
- if (::listen (MaybeSocket , MaxBacklog) == -1 )
160
+ if (::listen (Socket , MaxBacklog) == -1 )
158
161
return llvm::make_error<StringError>(getLastSocketErrorCode (),
159
162
" Listen error" );
160
163
161
- int Socket;
164
+ int PipeFD[2 ];
165
+ if (::pipe (PipeFD) == -1 )
166
+ return llvm::make_error<StringError>(getLastSocketErrorCode (),
167
+ " pipe failed" );
168
+
162
169
#ifdef _WIN32
163
- Socket = _open_osfhandle (MaybeWinsocket , 0 );
170
+ return ListeningSocket{ _open_osfhandle (Socket , 0 ), SocketPath, PipeFD} ;
164
171
#else
165
- Socket = MaybeSocket ;
172
+ return ListeningSocket{ Socket, SocketPath, PipeFD} ;
166
173
#endif // _WIN32
167
- return ListeningSocket{Socket, SocketPath};
168
174
}
169
175
170
176
Expected<std::unique_ptr<raw_socket_stream>>
@@ -180,12 +186,7 @@ ListeningSocket::accept(std::optional<std::chrono::milliseconds> Timeout) {
180
186
#endif
181
187
182
188
FDs[1 ].events = POLLIN;
183
- PipeMutex.lock ();
184
- if (::pipe (PipeFD) == -1 )
185
- return llvm::make_error<StringError>(getLastSocketErrorCode (),
186
- " pipe failed" );
187
189
FDs[1 ].fd = PipeFD[0 ];
188
- PipeMutex.unlock ();
189
190
190
191
int TimeoutCount = Timeout.value_or (std::chrono::milliseconds (-1 )).count ();
191
192
int PollStatus = ::poll (FDs, 2 , TimeoutCount);
@@ -223,14 +224,22 @@ void ListeningSocket::shutdown() {
223
224
::close (FD);
224
225
::unlink (SocketPath.c_str());
225
226
227
+ // Ensure ::poll returns if shutdown is called by a seperate thread
226
228
char Byte = ' A' ;
227
- PipeMutex.lock ();
228
- write (PipeFD[1 ], &Byte, 1 );
229
- PipeMutex.unlock ();
229
+ ::write (PipeFD[1 ], &Byte, 1 );
230
+
230
231
FD = -1 ;
231
232
}
232
233
233
- ListeningSocket::~ListeningSocket () { shutdown (); }
234
+ ListeningSocket::~ListeningSocket () {
235
+ shutdown ();
236
+
237
+ // Close the pipe's FDs in the destructor instead of within
238
+ // ListeningSocket::shutdown to avoid unnecessary synchronization issues that
239
+ // would occur as PipeFD's values would have to be changed to -1
240
+ ::close (PipeFD[0 ]);
241
+ ::close (PipeFD[1 ]);
242
+ }
234
243
235
244
// ===----------------------------------------------------------------------===//
236
245
// raw_socket_stream
0 commit comments