Provided by: manpages-posix-dev_2.16-1_all bug

NAME

       pthread_mutexattr_destroy, pthread_mutexattr_init - destroy and initialize the mutex attributes object

SYNOPSIS

       #include <pthread.h>

       int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
       int pthread_mutexattr_init(pthread_mutexattr_t *attr);

DESCRIPTION

       The  pthread_mutexattr_destroy() function shall destroy a mutex attributes object; the object becomes, in
       effect, uninitialized.  An  implementation  may  cause  pthread_mutexattr_destroy()  to  set  the  object
       referenced  by  attr  to  an invalid value. A destroyed attr attributes object can be reinitialized using
       pthread_mutexattr_init(); the results of otherwise referencing the object after it has been destroyed are
       undefined.

       The pthread_mutexattr_init() function shall initialize a mutex attributes object attr  with  the  default
       value for all of the attributes defined by the implementation.

       Results  are  undefined  if  pthread_mutexattr_init()  is  called  specifying an already initialized attr
       attributes object.

       After a mutex attributes object has been used to initialize one or more mutexes, any  function  affecting
       the attributes object (including destruction) shall not affect any previously initialized mutexes.

RETURN VALUE

       Upon  successful  completion, pthread_mutexattr_destroy() and pthread_mutexattr_init() shall return zero;
       otherwise, an error number shall be returned to indicate the error.

ERRORS

       The pthread_mutexattr_destroy() function may fail if:

       EINVAL The value specified by attr is invalid.

       The pthread_mutexattr_init() function shall fail if:

       ENOMEM Insufficient memory exists to initialize the mutex attributes object.

       These functions shall not return an error code of [EINTR].

       The following sections are informative.

EXAMPLES

       None.

APPLICATION USAGE

       None.

