pthread_mutex_timedlock_np()--Lock Mutex with Time-Out


  Syntax:
 #include <pthread.h>
 #include <time.h>
 int pthread_mutex_timedlock_np(pthread_mutex_t *mutex,   
				const struct timespec *deltatime);  
  Service Program Name: QP0WPTHR

  Default Public Authority: *USE

  Threadsafe: Yes

  Signal Safe: Yes

The pthread_mutex_timedlock_np() function acquires ownership of the mutex specified. If the mutex is currently locked by another thread, the call to pthread_mutex_timedlock_np() will block until the specified deltatime has elapsed or the holding thread relinquishes ownership by a call to pthread_mutex_unlock().

Performing a pthread_mutex_timedlock_np() wait for a mutex has different semantics related to signal handling than the pthread_mutex_lock() function. If a signal is delivered to a thread while that thread is performing a timed wait for a mutex, the signal is held pending until either the mutex is acquired or the time-out occurs. At that time the signal handler will run, when the signal handler returns, pthread_mutex_timedlock_np() will return the results of the timed mutex wait.

Use the CL command WRKJOB, option 20 for a screen that will aid in debugging mutex deadlocks.

Destroying a held mutex is a common way to serialize destruction of objects that are protected by that mutex, and is allowed. The call to pthread_mutex_timedlock_np() may fail with the EDESTROYED error if the mutex is destroyed by the thread that was currently holding it.

Note that mutex initialization using the PTHREAD_MUTEX_INITIALIZER does not immediately initialize the mutex. Instead, on first use, pthread_mutex_timedlock_np(), pthread_mutex_lock() or pthread_mutex_trylock() branches into a slow path and causes the initialization of the mutex. Because a mutex is not just a simple memory object, and requires that some resources be allocated by the system, an attempt to call pthread_mutex_destroy() or pthread_mutex_unlock() on a mutex that has was statically initialized using PTHREAD_MUTEX_INITIALIZER and was not yet locked will result in an EINVAL error.

A pthread mutex is a structure of type pthread_mutex_t that implement a behavior based on the Pthread mutexes. An MI mutex is a structure built into the machine that implement a similar sort of serialization construct.

The maximum number of recursive locks by the owning thread is 32,767. After which, attempts to lock the mutex will return the ERECURSE error.

Note: This function is not portable


Mutex Types

A normal mutex cannot be locked repeatedly by the owner. Attempts by a thread to relock an already held mutex, or to lock a mutex that was held by another thread when that thread terminated result in a deadlock condition.

A recursive mutex can be locked repeatedly by the owner. The mutex does not become unlocked until the owner has called pthread_mutex_unlock() for each successful lock request that it has outstanding on the mutex.

An errorcheck mutex checks for deadlock conditions that occur when a thread re-locks an already held mutex. If a thread attempts to relock a mutex that it already holds, the lock request fails with the EDEADLK error.

An ownerterm mutex is an IBM® i extension to the errorcheck mutex type. An ownerterm mutex checks for deadlock conditions that occur when a thread re-locks an already held mutex. If a thread attempts to relock a mutex that it already holds, the lock request fails with the EDEADLK error. An ownerterm mutex also checks for deadlock conditions that occur when a thread attempts to lock a mutex that was held by another thread when that thread terminated (an orphaned mutex). If a thread attempts to lock an orphaned mutex, the lock request fails with the EOWNERTERM error.

When a thread terminates while holding a mutex lock on a normal or errorcheck mutex, other threads that wait for that mutex will block forever, or until the specified deltatime has elapsed. The pthreads run-time simulates the deadlock that has occurred in your application. When attempting to debug these deadlock scenarios, the CL command WRKJOB, option 20 will show the thread as in a condition wait. Displaying the call stack will show that the function deadlockedOnOrphanedMutex or timedDeadlockOnOrphanedMutex is in the call stack.

When a thread attempts to acquire a normal mutex that it already holds, the thread will block forever, or until the specified deltatime has elapsed. The pthreads run-time simulates the deadlock that has occurred in your application. When attempting to debug these deadlock scenarios, the CL command WRKJOB, option 20 will show the thread as in a condition wait. Displaying the call stack will show that the function deadlockOnAlreadyHeldMutex or timedDeadlockOnAlreadyHeldMutex is in the call stack.

In order to change these behaviors, use an errorcheck or ownerterm mutex type.


Authorities and Locks

None.


Parameters

mutex
(Input) The address of the mutex to lock

Return Value

0
pthread_mutex_timedlock_np() was successful.
value
pthread_mutex_timedlock_np() was not successful. value is set to indicate the error condition.

Error Conditions

If pthread_mutex_timedlock_np() was not successful, the error condition returned usually indicates one of the following errors. Under some conditions, the value returned could indicate an error other than those listed here.

[EINVAL]

The value specified for the argument is not correct.

[EDESTROYED]

While waiting for the mutex lock to be satisfied, the mutex was destroyed.

[EBUSY]

The attempt to lock the mutex timed out because the mutex was already locked.

[EOWNERTERM]

A thread terminated holding the mutex, and the mutex is an ownerterm mutex type.

[EDEADLK]

A thread attempted to relock an already held mutex, and the mutex is an errorcheck mutex type.

[ERECURSE]

The recursive mutex cannot be recursively locked again.


Related Information


Example

Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.

#define _MULTI_THREADED
#include <pthread.h>
#include <stdio.h>
#include "check.h"

pthread_mutex_t    mutex = PTHREAD_MUTEX_INITIALIZER;

void *threadFunc(void *parm)
{
  int      rc;
  int      i;
  struct timespec deltatime;

  deltatime.tv_sec = 5;
  deltatime.tv_nsec = 0;

  printf("Timed lock the mutex from a secondary thread\n");
  rc = pthread_mutex_timedlock_np(&mutex, &deltatime);
  if (rc != EBUSY) {
     printf("Got an incorrect return code from pthread_mutex_timedlock_np\n");
  }
  printf("Thread mutex timeout\n");
  return 0;
}

int main(int argc, char **argv)
{
  int                   rc=0;
  pthread_t             thread;

  printf("Enter Testcase - %s\n", argv[0]);

  printf("Acquire the mutex in the initial thread\n");
  rc = pthread_mutex_lock(&mutex);
  checkResults("pthread_mutex_lock()\n", rc),

  printf("Create a thread\n");
  rc = pthread_create(&thread, NULL, threadFunc, NULL);
  checkResults("pthread_create()\n", rc);

  printf("Join to the thread\n");
  rc = pthread_join(thread, NULL);
  checkResults("pthread_join()\n", rc);

  printf("Destroy mutex\n");
  pthread_mutex_destroy(&mutex);

  printf("Main completed\n");
  return 0;
}

Output:

Enter Testcase - QP0WTEST/TPMTXTIM0
Acquire the mutex in the initial thread
Create a thread
Join to the thread
Timed lock the mutex from a secondary thread
Thread mutex timeout
Destroy mutex
Main completed

API introduced: V4R3

[ Back to top | Pthread APIs | APIs by category ]