I noticed that the use of locks in the QueueManager, especially the one that throws, could end up holding onto the lock too long:
|
fileprivate func synchronizeThrows<T>(action: () throws -> T) throws -> T { |
|
recursiveLock.lock() |
|
let result = try action() |
|
recursiveLock.unlock() |
|
return result |
|
} |
|
|
|
fileprivate func synchronize <T>(action: () -> T) -> T { |
|
recursiveLock.lock() |
|
let result = action() |
|
recursiveLock.unlock() |
|
return result |
|
} |
. I'm not a swift expert, but moving unlock into a
defer block should guarantee that the lock is released on exiting. I haven't repro'd this, but I would think any failable function being passed to synchronizeThrows would cause later operations to hang.
I noticed that the use of locks in the QueueManager, especially the one that throws, could end up holding onto the lock too long:
SwiftAudioEx/Sources/SwiftAudioEx/QueueManager.swift
Lines 20 to 32 in 4276703
deferblock should guarantee that the lock is released on exiting. I haven't repro'd this, but I would think any failable function being passed to synchronizeThrows would cause later operations to hang.