aboutsummaryrefslogtreecommitdiff
path: root/Sources/SleepInhibition.swift
diff options
context:
space:
mode:
authorGrégoire Duchêne <gregoire@awhk.org>2026-09-16 15:23:36 +0100
committerGrégoire Duchêne <gregoire@awhk.org>2026-09-16 15:23:36 +0100
commit3f5e77bac4cae53957eb707eb298fe34858fc335 (patch)
tree33fff16e81a1692b6dbe81067336cc93a757be05 /Sources/SleepInhibition.swift
parent5855696b7d8d360794ae5efba4dbc90e31eaf260 (diff)
Make sleep inhibition more structuredHEADmain
Diffstat (limited to 'Sources/SleepInhibition.swift')
-rw-r--r--Sources/SleepInhibition.swift42
1 files changed, 42 insertions, 0 deletions
diff --git a/Sources/SleepInhibition.swift b/Sources/SleepInhibition.swift
new file mode 100644
index 0000000..0d9a05e
--- /dev/null
+++ b/Sources/SleepInhibition.swift
@@ -0,0 +1,42 @@
+#if canImport(IOKit.pwr_mgt)
+import IOKit.pwr_mgt
+
+func withSleepInhibited(operation: () async throws -> Void) async throws {
+ let assertionID = try {
+ var assertionID = IOPMAssertionID(0)
+ let ioReturn = IOPMAssertionCreateWithDescription(
+ kIOPMAssertionTypePreventUserIdleSystemSleep as CFString,
+ "caffeinate-downloads" as CFString,
+ "There are files being downloaded" as CFString,
+ nil, nil, 0, nil,
+ &assertionID
+ )
+ guard ioReturn == kIOReturnSuccess else {
+ throw SleepInhibitionError("failed to inhibit sleep", ioReturn)
+ }
+ return assertionID
+ }()
+
+ do {
+ try await operation()
+ } catch is CancellationError {
+ }
+
+ let ioReturn = IOPMAssertionRelease(assertionID)
+ guard ioReturn == kIOReturnSuccess else {
+ throw SleepInhibitionError("failed to allow sleep", ioReturn)
+ }
+}
+
+struct SleepInhibitionError: CustomStringConvertible, Error {
+ let description: String
+
+ init(_ description: String, _ code: IOReturn) {
+ if let code = mach_error_string(code) {
+ self.description = "\(description): \(String(cString: code))"
+ } else {
+ self.description = "\(description): \(code)"
+ }
+ }
+}
+#endif