PTHREAD_MUTEX_DESTROY(3)   POSIX Programmer's Manual  PTHREAD_MUTEX_DESTROY(3)



PPRROOLLOOGG
       This manual page is part of the POSIX Programmer's Manual.  The OS
       implementation of this interface may differ (consult the corresponding
       OS manual page for details of OS behavior), or the interface may not be
       implemented on OS.


NNAAMMEE
       pthread_mutex_destroy, pthread_mutex_init -- destroy and initialize a
       mutex

SSYYNNOOPPSSIISS
       #include <pthread.h>

       int pthread_mutex_destroy(pthread_mutex_t *_m_u_t_e_x);
       int pthread_mutex_init(pthread_mutex_t *restrict _m_u_t_e_x,
           const pthread_mutexattr_t *restrict _a_t_t_r);
       pthread_mutex_t _m_u_t_e_x = PTHREAD_MUTEX_INITIALIZER;

DDEESSCCRRIIPPTTIIOONN
       The _p_t_h_r_e_a_d___m_u_t_e_x___d_e_s_t_r_o_y() function shall destroy the mutex object
       referenced by _m_u_t_e_x; the mutex object becomes, in effect,
       uninitialized. An implementation may cause _p_t_h_r_e_a_d___m_u_t_e_x___d_e_s_t_r_o_y() to
       set the object referenced by _m_u_t_e_x to an invalid value.

       A destroyed mutex object can be reinitialized using
       _p_t_h_r_e_a_d___m_u_t_e_x___i_n_i_t(); the results of otherwise referencing the object
       after it has been destroyed are undefined.

       It shall be safe to destroy an initialized mutex that is unlocked.
       Attempting to destroy a locked mutex or a mutex that is referenced (for
       example, while being used in a _p_t_h_r_e_a_d___c_o_n_d___t_i_m_e_d_w_a_i_t() or
       _p_t_h_r_e_a_d___c_o_n_d___w_a_i_t()) by another thread results in undefined behavior.

       The _p_t_h_r_e_a_d___m_u_t_e_x___i_n_i_t() function shall initialize the mutex referenced
       by _m_u_t_e_x with attributes specified by _a_t_t_r.  If _a_t_t_r is NULL, the
       default mutex attributes are used; the effect shall be the same as
       passing the address of a default mutex attributes object. Upon
       successful initialization, the state of the mutex becomes initialized
       and unlocked.

       Only _m_u_t_e_x itself may be used for performing synchronization. The
       result of referring to copies of _m_u_t_e_x in calls to
       _p_t_h_r_e_a_d___m_u_t_e_x___l_o_c_k(), _p_t_h_r_e_a_d___m_u_t_e_x___t_r_y_l_o_c_k(), _p_t_h_r_e_a_d___m_u_t_e_x___u_n_l_o_c_k(),
       and _p_t_h_r_e_a_d___m_u_t_e_x___d_e_s_t_r_o_y() is undefined.

       Attempting to initialize an already initialized mutex results in
       undefined behavior.

       In cases where default mutex attributes are appropriate, the macro
       PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes. The effect
       shall be equivalent to dynamic initialization by a call to
       _p_t_h_r_e_a_d___m_u_t_e_x___i_n_i_t() with parameter _a_t_t_r specified as NULL, except that
       no error checks are performed.

       The behavior is undefined if the value specified by the _m_u_t_e_x argument
       to _p_t_h_r_e_a_d___m_u_t_e_x___d_e_s_t_r_o_y() does not refer to an initialized mutex.

       The behavior is undefined if the value specified by the _a_t_t_r argument
       to _p_t_h_r_e_a_d___m_u_t_e_x___i_n_i_t() does not refer to an initialized mutex
       attributes object.

RREETTUURRNN VVAALLUUEE
       If successful, the _p_t_h_r_e_a_d___m_u_t_e_x___d_e_s_t_r_o_y() and _p_t_h_r_e_a_d___m_u_t_e_x___i_n_i_t()
       functions shall return zero; otherwise, an error number shall be
       returned to indicate the error.

EERRRROORRSS
       The _p_t_h_r_e_a_d___m_u_t_e_x___i_n_i_t() function shall fail if:

       EEAAGGAAIINN The system lacked the necessary resources (other than memory) to
              initialize another mutex.

       EENNOOMMEEMM Insufficient memory exists to initialize the mutex.

       EEPPEERRMM  The caller does not have the privilege to perform the operation.

       The _p_t_h_r_e_a_d___m_u_t_e_x___i_n_i_t() function may fail if:

       EEIINNVVAALL The attributes object referenced by _a_t_t_r has the robust mutex
              attribute set without the process-shared attribute being set.

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

       _T_h_e _f_o_l_l_o_w_i_n_g _s_e_c_t_i_o_n_s _a_r_e _i_n_f_o_r_m_a_t_i_v_e_.

