CommandLineToolkit

Форк
0
62 строки · 1.7 Кб
1
import Dispatch
2
import Foundation
3
import Signals
4
import Types
5

6
public typealias SignalHandler = (Int32) -> ()
7

8
private let syncQueue = DispatchQueue(label: "SignalHandling.syncQueue")
9
private var signalHandlers = [Int32: [UUID: SignalHandler]]()
10

11
// swiftlint:disable sync
12

13
public final class SignalHandling {
14
    public struct Handle {
15
        var signal: Int32
16
        var id: UUID
17
    }
18

19
    private init() {}
20

21
    /// Captures and holds a given handler and invokes it when a required signal occurs.
22
    @discardableResult
23
    public static func addSignalHandler(signal: Signal, handler: @escaping SignalHandler) -> Handle {
24
        let id = UUID()
25
        
26
        syncQueue.sync {
27
            signalHandlers[signal.intValue, default: [:]][id] = handler
28
        }
29
        
30
        Signals.trap(signal: signal.blueSignal) { signalValue in
31
            _handleSignal(signalValue)
32
        }
33

34
        return Handle(signal: signal.intValue, id: id)
35
    }
36

37
    public static func removeSignalHandler(handle: Handle) {
38
        syncQueue.sync {
39
            signalHandlers[handle.signal]?[handle.id] = nil
40
        }
41
    }
42

43
    public static func listen(signal: Signal) -> AsyncStream<Signal> {
44
        AsyncStream { continuation in
45
            let handle = addSignalHandler(signal: signal) { signal in
46
                continuation.yield(.init(rawValue: signal))
47
            }
48

49
            continuation.onTermination = { _ in
50
                removeSignalHandler(handle: handle)
51
            }
52
        }
53
    }
54
}
55

56
/// Universal signal handler
57
private func _handleSignal(_ signalValue: Int32) {
58
    let registeredHandlers = syncQueue.sync { signalHandlers[signalValue, default: [:]] }
59
    for (_, handler) in registeredHandlers {
60
        handler(signalValue)
61
    }
62
}
63

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.