safelock.c
/* Lock a mutex and handle EOWNERDEAD.
 *
 * Arguments:
 * - deadline: lock deadline in microseconds since the epoch
 * - *dirty: optionally reports whether the previous lock owner crashed
 *
 * Handles EOWNERDEAD from robust mutexes if "dirty" is not set,
 * otherwise sets *dirty and leaves cleanup for the caller.
 *
 * Returns 0 on success, and errno on failure:
 *
 * EBUSY            SAFELOCK_LOCK_TRY set, and already locked
 * EDEADLK          The mutex is already locked by the current thread
 * ENOTRECOVERABLE  The mutex is corrupted and needs to be re-init
 * ETIMEDOUT        The mutex could not be locked within the timeout
 *                  specified
 */
Lock a mutex and handle EOWNERDEAD.
Arguments:
- deadline: lock deadline in microseconds since the epoch
- *dirty: optionally reports whether the previous lock owner crashed

Handles EOWNERDEAD from robust mutexes if "dirty" is not set,
otherwise sets *dirty and leaves cleanup for the caller.

Returns 0 on success, and errno on failure.

EBUSY            SAFELOCK_LOCK_TRY set, and already locked
EDEADLK          The mutex is already locked by the current thread
ENOTRECOVERABLE  The mutex is corrupted and needs to be re-init
ETIMEDOUT        The mutex could not be locked within the timeout
specified
Lock a mutex and handle EOWNERDEAD . Arguments : - deadline : lock deadline in microseconds since the epoch - * dirty : optionally reports whether the previous lock owner crashed Handles EOWNERDEAD from robust mutexes if " dirty " is not set otherwise sets * dirty and leaves cleanup for the caller . Returns 0 on success and errno on failure . EBUSY SAFELOCK_LOCK_TRY set and already locked EDEADLK The mutex is already locked by the current thread ENOTRECOVERABLE The mutex is corrupted and needs to be re - init ETIMEDOUT The mutex could not be locked within the timeout specified
static int mutex_lock(pthread_mutex_t *lock, uint64_t deadline,
                      int *dirty)
{
    struct timespec ts;
    int err;
    if (deadline == SAFELOCK_LOCK_WAIT) {
        err = pthread_mutex_lock(lock);
    } else if (deadline == SAFELOCK_LOCK_TRY) {
        err = pthread_mutex_trylock(lock);
    } else {
        ts.tv_sec = deadline / 1000000;
        ts.tv_nsec = (deadline % 1000000) * 1000;
        err = pthread_mutex_timedlock(lock, &ts);
    }
    if (dirty)
        *dirty = 0;
    if (err == EOWNERDEAD) {
#ifdef __USE_XOPEN2K8
        NOFAIL(pthread_mutex_consistent(lock));
        if (dirty)
            *dirty = 1;
#else
        return ENOTRECOVERABLE;
#endif
    } else if (err == EINVAL) {
        return ENOTRECOVERABLE;
    } else if (err) {
        return err;
    }
    return 0;
}
static int mutex_lock ( pthread_mutex_t * lock , uint64_t deadline , int * dirty ) { struct timespec ts ; int err ; if ( deadline == SAFELOCK_LOCK_WAIT ) { err = pthread_mutex_lock ( lock ) ; } else if ( deadline == SAFELOCK_LOCK_TRY ) { err = pthread_mutex_trylock ( lock ) ; } else { ts . tv_sec = deadline / 1000000 ; ts . tv_nsec = ( deadline % 1000000 ) * 1000 ; err = pthread_mutex_timedlock ( lock , & ts ) ; } if ( dirty ) * dirty = 0 ; if ( err == EOWNERDEAD ) { #ifdef __USE_XOPEN2K8 NOFAIL ( pthread_mutex_consistent ( lock ) ) ; if ( dirty ) * dirty = 1 ; #else return ENOTRECOVERABLE ; #endif } else if ( err == EINVAL ) { return ENOTRECOVERABLE ; } else if ( err ) { return err ; } return 0 ; }
Lock a mutex and handle EOWNERDEAD.
Lock a mutex and handle EOWNERDEAD .
/* pthread_mutex_consistent should only fail when
         * the lock isn't robust, or the state is already
         * consistent - either indicates a bug */ /* If a mutex has been corrupted the safelock will need
         * to be removed in a race free manner (Eg, manually) */