Scroll to navigation

dispatch_semaphore_create(3) Library Functions Manual dispatch_semaphore_create(3)

NAME

dispatch_semaphore_create, dispatch_semaphore_signal, dispatch_semaphore_wait
synchronized counting semaphore

SYNOPSIS

#include <dispatch/dispatch.h>
dispatch_semaphore_t
dispatch_semaphore_create(long count);
long
dispatch_semaphore_signal(dispatch_semaphore_t semaphore);
long
dispatch_semaphore_wait(dispatch_semaphore_t semaphore, dispatch_time_t timeout);

DESCRIPTION

Dispatch semaphores are used to synchronize threads. The timeout parameter is creatable with the dispatch_time(3) or dispatch_walltime(3) functions.

COMPLETION SYNCHRONIZATION

If the count parameter is equal to zero, then the semaphore is useful for synchronizing completion of work. For example:
sema = dispatch_semaphore_create(0); 
 
dispatch_async(queue, ^{ 
	foo(); 
	dispatch_semaphore_signal(sema); 
}); 
 
bar(); 
 
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

FINITE RESOURCE POOL

If the count parameter is greater than zero, then the semaphore is useful for managing a finite pool of resources. For example, a library that wants to limit Unix descriptor usage:
sema = dispatch_semaphore_create(getdtablesize() / 4);
At each Unix FD allocation:
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 
fd = open("/etc/services", O_RDONLY);
When each FD is closed:
close(fd); 
dispatch_semaphore_signal(sema);

RETURN VALUES

The dispatch_semaphore_create() function returns NULL if no memory is available or if the count parameter is less than zero.
The dispatch_semaphore_signal() function returns non-zero when a thread is woken. Otherwise, zero is returned.
The dispatch_semaphore_wait() function returns zero upon success and non-zero after the timeout expires. If the timeout is DISPATCH_TIME_FOREVER, then dispatch_semaphore_wait() waits forever and always returns zero.

MEMORY MODEL

Dispatch semaphores are retained and released via calls to dispatch_retain() and dispatch_release().

CAVEATS

Dispatch semaphores are strict counting semaphores. In other words, dispatch semaphores do not saturate at any particular value. Saturation can be achieved through atomic compare-and-swap logic. What follows is a saturating binary semaphore:
void 
saturating_semaphore_signal(dispatch_semaphore_t dsema, int *sent) 
{ 
	if (__sync_bool_compare_and_swap(sent, 0, 1)) { 
		dispatch_semaphore_signal(dsema); 
	} 
} 
 
void 
saturating_semaphore_wait(dispatch_semaphore_t dsema, int *sent) 
{ 
	*sent = 0; 
	dispatch_semaphore_wait(dsema, DISPATCH_TIME_FOREVER); 
}

SEE ALSO

dispatch(3), dispatch_object(3)
May 1, 2009 Darwin