Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dispatch semaphore signal on wait timeout

When a dispatch_semaphore_wait runs into a timeout, does it automatically signal itself (increment the count), or has this to be done manually?

like image 244
Era Avatar asked Mar 31 '15 06:03

Era


1 Answers

dispatch_semaphore_wait() decrements the counting semaphore and waits if the resulting value is less than zero. If a timeout occurs, this decrement is reversed, so you don't have to adjust the count manually.

This is not apparent (to me) from the documentation, but consistent with the fact that a negative count indicates that threads are waiting on the semaphore. See also this comment in the source code:

// If the internal value is negative, then the absolute of the value is
// equal to the number of waiting threads. ...

You can also verify it by printing the debugDescription of the semaphore, the output shows the current value:

let sem = dispatch_semaphore_create(0)

NSLog("%@", sem.debugDescription)
// <OS_dispatch_semaphore: semaphore[0x100514a70] = { ..., value = 0, orig = 0 }>
// --> Initial value is 0

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(NSEC_PER_SEC)),
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
        NSLog("%@", sem.debugDescription)
        // <OS_dispatch_semaphore: semaphore[0x100514a70] = { ..., value = -1, orig = 0 }>
        // --> One thread is waiting, value is -1.
}

let ret = dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, 2*Int64(NSEC_PER_SEC)))
NSLog("%@", sem.debugDescription)
// <OS_dispatch_semaphore: semaphore[0x100514a70] = { ..., value = 0, orig = 0 }>
// --> Time out, value is 0 again.
like image 184
Martin R Avatar answered Sep 30 '22 18:09

Martin R