EEXXAAMMPPLLEESS
       None.

AAPPPPLLIICCAATTIIOONN UUSSAAGGEE
       None.

RRAATTIIOONNAALLEE
       If an implementation detects that the value specified by the _m_u_t_e_x
       argument to _p_t_h_r_e_a_d___m_u_t_e_x___d_e_s_t_r_o_y() does not refer to an initialized
       mutex, it is recommended that the function should fail and report an
       [[EEIINNVVAALL]] error.

       If an implementation detects that the value specified by the _m_u_t_e_x
       argument to _p_t_h_r_e_a_d___m_u_t_e_x___d_e_s_t_r_o_y() or _p_t_h_r_e_a_d___m_u_t_e_x___i_n_i_t() refers to a
       locked mutex or a mutex that is referenced (for example, while being
       used in a _p_t_h_r_e_a_d___c_o_n_d___t_i_m_e_d_w_a_i_t() or _p_t_h_r_e_a_d___c_o_n_d___w_a_i_t()) by another
       thread, or detects that the value specified by the _m_u_t_e_x argument to
       _p_t_h_r_e_a_d___m_u_t_e_x___i_n_i_t() refers to an already initialized mutex, it is
       recommended that the function should fail and report an [[EEBBUUSSYY]] error.

       If an implementation detects that the value specified by the _a_t_t_r
       argument to _p_t_h_r_e_a_d___m_u_t_e_x___i_n_i_t() does not refer to an initialized mutex
       attributes object, it is recommended that the function should fail and
       report an [[EEIINNVVAALL]] error.

   AAlltteerrnnaattee IImmpplleemmeennttaattiioonnss PPoossssiibbllee
       This volume of POSIX.1-2008 supports several alternative
       implementations of mutexes.  An implementation may store the lock
       directly in the object of type pptthhrreeaadd__mmuutteexx__tt.  Alternatively, an
       implementation may store the lock in the heap and merely store a
       pointer, handle, or unique ID in the mutex object.  Either
       implementation has advantages or may be required on certain hardware
       configurations. So that portable code can be written that is invariant
       to this choice, this volume of POSIX.1-2008 does not define assignment
       or equality for this type, and it uses the term ``initialize'' to
       reinforce the (more restrictive) notion that the lock may actually
       reside in the mutex object itself.

       Note that this precludes an over-specification of the type of the mutex
       or condition variable and motivates the opaqueness of the type.

       An implementation is permitted, but not required, to have
       _p_t_h_r_e_a_d___m_u_t_e_x___d_e_s_t_r_o_y() store an illegal value into the mutex. This may
       help detect erroneous programs that try to lock (or otherwise
       reference) a mutex that has already been destroyed.

   TTrraaddeeooffff BBeettwweeeenn EErrrroorr CChheecckkss aanndd PPeerrffoorrmmaannccee SSuuppppoorrtteedd
       Many error conditions that can occur are not required to be detected by
       the implementation in order to let implementations trade off
       performance _v_e_r_s_u_s degree of error checking according to the needs of
       their specific applications and execution environment. As a general
       rule, conditions caused by the system (such as insufficient memory) are
       required to be detected, but conditions caused by an erroneously coded
       application (such as failing to provide adequate synchronization to
       prevent a mutex from being deleted while in use) are specified to
       result in undefined behavior.

       A wide range of implementations is thus made possible. For example, an
       implementation intended for application debugging may implement all of
       the error checks, but an implementation running a single, provably
       correct application under very tight performance constraints in an
       embedded computer might implement minimal checks. An implementation
       might even be provided in two versions, similar to the options that
       compilers provide: a full-checking, but slower version; and a limited-
       checking, but faster version. To forbid this optionality would be a
       disservice to users.

       By carefully limiting the use of ``undefined behavior'' only to things
       that an erroneous (badly coded) application might do, and by defining
       that resource-not-available errors are mandatory, this volume of
       POSIX.1-2008 ensures that a fully-conforming application is portable
       across the full range of implementations, while not forcing all
       implementations to add overhead to check for numerous things that a
       correct program never does. When the behavior is undefined, no error
       number is specified to be returned on implementations that do detect
       the condition. This is because undefined behavior means _a_n_y_t_h_i_n_g can
       happen, which includes returning with any value (which might happen to
       be a valid, but different, error number). However, since the error
       number might be useful to application developers when diagnosing
       problems during application development, a recommendation is made in
       rationale that implementors should return a particular error number if
       their implementation does detect the condition.

   WWhhyy NNoo LLiimmiittss aarree DDeeffiinneedd
       Defining symbols for the maximum number of mutexes and condition
       variables was considered but rejected because the number of these
       objects may change dynamically. Furthermore, many implementations place
       these objects into application memory; thus, there is no explicit
       maximum.

   SSttaattiicc IInniittiiaalliizzeerrss ffoorr MMuutteexxeess aanndd CCoonnddiittiioonn VVaarriiaabblleess
       Providing for static initialization of statically allocated
       synchronization objects allows modules with private static
       synchronization variables to avoid runtime initialization tests and
       overhead. Furthermore, it simplifies the coding of self-initializing
       modules. Such modules are common in C libraries, where for various
       reasons the design calls for self-initialization instead of requiring
       an explicit module initialization function to be called. An example use
       of static initialization follows.

       Without static initialization, a self-initializing routine _f_o_o() might
       look as follows:

           ssttaattiicc pptthhrreeaadd__oonnccee__tt ffoooo__oonnccee == PPTTHHRREEAADD__OONNCCEE__IINNIITT;;
           ssttaattiicc pptthhrreeaadd__mmuutteexx__tt ffoooo__mmuutteexx;;

           void foo_init()
           {
               pthread_mutex_init(&foo_mutex, NULL);
           }

           void foo()
           {
               pthread_once(&foo_once, foo_init);
               pthread_mutex_lock(&foo_mutex);
              /* Do work. */
               pthread_mutex_unlock(&foo_mutex);
           }

       With static initialization, the same routine could be coded as follows:

           ssttaattiicc pptthhrreeaadd__mmuutteexx__tt ffoooo__mmuutteexx == PPTTHHRREEAADD__MMUUTTEEXX__IINNIITTIIAALLIIZZEERR;;

           void foo()
           {
               pthread_mutex_lock(&foo_mutex);
              /* Do work. */
               pthread_mutex_unlock(&foo_mutex);
           }

       Note that the static initialization both eliminates the need for the
       initialization test inside _p_t_h_r_e_a_d___o_n_c_e() and the fetch of &_f_o_o___m_u_t_e_x
       to learn the address to be passed to _p_t_h_r_e_a_d___m_u_t_e_x___l_o_c_k() or
       _p_t_h_r_e_a_d___m_u_t_e_x___u_n_l_o_c_k().

       Thus, the C code written to initialize static objects is simpler on all
       systems and is also faster on a large class of systems; those where the
       (entire) synchronization object can be stored in application memory.

       Yet the locking performance question is likely to be raised for
       machines that require mutexes to be allocated out of special memory.
       Such machines actually have to have mutexes and possibly condition
       variables contain pointers to the actual hardware locks. For static
       initialization to work on such machines, _p_t_h_r_e_a_d___m_u_t_e_x___l_o_c_k() also has
       to test whether or not the pointer to the actual lock has been
       allocated. If it has not, _p_t_h_r_e_a_d___m_u_t_e_x___l_o_c_k() has to initialize it
       before use. The reservation of such resources can be made when the
       program is loaded, and hence return codes have not been added to mutex
       locking and condition variable waiting to indicate failure to complete
       initialization.

       This runtime test in _p_t_h_r_e_a_d___m_u_t_e_x___l_o_c_k() would at first seem to be
       extra work; an extra test is required to see whether the pointer has
       been initialized. On most machines this would actually be implemented
       as a fetch of the pointer, testing the pointer against zero, and then
       using the pointer if it has already been initialized. While the test
       might seem to add extra work, the extra effort of testing a register is
       usually negligible since no extra memory references are actually done.
       As more and more machines provide caches, the real expenses are memory
       references, not instructions executed.

       Alternatively, depending on the machine architecture, there are often
       ways to eliminate _a_l_l overhead in the most important case: on the lock
       operations that occur _a_f_t_e_r the lock has been initialized. This can be
       done by shifting more overhead to the less frequent operation:
       initialization. Since out-of-line mutex allocation also means that an
       address has to be dereferenced to find the actual lock, one technique
       that is widely applicable is to have static initialization store a
       bogus value for that address; in particular, an address that causes a
       machine fault to occur. When such a fault occurs upon the first attempt
       to lock such a mutex, validity checks can be done, and then the correct
       address for the actual lock can be filled in. Subsequent lock
       operations incur no extra overhead since they do not ``fault''. This is
       merely one technique that can be used to support static initialization,
       while not adversely affecting the performance of lock acquisition. No
       doubt there are other techniques that are highly machine-dependent.

       The locking overhead for machines doing out-of-line mutex allocation is
       thus similar for modules being implicitly initialized, where it is
       improved for those doing mutex allocation entirely inline. The inline
       case is thus made much faster, and the out-of-line case is not
       significantly worse.

       Besides the issue of locking performance for such machines, a concern
       is raised that it is possible that threads would serialize contending
       for initialization locks when attempting to finish initializing
       statically allocated mutexes. (Such finishing would typically involve
       taking an internal lock, allocating a structure, storing a pointer to
       the structure in the mutex, and releasing the internal lock.) First,
       many implementations would reduce such serialization by hashing on the
       mutex address. Second, such serialization can only occur a bounded
       number of times. In particular, it can happen at most as many times as
       there are statically allocated synchronization objects. Dynamically
       allocated objects would still be initialized via _p_t_h_r_e_a_d___m_u_t_e_x___i_n_i_t()
       or _p_t_h_r_e_a_d___c_o_n_d___i_n_i_t().

       Finally, if none of the above optimization techniques for out-of-line
       allocation yields sufficient performance for an application on some
       implementation, the application can avoid static initialization
       altogether by explicitly initializing all synchronization objects with
       the corresponding _p_t_h_r_e_a_d___*___i_n_i_t() functions, which are supported by
       all implementations. An implementation can also document the tradeoffs
       and advise which initialization technique is more efficient for that
       particular implementation.

   DDeessttrrooyyiinngg MMuutteexxeess
       A mutex can be destroyed immediately after it is unlocked. For example,
       consider the following code:

           ssttrruucctt oobbjj {{
           pptthhrreeaadd__mmuutteexx__tt oomm;;
               iinntt rreeffccnntt;;
               ......
           }};;

           obj_done(struct obj *op)
           {
               pthread_mutex_lock(&op->om);
               if (--op->refcnt == 0) {
                   pthread_mutex_unlock(&op->om);
           (A)     pthread_mutex_destroy(&op->om);
           (B)     free(op);
               } else
           (C)     pthread_mutex_unlock(&op->om);
           }

       In this case _o_b_j is reference counted and _o_b_j___d_o_n_e() is called whenever
       a reference to the object is dropped.  Implementations are required to
       allow an object to be destroyed and freed and potentially unmapped (for
       example, lines A and B) immediately after the object is unlocked (line
       C).

   RRoobbuusstt MMuutteexxeess
       Implementations are required to provide robust mutexes for mutexes with
       the process-shared attribute set to PTHREAD_PROCESS_SHARED.
       Implementations are allowed, but not required, to provide robust
       mutexes when the process-shared attribute is set to
       PTHREAD_PROCESS_PRIVATE.

