[llvm] [llvm-jitlink] Replace pipes with unix domain sockets. (PR #223941)
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 16 00:59:32 PDT 2026
https://github.com/lhames created https://github.com/llvm/llvm-project/pull/223941
Replace pipes with unix domain sockets for basic out-of-process execution.
The new ORC runtime doesn't support pipes -- this changes will enable llvm-jitlink to connect to the new ORC runtime's executor (once it lands).
>From 7fa6e9276eb8e02eb0e48b7a033ed88349dd447e Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at apple.com>
Date: Wed, 16 Sep 2026 17:55:14 +1000
Subject: [PATCH] [llvm-jitlink] Replace pipes with unix domain sockets.
Replace pipes with unix domain sockets for basic out-of-process
execution.
The new ORC runtime doesn't support pipes -- this changes will enable
llvm-jitlink to connect to the new ORC runtime's executor (once it
lands).
---
.../llvm-jitlink-executor.cpp | 17 +++---
llvm/tools/llvm-jitlink/llvm-jitlink.cpp | 53 +++++--------------
2 files changed, 20 insertions(+), 50 deletions(-)
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
index d181858cd86990..3b0252d3c94aa2 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
@@ -138,8 +138,7 @@ int main(int argc, char *argv[]) {
ExitOnErr.setBanner(std::string(argv[0]) + ": ");
unsigned FirstProgramArg = 1;
- int InFD = 0;
- int OutFD = 0;
+ int FD = 0;
if (argc < 2)
printErrorAndExit("insufficient arguments");
@@ -164,13 +163,9 @@ int main(int argc, char *argv[]) {
StringRef SpecifierType, Specifier;
std::tie(SpecifierType, Specifier) = NextArg.split('=');
- if (SpecifierType == "filedescs") {
- StringRef FD1Str, FD2Str;
- std::tie(FD1Str, FD2Str) = Specifier.split(',');
- if (FD1Str.getAsInteger(10, InFD))
- printErrorAndExit(FD1Str + " is not a valid file descriptor");
- if (FD2Str.getAsInteger(10, OutFD))
- printErrorAndExit(FD2Str + " is not a valid file descriptor");
+ if (SpecifierType == "fd") {
+ if (Specifier.getAsInteger(10, FD))
+ printErrorAndExit(Specifier + " is not a valid file descriptor");
} else if (SpecifierType == "listen") {
StringRef Host, PortStr;
std::tie(Host, PortStr) = Specifier.split(':');
@@ -179,7 +174,7 @@ int main(int argc, char *argv[]) {
if (PortStr.getAsInteger(10, Port))
printErrorAndExit("port number '" + PortStr + "' is not a valid integer");
- InFD = OutFD = openListener(Host.str(), PortStr.str());
+ FD = openListener(Host.str(), PortStr.str());
} else
printErrorAndExit("invalid specifier type \"" + SpecifierType + "\"");
@@ -203,7 +198,7 @@ int main(int argc, char *argv[]) {
rt_bootstrap::ExecutorSharedMemoryMapperService>());
return Error::success();
},
- InFD, OutFD));
+ FD, FD));
ExitOnErr(Server->waitForDisconnect());
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index cbc419e84b3e56..05606849797ab9 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -932,60 +932,35 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() {
inconvertibleErrorCode());
#else
- constexpr int ReadEnd = 0;
- constexpr int WriteEnd = 1;
-
- // Pipe FDs.
- int ToExecutor[2];
- int FromExecutor[2];
+ constexpr int ParentSocket = 0, ChildSocket = 1;
+ int Sockets[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, Sockets) == -1)
+ return make_error<StringError>(
+ Twine("Unable to create socket for executor: ") + strerror(errno),
+ inconvertibleErrorCode());
pid_t ChildPID;
-
- // Create pipes to/from the executor..
- if (pipe(ToExecutor) != 0 || pipe(FromExecutor) != 0)
- return make_error<StringError>("Unable to create pipe for executor",
- inconvertibleErrorCode());
-
ChildPID = fork();
if (ChildPID == 0) {
// In the child...
-
- // Close the parent ends of the pipes
- close(ToExecutor[WriteEnd]);
- close(FromExecutor[ReadEnd]);
-
- // Execute the child process.
- std::unique_ptr<char[]> ExecutorPath, FDSpecifier;
- {
- ExecutorPath = std::make_unique<char[]>(OutOfProcessExecutor.size() + 1);
- strcpy(ExecutorPath.get(), OutOfProcessExecutor.data());
-
- std::string FDSpecifierStr("filedescs=");
- FDSpecifierStr += utostr(ToExecutor[ReadEnd]);
- FDSpecifierStr += ',';
- FDSpecifierStr += utostr(FromExecutor[WriteEnd]);
- FDSpecifier = std::make_unique<char[]>(FDSpecifierStr.size() + 1);
- strcpy(FDSpecifier.get(), FDSpecifierStr.c_str());
- }
-
- char *const Args[] = {ExecutorPath.get(), FDSpecifier.get(), nullptr};
- int RC = execvp(ExecutorPath.get(), Args);
+ close(Sockets[ParentSocket]);
+ std::string ConnSpec = "fd=" + std::to_string(Sockets[ChildSocket]);
+ char *const Args[] = {OutOfProcessExecutor.data(), ConnSpec.data(),
+ nullptr};
+ int RC = execvp(OutOfProcessExecutor.data(), Args);
if (RC != 0) {
errs() << "unable to launch out-of-process executor \""
- << ExecutorPath.get() << "\"\n";
+ << OutOfProcessExecutor << "\"\n";
exit(1);
}
}
// else we're the parent...
-
- // Close the child ends of the pipes
- close(ToExecutor[ReadEnd]);
- close(FromExecutor[WriteEnd]);
+ close(Sockets[ChildSocket]);
return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
std::make_unique<DynamicThreadPoolTaskDispatcher>(MaterializationThreads),
- FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
+ Sockets[ParentSocket], Sockets[ParentSocket]);
#endif
}
More information about the llvm-commits
mailing list