Last active
August 28, 2016 14:25
-
-
Save hohl/cf1f6f9f88c748097dd45e0ffa77f1a2 to your computer and use it in GitHub Desktop.
Serial dispatch queue implementation for cross-platform usage with Vapor. Feel free to use the code below as you want.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Core | |
/** | |
Defines the basic ability of a job queue to dispatch jobs on a queue. | |
ThreadQueue is designed as protocol to support further implementations like a ConcurrentQueue. | |
*/ | |
public protocol ThreadQueue { | |
func dispatch(_ function: @escaping () -> Void) | |
} | |
/** | |
A basic and lightweight serial job queue which runs all jobs serially on a single thread. | |
*/ | |
public class SerialQueue: ThreadQueue { | |
private let lock = Lock() | |
private let semaphore = Semaphore() | |
private var jobs = [() -> Void]() | |
public init() throws { | |
try background(function: { | |
self.run() | |
}); | |
} | |
public func dispatch(_ function: @escaping () -> Void) { | |
lock.lock() | |
defer { | |
lock.unlock() | |
} | |
jobs.append(function) | |
semaphore.signal() | |
} | |
private func run() { | |
while true { | |
var job: (() -> Void)? | |
do { | |
lock.lock() | |
defer { | |
lock.unlock() | |
} | |
let count = jobs.count | |
if count > 0 { | |
job = jobs.removeFirst() | |
} else { | |
semaphore.wait() | |
if jobs.count > 0 { | |
job = jobs.removeFirst() | |
} | |
} | |
} | |
if let job = job { | |
job() | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment