From ff88aa8f5ec1c74efd96587702f7ab82de69861d Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Sun, 14 Nov 2021 21:31:58 -0600 Subject: [PATCH] Move the handle idle command into the command queue My theory is that it's ok to send the `noidle` synchronously but the subsequent handling of the idle response should be on the command queue. My hope is that this fixes issues with less than perfect network connections (and also very occasionally seen on good networks). --- .../Extensions/MPDClient+Command.swift | 2 +- .../MPDClient/Extensions/MPDClient+Idle.swift | 51 +++++++------------ Shared/MPDClient/MPDClient.swift | 2 - 3 files changed, 20 insertions(+), 35 deletions(-) diff --git a/Shared/MPDClient/Extensions/MPDClient+Command.swift b/Shared/MPDClient/Extensions/MPDClient+Command.swift index 8135766..18520c6 100644 --- a/Shared/MPDClient/Extensions/MPDClient+Command.swift +++ b/Shared/MPDClient/Extensions/MPDClient+Command.swift @@ -158,7 +158,7 @@ extension MPDClient { let commandOperation = BlockOperation() { [unowned self] in self.sendCommand(command: command, userData: userData) - + if self.checkError() { self.idle(forceIdle) } diff --git a/Shared/MPDClient/Extensions/MPDClient+Idle.swift b/Shared/MPDClient/Extensions/MPDClient+Idle.swift index 362086e..3029be3 100644 --- a/Shared/MPDClient/Extensions/MPDClient+Idle.swift +++ b/Shared/MPDClient/Extensions/MPDClient+Idle.swift @@ -12,50 +12,37 @@ import mpdclient extension MPDClient { func noIdle() { guard isConnected else { return } - - do { - idleLock.lock() - defer { idleLock.unlock() } - if isIdle { - mpd_send_noidle(connection) - isIdle = false - } + + if isIdle { + mpd_send_noidle(connection) } } func idle(_ force: Bool = false) { guard isConnected else { return } - let shouldIdle: Bool - - do { - idleLock.lock() - defer { idleLock.unlock() } - shouldIdle = (!isIdle && commandQueue.operationCount == 1) || force - if shouldIdle { - mpd_send_idle(connection) - self.isIdle = true - } - } - + let shouldIdle: Bool = (!isIdle && commandQueue.operationCount == 1) || force + if shouldIdle { - let result = mpd_recv_idle(connection, true) - handleIdleResult(result) + self.isIdle = true + mpd_send_idle(connection) + + let handleIdleOperation = BlockOperation() { [unowned self] in + self.handleIdleResult() + } + + handleIdleOperation.queuePriority = .high + commandQueue.addOperation(handleIdleOperation) } } - func handleIdleResult(_ result: mpd_idle) { + func handleIdleResult() { + let result = mpd_recv_idle(connection, true) let mpdIdle = MPDIdle(rawValue: result.rawValue) - let wasIdle: Bool + + isIdle = false - do { - idleLock.lock() - defer { idleLock.unlock() } - wasIdle = isIdle - isIdle = false - } - - if checkError() && wasIdle { + if checkError() { if mpdIdle.contains(.database) { self.fetchAllAlbums() } diff --git a/Shared/MPDClient/MPDClient.swift b/Shared/MPDClient/MPDClient.swift index c5c522e..9decfd8 100644 --- a/Shared/MPDClient/MPDClient.swift +++ b/Shared/MPDClient/MPDClient.swift @@ -21,8 +21,6 @@ class MPDClient { var queue: [MPDSong] = [] let commandQueue = OperationQueue() - - let idleLock = NSLock() init(withDelegate delegate: MPDClientDelegate?) { commandQueue.maxConcurrentOperationCount = 1