[llvm] [orc-rt] Add ConnectorRegistry and the socket:adopt connector (PR #225398)

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 22 06:40:11 PDT 2026


https://github.com/lhames created https://github.com/llvm/llvm-project/pull/225398

Maps the transport named by a ConnectionSpec to the connector that establishes it. Connectors are registered manually, so they are only available -- and for static archive builds, only linked -- if explicitly requested.

Clients can connect a Session to a controller by passing a ConnectionSpec for a registered transport (provided that the ConnectionSpec is well-formed as defined by that transport).

This commit introduces a "socket:adopt" connector, which takes a stream socket that this process already holds and attaches a SocketSimpleRemoteCA for it.

>From 04d226c91a33e4733a683e755ddf4a907249eb81 Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Tue, 22 Sep 2026 18:12:29 +1000
Subject: [PATCH] [orc-rt] Add ConnectorRegistry and the socket:adopt connector

Maps the transport named by a ConnectionSpec to the connector that
establishes it. Connectors are registered manually, so they are only
available -- and for static archive builds, only linked -- if
explicitly requested.

Clients can connect a Session to a controller by passing a
ConnectionSpec for a registered transport (provided that the
ConnectionSpec is well-formed as defined by that transport).

This commit introduces a "socket:adopt" connector, which takes a stream
socket that this process already holds and attaches a SocketSimpleRemoteCA
for it.
---
 .../orc-rt/bedrock/ConnectorRegistry.h        | 71 +++++++++++++++++++
 .../include/orc-rt/bedrock/SocketConnector.h  | 26 +++++++
 orc-rt/lib/bedrock/CMakeLists.txt             |  2 +
 orc-rt/lib/bedrock/ConnectorRegistry.cpp      | 59 +++++++++++++++
 .../lib/bedrock/sys/posix/SocketConnector.cpp | 68 ++++++++++++++++++
 5 files changed, 226 insertions(+)
 create mode 100644 orc-rt/include/orc-rt/bedrock/ConnectorRegistry.h
 create mode 100644 orc-rt/include/orc-rt/bedrock/SocketConnector.h
 create mode 100644 orc-rt/lib/bedrock/ConnectorRegistry.cpp
 create mode 100644 orc-rt/lib/bedrock/sys/posix/SocketConnector.cpp

diff --git a/orc-rt/include/orc-rt/bedrock/ConnectorRegistry.h b/orc-rt/include/orc-rt/bedrock/ConnectorRegistry.h
new file mode 100644
index 0000000000000..72150f3b66df1
--- /dev/null
+++ b/orc-rt/include/orc-rt/bedrock/ConnectorRegistry.h
@@ -0,0 +1,71 @@
+//===- ConnectorRegistry.h - Transport connector registry -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// A registry of connectors, keyed by transport name.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ORC_RT_BEDROCK_CONNECTORREGISTRY_H
+#define ORC_RT_BEDROCK_CONNECTORREGISTRY_H
+
+#include "orc-rt/bedrock/BootstrapInfo.h"
+#include "orc-rt/bedrock/ConnectionSpec.h"
+#include "orc-rt/support/Error.h"
+#include "orc-rt/support/move_only_function.h"
+
+#include <mutex>
+#include <string>
+#include <unordered_map>
+
+namespace orc_rt {
+
+class Session;
+
+/// Maps transport names to the connectors that establish them, so that a
+/// process can act on a ConnectionSpec without knowing which transports were
+/// built into it.
+///
+/// Connectors are registered explicitly rather than self-registering. This
+/// ensures that only requested transport mechanisms are available.
+class ConnectorRegistry {
+public:
+  struct AttachInfo {
+    Session &S;
+    BootstrapInfo BI;
+  };
+
+  /// Supplies the Session and BootstrapInfo to connect.
+  using GetAttachInfoFn = move_only_function<Expected<AttachInfo>() noexcept>;
+
+  /// Establishes the connection CS describes and attaches it to the Session
+  /// that GetSession returns.
+  using ConnectorFn = move_only_function<Error(
+      GetAttachInfoFn GetAttachInfo, const ConnectionSpec &) noexcept>;
+
+  /// Registers Connector as the handler for Transport.
+  ///
+  /// Errors if Transport already has one: two connectors for one name means
+  /// the process cannot tell which it is speaking.
+  Error registerConnector(std::string Transport,
+                          ConnectorFn Connector) noexcept;
+
+  /// Runs the connector registered for CS's transport.
+  ///
+  /// Fails if no connector is registered for it, which is how a spec naming a
+  /// transport this process was not built with is reported.
+  Error connect(GetAttachInfoFn GetAttachInfo,
+                const ConnectionSpec &CS) noexcept;
+
+private:
+  std::mutex M;
+  std::unordered_map<std::string, ConnectorFn> Connectors;
+};
+
+} // namespace orc_rt
+
+#endif // ORC_RT_BEDROCK_CONNECTORREGISTRY_H
diff --git a/orc-rt/include/orc-rt/bedrock/SocketConnector.h b/orc-rt/include/orc-rt/bedrock/SocketConnector.h
new file mode 100644
index 0000000000000..1e28578e1ab62
--- /dev/null
+++ b/orc-rt/include/orc-rt/bedrock/SocketConnector.h
@@ -0,0 +1,26 @@
+//===- SocketConnector.h - Inherited socket connector -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// A connector for the "socket" transport.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ORC_RT_BEDROCK_SOCKETCONNECTOR_H
+#define ORC_RT_BEDROCK_SOCKETCONNECTOR_H
+
+#include "orc-rt/bedrock/ConnectorRegistry.h"
+
+namespace orc_rt {
+
+/// Registers the connector for the "socket" transport, whose only action is
+/// "adopt": a stream socket this process was handed, already connected.
+Error registerSocketConnector(ConnectorRegistry &R) noexcept;
+
+} // namespace orc_rt
+
+#endif // ORC_RT_BEDROCK_SOCKETCONNECTOR_H
diff --git a/orc-rt/lib/bedrock/CMakeLists.txt b/orc-rt/lib/bedrock/CMakeLists.txt
index 48f77c664b526..a0c2cd98a129c 100644
--- a/orc-rt/lib/bedrock/CMakeLists.txt
+++ b/orc-rt/lib/bedrock/CMakeLists.txt
@@ -2,6 +2,7 @@
 set(ORC_RT_BEDROCK_SOURCES
   BootstrapInfo.cpp
   ConnectionSpec.cpp
+  ConnectorRegistry.cpp
   ExecutorProcessInfo.cpp
   GDBJITRegistrar.cpp
   InProcessControllerAccess.cpp
@@ -40,6 +41,7 @@ set(ORC_RT_BEDROCK_POSIX_SOURCES
   sys/posix/DynamicLibrary.cpp
   sys/posix/Memory.cpp
   sys/posix/PageSize.cpp
+  sys/posix/SocketConnector.cpp
   sys/posix/SocketHandle.cpp
   sys/posix/sps/SimpleRemoteCAOverSocket.cpp
 )
diff --git a/orc-rt/lib/bedrock/ConnectorRegistry.cpp b/orc-rt/lib/bedrock/ConnectorRegistry.cpp
new file mode 100644
index 0000000000000..c850cca7f4cbd
--- /dev/null
+++ b/orc-rt/lib/bedrock/ConnectorRegistry.cpp
@@ -0,0 +1,59 @@
+//===- ConnectorRegistry.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains the implementation of APIs in the
+// orc-rt/bedrock/ConnectorRegistry.h header.
+//
+//===----------------------------------------------------------------------===//
+
+#include "orc-rt/bedrock/ConnectorRegistry.h"
+
+#include "orc-rt-internal/support/StringExtras.h"
+
+#include <cassert>
+
+using namespace orc_rt;
+
+namespace orc_rt {
+
+Error ConnectorRegistry::registerConnector(std::string Transport,
+                                           ConnectorFn Connector) noexcept {
+  std::scoped_lock<std::mutex> Lock(M);
+  if (Connectors.count(Transport))
+    return make_error<StringError>(
+        (StringOutputStream()
+         << "A connector is already registered for transport \"" << Transport
+         << "\"")
+            .str());
+  Connectors[std::move(Transport)] = std::move(Connector);
+  return Error::success();
+}
+
+Error ConnectorRegistry::connect(GetAttachInfoFn GetAttachInfo,
+                                 const ConnectionSpec &CS) noexcept {
+  ConnectorFn *Connector = nullptr;
+  {
+    std::scoped_lock<std::mutex> Lock(M);
+    auto I = Connectors.find(CS.transport());
+    if (I == Connectors.end())
+      return make_error<StringError>((StringOutputStream()
+                                      << "In connection spec \"" << CS.str()
+                                      << "\", unrecognized transport \""
+                                      << CS.transport() << "\"")
+                                         .str());
+    Connector = &I->second;
+  }
+
+  // Run the connector without the lock: it blocks on IO, and may register
+  // further connectors or connect again. The pointer stays good because
+  // unordered_map does not move its elements on insert, and nothing removes
+  // them.
+  return (*Connector)(std::move(GetAttachInfo), CS);
+}
+
+} // namespace orc_rt
diff --git a/orc-rt/lib/bedrock/sys/posix/SocketConnector.cpp b/orc-rt/lib/bedrock/sys/posix/SocketConnector.cpp
new file mode 100644
index 0000000000000..7d98ef116f88c
--- /dev/null
+++ b/orc-rt/lib/bedrock/sys/posix/SocketConnector.cpp
@@ -0,0 +1,68 @@
+//===- SocketConnector.cpp - Socket connector on POSIX ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Adoption of an inherited socket on POSIX systems.
+//
+//===----------------------------------------------------------------------===//
+
+#include "orc-rt/bedrock/SocketConnector.h"
+
+#include "orc-rt-internal/support/StringExtras.h"
+#include "orc-rt/bedrock/sps/SimpleRemoteCAOverSocket.h"
+
+#include <charconv>
+
+using namespace orc_rt;
+
+namespace {
+
+Error socketConnector(ConnectorRegistry::GetAttachInfoFn GetAttachInfo,
+                      const ConnectionSpec &CS) noexcept {
+  auto BadCS = [&](const std::string &Reason) noexcept {
+    return make_error<StringError>((StringOutputStream()
+                                    << "Invalid connection spec \"" << CS.str()
+                                    << "\": " << Reason)
+                                       .str());
+  };
+
+  if (CS.action() != "adopt")
+    return BadCS("the socket transport supports only the \"adopt\" action");
+
+  std::string_view FDStr = CS.descriptor();
+  int FD;
+  auto [Ptr, ErrC] =
+      std::from_chars(FDStr.data(), FDStr.data() + FDStr.size(), FD);
+  if (auto EC = std::make_error_code(ErrC))
+    return BadCS(std::string(FDStr) + " is not a descriptor (" + EC.message() +
+                 ")");
+  if (Ptr != FDStr.data() + FDStr.size())
+    return BadCS("trailing characters after file descriptor \"" +
+                 std::string(FDStr) + "\"");
+  if (FD < 0)
+    return BadCS("file descriptor " + std::string(FDStr) + " is negative");
+
+  auto AI = GetAttachInfo();
+  if (!AI)
+    return AI.takeError();
+  auto CA = createSimpleRemoteCAOverSocket(AI->S, SocketHandle(FD));
+  if (!CA)
+    return CA.takeError();
+
+  AI->S.attach(std::move(*CA), std::move(AI->BI));
+  return Error::success();
+}
+
+} // namespace
+
+namespace orc_rt {
+
+Error registerSocketConnector(ConnectorRegistry &R) noexcept {
+  return R.registerConnector("socket", socketConnector);
+}
+
+} // namespace orc_rt



More information about the llvm-commits mailing list