-
-
Save zwaldowski/777c5b9e004122ba7930 to your computer and use it in GitHub Desktop.
A function declared as rethrows that synchronously executes a throwing block in a dispatch_queue.
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 Dispatch | |
@_silgen_name("dispatch_sync") private func os_dispatch_sync(queue: dispatch_queue_t, @noescape _ block: dispatch_block_t) | |
@_silgen_name("dispatch_barrier_sync") private func os_dispatch_barrier_sync(queue: dispatch_queue_t, @noescape _ block: dispatch_block_t) | |
private func dispatch_sync_rethrow_wrapper<Return>(queue: dispatch_queue_t, @noescape dispatcher: (dispatch_queue_t, dispatch_block_t) -> Void, @noescape body: () throws -> Return, @noescape onError: ErrorType throws -> Void) rethrows -> Return { | |
var ret: Return! | |
var innerError: ErrorType? | |
os_dispatch_sync(queue) { | |
do { | |
ret = try body() | |
} catch { | |
innerError = error | |
} | |
} | |
if let innerError = innerError { | |
try onError(innerError) | |
} | |
return ret | |
} | |
// A function declared as rethrows that synchronously executes a throwing | |
// block in a dispatch_queue. | |
// | |
// Based on Ransak's answer to https://forums.developer.apple.com/message/19685 | |
public func dispatch_sync<Return>(queue: dispatch_queue_t, @noescape _ body: () throws -> Return) rethrows -> Return { | |
return try dispatch_sync_rethrow_wrapper(queue, dispatcher: os_dispatch_sync, body: body, onError: { throw $0 }) | |
} | |
public func dispatch_barrier_sync<Return>(queue: dispatch_queue_t, @noescape _ body: () throws -> Return) rethrows -> Return { | |
return try dispatch_sync_rethrow_wrapper(queue, dispatcher: os_dispatch_barrier_sync, body: body, onError: { throw $0 }) | |
} | |
// Some error | |
struct SomeError: ErrorType {} | |
// Some queue: | |
let queue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0) | |
// try required for throwing closure: | |
do { | |
let value = try dispatch_sync(queue) { () -> Int in | |
throw SomeError() | |
} | |
print("returned \(value)") | |
} catch { | |
print("caught \(error)") | |
} | |
// try not required for non-throwing closure: | |
let value = dispatch_sync(queue) { () -> Int in | |
print("hello") | |
return 5 | |
} | |
print("returned \(value)") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment