sem_timedwait(), sem_timedwait_monotonic()

Wait on a named or unnamed semaphore, with a timeout

Synopsis:

#include <semaphore.h>
#include <time.h>

int sem_timedwait( 
        sem_t * sem,
        const struct timespec * abs_timeout );

int sem_timedwait_monotonic(
        sem_t * sem,
        const struct timespec * abs_timeout );

Arguments:

sem
The semaphore that you want to wait on.
abs_timeout
A pointer to a timespec structure that specifies the absolute time at which the time-out is to expire.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The sem_timedwait() function decrements the semaphore referenced by sem as in the sem_wait() function. However, if the semaphore can't be decremented without waiting for another thread to increment the semaphore by calling sem_post(), the wait is terminated when the specified timeout expires. The timeout is based on the CLOCK_REALTIME clock.

The sem_timedwait_monotonic() function is a QNX Neutrino extension; it's similar to sem_timedwait(), but it uses CLOCK_MONOTONIC, so the timeout isn't affected by changes to the system time.

The timeout expires when the absolute time specified by abs_timeout passes, as measured by the clock on which timeouts are based (i.e. when the value of that clock equals or exceeds abs_timeout), or if the absolute time specified by abs_timeout has already been passed at the time of the call.

Returns:

0
The calling thread successfully decremented the semaphore designated by sem.
-1
The call was unsuccessful (errno is set). The state of the semaphore is unchanged.

Errors:

EINTR
A signal interrupted this function.
EINVAL
Invalid semaphore sem, or the thread would have blocked, and the abs_timeout parameter specified a nanoseconds field value less than zero or greater than or equal to 1000 million.
ETIMEDOUT
The semaphore couldn't be decremented before the specified timeout expired.

Examples:

#include <stdio.h>
#include <semaphore.h>
#include <time.h>

main(){

    struct timespec tm;
    sem_t sem;
    int i=0;

    sem_init( &sem, 0, 0);

    do {
        clock_gettime(CLOCK_REALTIME, &tm);
        tm.tv_sec += 1;
        i++;
        printf("i=%d\n",i);
        if (i==10) {
            sem_post(&sem);
        }

    } while ( sem_timedwait( &sem, &tm ) == -1 );

    printf("Semaphore acquired after %d timeouts\n", i);
    return;
}

Classification:

sem_timedwait() is POSIX 1003.1; sem_timedwait_monotonic() is QNX Neutrino

Safety:  
Cancellation point Yes
Interrupt handler No
Signal handler Yes
Thread Yes