Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's difference between pthread_mutex_trylock's return and pthread_mutex_lock's return

I read the Linux man page and OpenGroup for pthread_mutex_lock and get this:

If successful, the pthread_mutex_lock() and pthread_mutex_unlock() functions shall return zero, otherwise, an error number shall be returned to indicate the error.

The pthread_mutex_trylock() function shall return zero if a lock on the mutex object referenced by mutex is acquired. Otherwise, an error number is returned to indicate the error.

  1. I was confused by these two lines. If you both return zero when sucess and return non-zero when error, where do they write this in two lines?
  2. I know mutex can be lock and unlock, but what does a mutex is acquired mean?
like image 392
Lidong Guo Avatar asked Aug 23 '13 00:08

Lidong Guo


1 Answers

In this context mutex is acquired means that there was no thread holding the lock at the time. If the mutex is recursive, the call to pthread_mutex_trylock() will succeed unless it has been recursively locked too many times.

You can think of pthread_mutex_trylock() as a non-blocking call, where if it would have blocked, it returns with an error instead. If it returns success, it means you have the lock as if pthred_mutex_lock() returned successfully. If it fails with EBUSY it means some other is holding the lock. If it fails with EOWNERDEAD, the lock was held by another thread, but that thread had died (getting the lock actually succeeded, but the current data state may not be consistent). If it fails with EAGAIN it was locked recursively too many times. There are other failure reasons, but in those cases, the lock has not been acquired.

int error = pthread_mutex_trylock(&lock);
if (error == 0) {
    /*... have the lock */
    pthread_mutex_unlock(&lock);
} else if (error == EBUSY) {
    /*... failed to get the lock because another thread holds lock */
} else if (error == EOWNERDEAD) {
    /*... got the lock, but the critical section state may not be consistent */
    if (make_state_consistent_succeeds()) {
        pthread_mutex_consistent(&lock);
        /*... things are good now */
        pthread_mutex_unlock(&lock);
    } else {
        /*... abort()? */
    }
} else {
    switch (error) {
    case EAGAIN: /*... recursively locked too many times */
    case EINVAL: /*... thread priority higher than mutex priority ceiling */
    case ENOTRECOVERABLE:
                 /*... mutex suffered EOWNERDEAD, and is no longer consistent */
    default:
        /*...some other as yet undocumented failure reason */
    }
}

The EAGAIN, EINVAL, ENOTRECOVERABLE, and EOWNERDEAD also happen with pthread_mutex_lock(). For more information, consult the documentation and man page.

like image 144
jxh Avatar answered Oct 23 '22 22:10

jxh