RATIONALE

       See  pthread_attr_init()  for  a  general  explanation   of   attributes.    Attributes   objects   allow
       implementations   to   experiment  with  useful  extensions  and  permit  extension  of  this  volume  of
       IEEE Std 1003.1-2001 without changing the existing functions. Thus, they provide for future extensibility
       of this volume of IEEE Std 1003.1-2001 and reduce the temptation to standardize prematurely on  semantics
       that are not yet widely implemented or understood.

       Examples  of  possible  additional mutex attributes that have been discussed are spin_only, limited_spin,
       no_spin, recursive, and metered. (To explain what the latter attributes  might  mean:  recursive  mutexes
       would  allow  for  multiple  re-locking  by  the  current owner; metered mutexes would transparently keep
       records of queue length, wait time, and so on.) Since there is not yet wide agreement on  the  usefulness
       of  these  resulting  from shared implementation and usage experience, they are not yet specified in this
       volume of IEEE Std 1003.1-2001.  Mutex attributes objects, however, make it possible to  test  out  these
       concepts for possible standardization at a later time.

   Mutex Attributes and Performance
       Care has been taken to ensure that the default values of the mutex attributes have been defined such that
       mutexes  initialized with the defaults have simple enough semantics so that the locking and unlocking can
       be done with the equivalent of a test-and-set instruction (plus possibly a few other basic instructions).

       There is at least one implementation method that can be used to reduce the cost of testing  at  lock-time
       if a mutex has non-default attributes. One such method that an implementation can employ (and this can be
       made  fully  transparent to fully conforming POSIX applications) is to secretly pre-lock any mutexes that
       are initialized  to  non-default  attributes.  Any  later  attempt  to  lock  such  a  mutex  causes  the
       implementation to branch to the "slow path" as if the mutex were unavailable; then, on the slow path, the
       implementation  can  do  the  "real work" to lock a non-default mutex. The underlying unlock operation is
       more complicated since the implementation never really wants to release the  pre-lock  on  this  kind  of
       mutex.  This  illustrates that, depending on the hardware, there may be certain optimizations that can be
       used so that whatever mutex attributes are considered  "most  frequently  used"  can  be  processed  most
       efficiently.

   Process Shared Memory and Synchronization
       The existence of memory mapping functions in this volume of IEEE Std 1003.1-2001 leads to the possibility
       that an application may allocate the synchronization objects from this section in memory that is accessed
       by multiple processes (and therefore, by threads of multiple processes).

       In  order  to  permit  such usage, while at the same time keeping the usual case (that is, usage within a
       single process) efficient, a process-shared option has been defined.

       If an implementation supports the _POSIX_THREAD_PROCESS_SHARED option, then the process-shared  attribute
       can  be  used  to  indicate  that  mutexes  or condition variables may be accessed by threads of multiple
       processes.

       The default setting of PTHREAD_PROCESS_PRIVATE has been chosen for the process-shared attribute  so  that
       the most efficient forms of these synchronization objects are created by default.

       Synchronization  variables that are initialized with the PTHREAD_PROCESS_PRIVATE process-shared attribute
       may only be operated on by threads in the process that initialized them. Synchronization  variables  that
       are initialized with the PTHREAD_PROCESS_SHARED process-shared attribute may be operated on by any thread
       in any process that has access to it. In particular, these processes may exist beyond the lifetime of the
       initializing  process. For example, the following code implements a simple counting semaphore in a mapped
       file that may be used by many processes.

              /* sem.h */
              struct semaphore {
                  pthread_mutex_t lock;
                  pthread_cond_t nonzero;
                  unsigned count;
              };
              typedef struct semaphore semaphore_t;

              semaphore_t *semaphore_create(char *semaphore_name);
              semaphore_t *semaphore_open(char *semaphore_name);
              void semaphore_post(semaphore_t *semap);
              void semaphore_wait(semaphore_t *semap);
              void semaphore_close(semaphore_t *semap);

              /* sem.c */
              #include <sys/types.h>
              #include <sys/stat.h>
              #include <sys/mman.h>
              #include <fcntl.h>
              #include <pthread.h>
              #include "sem.h"

              semaphore_t *
              semaphore_create(char *semaphore_name)
              {
              int fd;
                  semaphore_t *semap;
                  pthread_mutexattr_t psharedm;
                  pthread_condattr_t psharedc;

                  fd = open(semaphore_name, O_RDWR | O_CREAT | O_EXCL, 0666);
                  if (fd < 0)
                      return (NULL);
                  (void) ftruncate(fd, sizeof(semaphore_t));
                  (void) pthread_mutexattr_init(&psharedm);
                  (void) pthread_mutexattr_setpshared(&psharedm,
                      PTHREAD_PROCESS_SHARED);
                  (void) pthread_condattr_init(&psharedc);
                  (void) pthread_condattr_setpshared(&psharedc,
                      PTHREAD_PROCESS_SHARED);
                  semap = (semaphore_t *) mmap(NULL, sizeof(semaphore_t),
                          PROT_READ | PROT_WRITE, MAP_SHARED,
                          fd, 0);
                  close (fd);
                  (void) pthread_mutex_init(&semap->lock, &psharedm);
                  (void) pthread_cond_init(&semap->nonzero, &psharedc);
                  semap->count = 0;
                  return (semap);
              }

              semaphore_t *
              semaphore_open(char *semaphore_name)
              {
                  int fd;
                  semaphore_t *semap;

                  fd = open(semaphore_name, O_RDWR, 0666);
                  if (fd < 0)
                      return (NULL);
                  semap = (semaphore_t *) mmap(NULL, sizeof(semaphore_t),
                          PROT_READ | PROT_WRITE, MAP_SHARED,
                          fd, 0);
                  close (fd);
                  return (semap);
              }

              void
              semaphore_post(semaphore_t *semap)
              {
                  pthread_mutex_lock(&semap->lock);
                  if (semap->count == 0)
                      pthread_cond_signal(&semapx->nonzero);
                  semap->count++;
                  pthread_mutex_unlock(&semap->lock);
              }

              void
              semaphore_wait(semaphore_t *semap)
              {
                  pthread_mutex_lock(&semap->lock);
                  while (semap->count == 0)
                      pthread_cond_wait(&semap->nonzero, &semap->lock);
                  semap->count--;
                  pthread_mutex_unlock(&semap->lock);
              }

              void
              semaphore_close(semaphore_t *semap)
              {
                  munmap((void *) semap, sizeof(semaphore_t));
              }

       The following code is for three separate processes that create, post, and wait on a semaphore in the file
       /tmp/semaphore.  Once the file is created, the  post  and  wait  programs  increment  and  decrement  the
       counting semaphore (waiting and waking as required) even though they did not initialize the semaphore.

              /* create.c */
              #include "pthread.h"
              #include "sem.h"

              int
              main()
              {
                  semaphore_t *semap;

                  semap = semaphore_create("/tmp/semaphore");
                  if (semap == NULL)
                      exit(1);
                  semaphore_close(semap);
                  return (0);
              }

              /* post */
              #include "pthread.h"
              #include "sem.h"

              int
              main()
              {
                  semaphore_t *semap;

                  semap = semaphore_open("/tmp/semaphore");
                  if (semap == NULL)
                      exit(1);
                  semaphore_post(semap);
                  semaphore_close(semap);
                  return (0);
              }

              /* wait */
              #include "pthread.h"
              #include "sem.h"

              int
              main()
              {
                  semaphore_t *semap;

                  semap = semaphore_open("/tmp/semaphore");
                  if (semap == NULL)
                      exit(1);
                  semaphore_wait(semap);
                  semaphore_close(semap);
                  return (0);
              }

FUTURE DIRECTIONS

       None.

SEE ALSO

       pthread_cond_destroy()  ,  pthread_create()  ,  pthread_mutex_destroy() , pthread_mutexattr_destroy , the
       Base Definitions volume of IEEE Std 1003.1-2001, <pthread.h>

COPYRIGHT

       Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1, 2003 Edition,
       Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open  Group  Base
       Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of Electrical and Electronics Engineers,
       Inc  and  The  Open Group. In the event of any discrepancy between this version and the original IEEE and
       The Open Group Standard, the original IEEE and The Open Group  Standard  is  the  referee  document.  The
       original Standard can be obtained online at http://www.opengroup.org/unix/online.html .

IEEE/The Open Group                                   2003                          PTHREAD_MUTEXATTR_DESTROY(P)