mirror of https://github.com/mkerrisk/man-pages
285 lines
8.5 KiB
Groff
285 lines
8.5 KiB
Groff
.\" Copyright (c) 2017, Yubin Ruan <ablacktshirt@gmail.com>
|
|
.\" and Copyright (c) 2017, Michael Kerrisk <mtk.manpages@gmail.com>
|
|
.\"
|
|
.\" %%%LICENSE_START(VERBATIM)
|
|
.\" Permission is granted to make and distribute verbatim copies of this
|
|
.\" manual provided the copyright notice and this permission notice are
|
|
.\" preserved on all copies.
|
|
.\"
|
|
.\" Permission is granted to copy and distribute modified versions of this
|
|
.\" manual under the conditions for verbatim copying, provided that the
|
|
.\" entire resulting derived work is distributed under the terms of a
|
|
.\" permission notice identical to this one.
|
|
.\"
|
|
.\" Since the Linux kernel and libraries are constantly changing, this
|
|
.\" manual page may be incorrect or out-of-date. The author(s) assume no
|
|
.\" responsibility for errors or omissions, or for damages resulting from
|
|
.\" the use of the information contained herein. The author(s) may not
|
|
.\" have taken the same level of care in the production of this manual,
|
|
.\" which is licensed free of charge, as they might when working
|
|
.\" professionally.
|
|
.\"
|
|
.\" Formatted or processed versions of this manual, if unaccompanied by
|
|
.\" the source, must acknowledge the copyright and authors of this work.
|
|
.\" %%%LICENSE_END
|
|
.\"
|
|
.TH PTHREAD_MUTEXATTR_SETROBUST 3 2020-06-09 "Linux" "Linux Programmer's Manual"
|
|
.SH NAME
|
|
pthread_mutexattr_getrobust, pthread_mutexattr_setrobust
|
|
\- get and set the robustness attribute of a mutex attributes object
|
|
.SH SYNOPSIS
|
|
.nf
|
|
.B #include <pthread.h>
|
|
.PP
|
|
.BI "int pthread_mutexattr_getrobust(const pthread_mutexattr_t *" attr ,
|
|
.BI " int *" robustness ");"
|
|
.BI "int pthread_mutexattr_setrobust(const pthread_mutexattr_t *" attr ,
|
|
.BI " int " robustness ");"
|
|
.fi
|
|
.PP
|
|
Compile and link with \fI\-pthread\fP.
|
|
.PP
|
|
.in -4n
|
|
Feature Test Macro Requirements for glibc (see
|
|
.BR feature_test_macros (7)):
|
|
.in
|
|
.PP
|
|
.BR pthread_mutexattr_getrobust (),
|
|
.BR pthread_mutexattr_setrobust ():
|
|
.br
|
|
.RS 4
|
|
.ad l
|
|
_POSIX_C_SOURCE >= 200809L
|
|
.\" FIXME .
|
|
.\" But see https://sourceware.org/bugzilla/show_bug.cgi?id=22125
|
|
.RE
|
|
.ad
|
|
.SH DESCRIPTION
|
|
The
|
|
.BR pthread_mutexattr_getrobust ()
|
|
function places the value of the robustness attribute of
|
|
the mutex attributes object referred to by
|
|
.I attr
|
|
in
|
|
.IR *robustness .
|
|
The
|
|
.BR pthread_mutexattr_setrobust ()
|
|
function sets the value of the robustness attribute of
|
|
the mutex attributes object referred to by
|
|
.I attr
|
|
to the value specified in
|
|
.IR *robustness .
|
|
.PP
|
|
The robustness attribute specifies the behavior of the mutex when
|
|
the owning thread dies without unlocking the mutex.
|
|
The following values are valid for
|
|
.IR robustness :
|
|
.TP
|
|
.BR PTHREAD_MUTEX_STALLED
|
|
This is the default value for a mutex attributes object.
|
|
If a mutex is initialized with the
|
|
.BR PTHREAD_MUTEX_STALLED
|
|
attribute and its owner dies without unlocking it,
|
|
the mutex remains locked afterwards and any future attempts to call
|
|
.BR pthread_mutex_lock (3)
|
|
on the mutex will block indefinitely.
|
|
.TP
|
|
.B PTHREAD_MUTEX_ROBUST
|
|
If a mutex is initialized with the
|
|
.BR PTHREAD_MUTEX_ROBUST
|
|
attribute and its owner dies without unlocking it,
|
|
any future attempts to call
|
|
.BR pthread_mutex_lock (3)
|
|
on this mutex will succeed and return
|
|
.B EOWNERDEAD
|
|
to indicate that the original owner no longer exists and the mutex is in
|
|
an inconsistent state.
|
|
Usually after
|
|
.B EOWNERDEAD
|
|
is returned, the next owner should call
|
|
.BR pthread_mutex_consistent (3)
|
|
on the acquired mutex to make it consistent again before using it any further.
|
|
.IP
|
|
If the next owner unlocks the mutex using
|
|
.BR pthread_mutex_unlock (3)
|
|
before making it consistent, the mutex will be permanently unusable and any
|
|
subsequent attempts to lock it using
|
|
.BR pthread_mutex_lock (3)
|
|
will fail with the error
|
|
.BR ENOTRECOVERABLE .
|
|
The only permitted operation on such a mutex is
|
|
.BR pthread_mutex_destroy (3).
|
|
.IP
|
|
If the next owner terminates before calling
|
|
.BR pthread_mutex_consistent (3),
|
|
further
|
|
.BR pthread_mutex_lock (3)
|
|
operations on this mutex will still return
|
|
.BR EOWNERDEAD .
|
|
.PP
|
|
Note that the
|
|
.IR attr
|
|
argument of
|
|
.BR pthread_mutexattr_getrobust ()
|
|
and
|
|
.BR pthread_mutexattr_setrobust ()
|
|
should refer to a mutex attributes object that was initialized by
|
|
.BR pthread_mutexattr_init (3),
|
|
otherwise the behavior is undefined.
|
|
.SH RETURN VALUE
|
|
On success, these functions return 0.
|
|
On error, they return a positive error number.
|
|
.PP
|
|
In the glibc implementation,
|
|
.BR pthread_mutexattr_getrobust ()
|
|
always return zero.
|
|
.SH ERRORS
|
|
.TP
|
|
.B EINVAL
|
|
A value other than
|
|
.B PTHREAD_MUTEX_STALLED
|
|
or
|
|
.B PTHREAD_MUTEX_ROBUST
|
|
was passed to
|
|
.BR pthread_mutexattr_setrobust ().
|
|
.SH VERSIONS
|
|
.BR pthread_mutexattr_getrobust ()
|
|
and
|
|
.BR pthread_mutexattr_setrobust ()
|
|
were added to glibc in version 2.12.
|
|
.SH CONFORMING TO
|
|
POSIX.1-2008.
|
|
.SH NOTES
|
|
In the Linux implementation,
|
|
when using process-shared robust mutexes, a waiting thread also receives the
|
|
.B EOWNERDEAD
|
|
notification if the owner of a robust mutex performs an
|
|
.BR execve (2)
|
|
without first unlocking the mutex.
|
|
POSIX.1 does not specify this detail,
|
|
but the same behavior also occurs in at least some
|
|
.\" E.g., Solaris, according to its manual page
|
|
other implementations.
|
|
.PP
|
|
Before the addition of
|
|
.BR pthread_mutexattr_getrobust ()
|
|
and
|
|
.BR pthread_mutexattr_setrobust ()
|
|
to POSIX,
|
|
glibc defined the following equivalent nonstandard functions if
|
|
.BR _GNU_SOURCE
|
|
was defined:
|
|
.PP
|
|
.nf
|
|
.BI "int pthread_mutexattr_getrobust_np(const pthread_mutexattr_t *" attr ,
|
|
.BI " int *" robustness ");"
|
|
.BI "int pthread_mutexattr_setrobust_np(const pthread_mutexattr_t *" attr ,
|
|
.BI " int " robustness ");"
|
|
.fi
|
|
.PP
|
|
Correspondingly, the constants
|
|
.B PTHREAD_MUTEX_STALLED_NP
|
|
and
|
|
.B PTHREAD_MUTEX_ROBUST_NP
|
|
were also defined.
|
|
.PP
|
|
These GNU-specific APIs, which first appeared in glibc 2.4,
|
|
are nowadays obsolete and should not be used in new programs.
|
|
.SH EXAMPLES
|
|
The program below demonstrates the use of the robustness attribute of a
|
|
mutex attributes object.
|
|
In this program, a thread holding the mutex
|
|
dies prematurely without unlocking the mutex.
|
|
The main thread subsequently acquires the mutex
|
|
successfully and gets the error
|
|
.BR EOWNERDEAD ,
|
|
after which it makes the mutex consistent.
|
|
.PP
|
|
The following shell session shows what we see when running this program:
|
|
.PP
|
|
.in +4n
|
|
.EX
|
|
$ \fB./a.out\fP
|
|
[original owner] Setting lock...
|
|
[original owner] Locked. Now exiting without unlocking.
|
|
[main thread] Attempting to lock the robust mutex.
|
|
[main thread] pthread_mutex_lock() returned EOWNERDEAD
|
|
[main thread] Now make the mutex consistent
|
|
[main thread] Mutex is now consistent; unlocking
|
|
.EE
|
|
.in
|
|
.SS Program source
|
|
.EX
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <pthread.h>
|
|
#include <errno.h>
|
|
|
|
#define handle_error_en(en, msg) \e
|
|
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
|
|
|
|
static pthread_mutex_t mtx;
|
|
|
|
static void *
|
|
original_owner_thread(void *ptr)
|
|
{
|
|
printf("[original owner] Setting lock...\en");
|
|
pthread_mutex_lock(&mtx);
|
|
printf("[original owner] Locked. Now exiting without unlocking.\en");
|
|
pthread_exit(NULL);
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
pthread_t thr;
|
|
pthread_mutexattr_t attr;
|
|
int s;
|
|
|
|
pthread_mutexattr_init(&attr);
|
|
/* initialize the attributes object */
|
|
pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
|
|
/* set robustness */
|
|
|
|
pthread_mutex_init(&mtx, &attr); /* initialize the mutex */
|
|
|
|
pthread_create(&thr, NULL, original_owner_thread, NULL);
|
|
|
|
sleep(2);
|
|
|
|
/* "original_owner_thread" should have exited by now */
|
|
|
|
printf("[main thread] Attempting to lock the robust mutex.\en");
|
|
s = pthread_mutex_lock(&mtx);
|
|
if (s == EOWNERDEAD) {
|
|
printf("[main thread] pthread_mutex_lock() returned EOWNERDEAD\en");
|
|
printf("[main thread] Now make the mutex consistent\en");
|
|
s = pthread_mutex_consistent(&mtx);
|
|
if (s != 0)
|
|
handle_error_en(s, "pthread_mutex_consistent");
|
|
printf("[main thread] Mutex is now consistent; unlocking\en");
|
|
s = pthread_mutex_unlock(&mtx);
|
|
if (s != 0)
|
|
handle_error_en(s, "pthread_mutex_unlock");
|
|
|
|
exit(EXIT_SUCCESS);
|
|
} else if (s == 0) {
|
|
printf("[main thread] pthread_mutex_lock() unexpectedly succeeded\en");
|
|
exit(EXIT_FAILURE);
|
|
} else {
|
|
printf("[main thread] pthread_mutex_lock() unexpectedly failed\en");
|
|
handle_error_en(s, "pthread_mutex_lock");
|
|
}
|
|
}
|
|
.EE
|
|
.SH SEE ALSO
|
|
.ad l
|
|
.nh
|
|
.BR get_robust_list (2),
|
|
.BR set_robust_list (2),
|
|
.BR pthread_mutex_consistent (3),
|
|
.BR pthread_mutex_init (3),
|
|
.BR pthread_mutex_lock (3),
|
|
.BR pthreads (7)
|