Skip to content

Commit b9ef683

Browse files
authored
Add shutDown method to PluginMessageHandler (#2915)
This method deterministically and synchronously cleans up resources that cannot be dealt with in a deinitializer due to possible errors thrown during the clean up. Usually this includes closure of file handles, sockets, shutting down external processes and IPC resources set up for these processes, etc. This method is required for `swift-plugin-server` to properly clean up file handles there were opened for communication with Wasm macros, as prototyped in swiftlang/swift#73031.
1 parent 6be29a5 commit b9ef683

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

Sources/SwiftCompilerPlugin/CompilerPlugin.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,6 @@ extension CompilerPlugin {
112112
let connection = try StandardIOMessageConnection()
113113
let provider = MacroProviderAdapter(plugin: Self())
114114
let impl = CompilerPluginMessageListener(connection: connection, provider: provider)
115-
impl.main()
115+
try impl.main()
116116
}
117117
}

Sources/SwiftCompilerPluginMessageHandling/CompilerPluginMessageHandler.swift

+12-1
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,13 @@ public class CompilerPluginMessageListener<Connection: MessageConnection, Handle
9696
///
9797
/// On internal errors, such as I/O errors or JSON serialization errors, print
9898
/// an error message and `exit(1)`
99-
public func main() {
99+
public func main() throws {
100100
#if os(WASI)
101101
// Rather than blocking on read(), let the host tell us when there's data.
102102
readabilityHandler = { _ = self.handleNextMessage() }
103103
#else
104104
while handleNextMessage() {}
105+
try self.handler.shutDown()
105106
#endif
106107
}
107108

@@ -133,6 +134,12 @@ public class CompilerPluginMessageListener<Connection: MessageConnection, Handle
133134
public protocol PluginMessageHandler {
134135
/// Handles a single message received from the plugin host.
135136
func handleMessage(_ message: HostToPluginMessage) -> PluginToHostMessage
137+
138+
/// Deterministically and synchronously cleans up resources that cannot be dealt with in
139+
/// a deinitializer due to possible errors thrown during the clean up. Usually this
140+
/// includes closure of file handles, sockets, shutting down external processes and IPC
141+
/// resources set up for these processes, etc.
142+
func shutDown() throws
136143
}
137144

138145
/// A `PluginMessageHandler` that uses a `PluginProvider`.
@@ -226,6 +233,10 @@ public class PluginProviderMessageHandler<Provider: PluginProvider>: PluginMessa
226233
return .loadPluginLibraryResult(loaded: diags.isEmpty, diagnostics: diags)
227234
}
228235
}
236+
237+
/// Empty implementation for the default message handler, since all resources are automatically
238+
/// cleaned up in the synthesized initializer.
239+
public func shutDown() throws {}
229240
}
230241

231242
@_spi(PluginMessage)

0 commit comments

Comments
 (0)