diff options
Diffstat (limited to 'Sources/SleepInhibition.swift')
| -rw-r--r-- | Sources/SleepInhibition.swift | 42 |
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 |
