Skip to content

Commit a7f9b96

Browse files
committed
WIP
1 parent 7832769 commit a7f9b96

File tree

5 files changed

+130
-59
lines changed

5 files changed

+130
-59
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===-- FileDescriptor.h ----------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file contains a utility functions for working with file descriptors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_SUPPORT_FILEDESCRIPTOR_H
14+
#define LLVM_SUPPORT_FILEDESCRIPTOR_H
15+
16+
#include "llvm/Support/Error.h"
17+
#include <chrono>
18+
19+
namespace llvm {
20+
// Helper function to get the value from either std::atomic<int> or int
21+
template <typename T> int getFD(T &FD) {
22+
if constexpr (std::is_same_v<T, std::atomic<int>>) {
23+
return FD.load();
24+
} else {
25+
return FD;
26+
}
27+
}
28+
29+
template <typename T>
30+
llvm::Error manageTimeout(std::chrono::milliseconds Timeout, T &FD, int PipeFD);
31+
} // namespace llvm
32+
#endif

llvm/lib/Support/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,9 @@ add_llvm_component_library(LLVMSupport
176176
ExponentialBackoff.cpp
177177
ExtensibleRTTI.cpp
178178
FileCollector.cpp
179-
FileUtilities.cpp
179+
FileDescriptor.cpp
180180
FileOutputBuffer.cpp
181+
FileUtilities.cpp
181182
FloatingPointMode.cpp
182183
FoldingSet.cpp
183184
FormattedStream.cpp

llvm/lib/Support/FileDescriptor.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//===-- FileDescriptor.cpp --------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file contains a utility functions for working with file descriptors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "llvm/Support/Error.h"
14+
#include "llvm/Support/FileDescriptor.h"
15+
#include <atomic>
16+
#include <chrono>
17+
#include <poll.h>
18+
19+
static std::error_code getLastSocketErrorCode() {
20+
#ifdef _WIN32
21+
return std::error_code(::WSAGetLastError(), std::system_category());
22+
#else
23+
return llvm::errnoAsErrorCode();
24+
#endif
25+
}
26+
27+
template <typename T>
28+
llvm::Error llvm::manageTimeout(std::chrono::milliseconds Timeout, T &FD, int PipeFD) {
29+
static_assert(std::is_same_v<T, int> || std::is_same_v<T, std::atomic<int>>,
30+
"FD must be of type int& or std::atomic<int>&");
31+
32+
struct pollfd FDs[2];
33+
FDs[0].events = POLLIN;
34+
#ifdef _WIN32
35+
SOCKET WinServerSock = _get_osfhandle(FD);
36+
FDs[0].fd = WinServerSock;
37+
#else
38+
FDs[0].fd = llvm::getFD(FD);
39+
#endif
40+
FDs[1].events = POLLIN;
41+
FDs[1].fd = PipeFD;
42+
43+
// Keep track of how much time has passed in case poll is interupted by a
44+
// signal and needs to be recalled
45+
int RemainingTime = Timeout.count();
46+
std::chrono::milliseconds ElapsedTime = std::chrono::milliseconds(0);
47+
int PollStatus = -1;
48+
49+
while (PollStatus == -1 && (Timeout.count() == -1 || ElapsedTime < Timeout)) {
50+
if (Timeout.count() != -1)
51+
RemainingTime -= ElapsedTime.count();
52+
53+
auto Start = std::chrono::steady_clock::now();
54+
#ifdef _WIN32
55+
PollStatus = WSAPoll(FDs, 2, RemainingTime);
56+
#else
57+
PollStatus = ::poll(FDs, 2, RemainingTime);
58+
#endif
59+
// If FD equals -1 then ListeningSocket::shutdown has been called and it is
60+
// appropriate to return operation_canceled
61+
if (FD == -1)
62+
return llvm::make_error<llvm::StringError>(
63+
std::make_error_code(std::errc::operation_canceled),
64+
"Accept canceled");
65+
66+
#if _WIN32
67+
if (PollStatus == SOCKET_ERROR) {
68+
#else
69+
if (PollStatus == -1) {
70+
#endif
71+
std::error_code PollErrCode = getLastSocketErrorCode();
72+
// Ignore EINTR (signal occured before any request event) and retry
73+
if (PollErrCode != std::errc::interrupted)
74+
return llvm::make_error<llvm::StringError>(PollErrCode,
75+
"FD poll failed");
76+
}
77+
if (PollStatus == 0)
78+
return llvm::make_error<llvm::StringError>(
79+
std::make_error_code(std::errc::timed_out),
80+
"No client requests within timeout window");
81+
82+
if (FDs[0].revents & POLLNVAL)
83+
return llvm::make_error<llvm::StringError>(
84+
std::make_error_code(std::errc::bad_file_descriptor));
85+
86+
auto Stop = std::chrono::steady_clock::now();
87+
ElapsedTime +=
88+
std::chrono::duration_cast<std::chrono::milliseconds>(Stop - Start);
89+
}
90+
return llvm::Error::success();
91+
}

llvm/lib/Support/raw_socket_stream.cpp

Lines changed: 4 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/Support/raw_socket_stream.h"
1515
#include "llvm/Config/config.h"
1616
#include "llvm/Support/Error.h"
17+
#include "llvm/Support/FileDescriptor.h"
1718
#include "llvm/Support/FileSystem.h"
1819

1920
#include <atomic>
@@ -179,64 +180,9 @@ Expected<ListeningSocket> ListeningSocket::createUnix(StringRef SocketPath,
179180

180181
Expected<std::unique_ptr<raw_socket_stream>>
181182
ListeningSocket::accept(std::chrono::milliseconds Timeout) {
182-
183-
struct pollfd FDs[2];
184-
FDs[0].events = POLLIN;
185-
#ifdef _WIN32
186-
SOCKET WinServerSock = _get_osfhandle(FD);
187-
FDs[0].fd = WinServerSock;
188-
#else
189-
FDs[0].fd = FD;
190-
#endif
191-
FDs[1].events = POLLIN;
192-
FDs[1].fd = PipeFD[0];
193-
194-
// Keep track of how much time has passed in case poll is interupted by a
195-
// signal and needs to be recalled
196-
int RemainingTime = Timeout.count();
197-
std::chrono::milliseconds ElapsedTime = std::chrono::milliseconds(0);
198-
int PollStatus = -1;
199-
200-
while (PollStatus == -1 && (Timeout.count() == -1 || ElapsedTime < Timeout)) {
201-
if (Timeout.count() != -1)
202-
RemainingTime -= ElapsedTime.count();
203-
204-
auto Start = std::chrono::steady_clock::now();
205-
#ifdef _WIN32
206-
PollStatus = WSAPoll(FDs, 2, RemainingTime);
207-
#else
208-
PollStatus = ::poll(FDs, 2, RemainingTime);
209-
#endif
210-
// If FD equals -1 then ListeningSocket::shutdown has been called and it is
211-
// appropriate to return operation_canceled
212-
if (FD.load() == -1)
213-
return llvm::make_error<StringError>(
214-
std::make_error_code(std::errc::operation_canceled),
215-
"Accept canceled");
216-
217-
#if _WIN32
218-
if (PollStatus == SOCKET_ERROR) {
219-
#else
220-
if (PollStatus == -1) {
221-
#endif
222-
std::error_code PollErrCode = getLastSocketErrorCode();
223-
// Ignore EINTR (signal occured before any request event) and retry
224-
if (PollErrCode != std::errc::interrupted)
225-
return llvm::make_error<StringError>(PollErrCode, "FD poll failed");
226-
}
227-
if (PollStatus == 0)
228-
return llvm::make_error<StringError>(
229-
std::make_error_code(std::errc::timed_out),
230-
"No client requests within timeout window");
231-
232-
if (FDs[0].revents & POLLNVAL)
233-
return llvm::make_error<StringError>(
234-
std::make_error_code(std::errc::bad_file_descriptor));
235-
236-
auto Stop = std::chrono::steady_clock::now();
237-
ElapsedTime +=
238-
std::chrono::duration_cast<std::chrono::milliseconds>(Stop - Start);
239-
}
183+
llvm::Error TimeoutErr = manageTimeout(Timeout, FD, PipeFD[0]);
184+
// if (TimeoutErr)
185+
// return TimeoutErr;
240186

241187
int AcceptFD;
242188
#ifdef _WIN32

llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ static_library("Support") {
8080
"ExponentialBackoff.cpp",
8181
"ExtensibleRTTI.cpp",
8282
"FileCollector.cpp",
83+
"FileDescriptor.cpp",
8384
"FileOutputBuffer.cpp",
8485
"FileUtilities.cpp",
8586
"FloatingPointMode.cpp",

0 commit comments

Comments
 (0)