FFUUTTUURREE DDIIRREECCTTIIOONNSS
       None.

SSEEEE AALLSSOO
       _p_t_h_r_e_a_d___m_u_t_e_x___g_e_t_p_r_i_o_c_e_i_l_i_n_g(), _p_t_h_r_e_a_d___m_u_t_e_x_a_t_t_r___g_e_t_r_o_b_u_s_t(),
       _p_t_h_r_e_a_d___m_u_t_e_x___l_o_c_k(), _p_t_h_r_e_a_d___m_u_t_e_x___t_i_m_e_d_l_o_c_k(),
       _p_t_h_r_e_a_d___m_u_t_e_x_a_t_t_r___g_e_t_p_s_h_a_r_e_d()

       The Base Definitions volume of POSIX.1-2008, <<pptthhrreeaadd..hh>>

CCOOPPYYRRIIGGHHTT
       Portions of this text are reprinted and reproduced in electronic form
       from IEEE Std 1003.1, 2013 Edition, Standard for Information Technology
       -- Portable Operating System Interface (POSIX), The Open Group Base
       Specifications Issue 7, Copyright (C) 2013 by the Institute of
       Electrical and Electronics Engineers, Inc and The Open Group.  (This is
       POSIX.1-2008 with the 2013 Technical Corrigendum 1 applied.) 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.unix.org/online.html .

       Any typographical or formatting errors that appear in this page are
       most likely to have been introduced during the conversion of the source
       files to man page format. To report such errors, see
       https://www.kernel.org/doc/man-pages/reporting_bugs.html .



IEEE/The Open Group                  2013             PTHREAD_MUTEX_DESTROY(3)
