This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCTH 0/2] pthread_mutexattr_setrobust() and pthread_mutex_consistent()
- From: Yubin Ruan <ablacktshirt at gmail dot com>
- To: "Michael Kerrisk (man-pages)" <mtk dot manpages at gmail dot com>
- Cc: linux-man at vger dot kernel dot org, libc-alpha at sourceware dot org
- Date: Sun, 27 Aug 2017 05:05:53 +0800
- Subject: Re: [PATCTH 0/2] pthread_mutexattr_setrobust() and pthread_mutex_consistent()
- Authentication-results: sourceware.org; auth=none
- References: <CAJYFCiMZN09HaHpvKgxz3mqzmcaXAWmkz=BmgOW9WVdRKOhDsg@mail.gmail.com> <36ab9ec0-b496-c007-c12f-065fd618e7fd@gmail.com> <CAJYFCiPM6Hy1cPF2mUBu5bVqxNX+5kvKnJZLhYzMMwuMiHCKeg@mail.gmail.com>
On Tue, Aug 22, 2017 at 10:19:48AM +0800, Yubin Ruan wrote:
> 2017-08-22 8:33 GMT+08:00 Michael Kerrisk (man-pages) <mtk.manpages@gmail.com>:
> > Hello Yubin
> >
> > On 08/20/2017 11:42 AM, Yubin Ruan wrote:
> >> Hi Michael,
> >> This patch series introduce three pthread functions for linux-man:
> >> * pthread_mutexattr_setrobust()
> >> * pthread_mutexattr_getrobust()
> >> * pthread_mutex_consistent()
> >>
> >> I put pthread_mutexattr_setrobust() and pthread_mutexattr_getrobust()
> >> altogether since they are related.
> >>
> >> I obtain my information about these functions mainly from reading the
> >> glibc source code and do some testing. There might be some mistake,
> >> but they are mostly correct (95% or so).
> >>
> >> Following this email would be those man pages in plain text and nroff
> >> format. I have tested those nroff file on my Linux box using man, and
> >> it look pretty well. Please point out if there are any mistake in
> >> formatting.
> >
> > Thanks for the drafts. Could I ask you to review the man-pages(7)
> > page. There's a number of details described in that page
> > which should be fixed in the drafts. Also, please try rendering
> > your pages with "man -l <page>". This will show problems with
> > the example code. See the chown(2) man page example for
> > the required escape sequences for "\n" and the single quote.
>
> No problem. I would fix the formatting issues.
Hi Michael,
Sorry that it took so long.
Following is the renew patch. I have corrected several formatting issues (i.e.,
\n , - , but I can't find anything wrong with ' ) and some typos. The only
issue I cannot solve is that the new `pthread_mutex_consistent(3)` page is too
short that it shows at the very bottom... please help with this.
Also, please find attached three verification snippets.
Signed-off-by: Yubin Ruan <ablacktshirt@gmail.com>
---
man3/pthread_mutex_consistent.3 | 60 +++++++++++
man3/pthread_mutexattr_setrobust.3 | 199 +++++++++++++++++++++++++++++++++++++
2 files changed, 259 insertions(+)
create mode 100644 man3/pthread_mutex_consistent.3
create mode 100644 man3/pthread_mutexattr_setrobust.3
diff --git a/man3/pthread_mutex_consistent.3 b/man3/pthread_mutex_consistent.3
new file mode 100644
index 0000000..6d5bc81
--- /dev/null
+++ b/man3/pthread_mutex_consistent.3
@@ -0,0 +1,60 @@
+.\" Copyright (c) 2017, Yubin Ruan <ablacktshirt@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 2017-08-20 "Linux" "Linux Programmer's Manual"
+.SH NAME
+pthread_mutex_consistent \- make the robust mutex consistent
+.SH SYNOPSIS
+.nf
+.B #include <pthread.h>
+.PP
+.BI "int pthread_mute_consistent(pthread_mute_t *" mutex ");"
+.fi
+.PP
+Compile and link with \fI\-pthread\fP.
+.SH DESCRIPTION
+This function make a robust mutex consistent if it is in a inconsistent
+state. A mutex can be left in a inconsistent state if its owner terminate
+while holding the mutex, in which situation the next owner who acquire the
+mutex will succeed and be notified by the return value of
+.B EOWNERDEAD.
+
+.SH RETURN VALUE
+On success,
+.IR pthread_mutex_consistent()
+return 0. Otherwise an error value is returned to indicate the error.
+
+.SH ERRORS
+.TP
+.B EINVAL
+The mutex is either not robust or it is not in a inconsistent state.
+
+.SH SEE ALSO
+.ad l
+.nh
+.BR pthread_mutexattr_init (3),
+.BR pthread_mutex_lock (3),
+.BR pthread_mutexattr_setrobust (3),
+.BR pthread_mutexattr_getrobust (3),
+.BR pthreads (7)
diff --git a/man3/pthread_mutexattr_setrobust.3 b/man3/pthread_mutexattr_setrobust.3
new file mode 100644
index 0000000..3add496
--- /dev/null
+++ b/man3/pthread_mutexattr_setrobust.3
@@ -0,0 +1,199 @@
+.\" Copyright (c) 2017, Yubin Ruan <ablacktshirt@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 2017-08-20 "Linux" "Linux Programmer's Manual"
+.SH NAME
+pthread_mutexattr_getrobust, pthread_mutexattr_setrobust,
+pthread_mutexattr_getrobust_np, pthread_mutexattr_setrobust_np
+\- get and set the robustness attribute of a mutex attribute object
+.SH SYNOPSIS
+.nf
+.B #include <pthread.h>
+.PP
+.BI "int pthread_mutexattr_getrobust(const pthread_mutexattr_t *" attr, "int *" robustness ");"
+.BI "int pthread_mutexattr_setrobust(const pthread_mutexattr_t *" attr, "int *" robustness ");"
+.BI "int pthread_mutexattr_getrobust_np(const pthread_mutexattr_t *" attr, "int *" robustness ");"
+.BI "int pthread_mutexattr_setrobust_np(const pthread_mutexattr_t *" attr, "int *" robustness ");"
+.fi
+.PP
+Compile and link with \fI\-pthread\fP.
+.SH DESCRIPTION
+The
+.BR pthread_mutexattr_getrobust()
+and
+.BR pthread_mutexattr_setrobust()
+functions get and set the robustness attribute of a
+initialized mutex attribute object, respectively.
+The robustness attribute specifies the behavior of the mutex
+when its owner dies without unlocking it. These two
+functions are specified in POSIX. Glibc's NPTL has
+.BR pthread_mutexattr_getrobust_np (3)
+and
+.BR pthread_mutexattr_setrobust_np (3)
+respectively but they are just aliases, with the "np" standing for "Native Posix".
+See
+.BR NPTL (7).
+.PP
+Currently there are only two possible values for the
+.IR robustness
+attribute:
+.TP
+.BR PTHREAD_MUTEX_STALLED
+is the default value for a mutex attribute object. If a mutex is initialized
+with a
+.BR PTHREAD_MUTEX_STALLED
+attribute object and its owner dies without unlocking it, it is kept locked
+afterwards and any future attempts to call
+.IR pthread_mutex_lock (3)
+on this mutex will block indefinitely.
+.TP
+.B PTHREAD_MUTEX_ROBUST
+can be set on a mutex attribute object so that when the owner of the mutex
+dies or when the process containing such a locked mutex performs
+.IR execve (2)
+, any future attempts to call
+.IR pthread_mutex_lock (3)
+on this mutex will suceed and return
+.B EOWNERDEAD
+to indicate that the original owner no longer exists and the mutex is left in
+an inconsistent state. Usually after
+.B EOWNERDEAD
+is returned, the next owner should call
+.IR pthread_mutex_consistent (3)
+on the acquired mutex to make it consistent again before using it any further.
+If the next owner unlock it using
+.IR pthread_mutex_unlock (3)
+before making it consistent, the mutex will be unusable permanently and any
+subsequent attempts to lock it using
+.IR pthread_mutex_lock (3)
+will return
+.B ENOTRECOVERABLE.
+If the next owner terminates before calling
+.IR pthread_mutex_consistent (3)
+, furture
+.IR pthread_mutex_lock (3)
+on this mutex will still return
+.B EOWNERDEAD.
+
+
+Glibc defines
+.B PTHREAD_MUTEX_STALLED_NP
+and
+.B PTHREAD_MUTEX_ROBUST_NP
+as aliases of
+.B PTHREAD_MUTEX_STALLED
+and
+.B PTHREAD_MUTEX_ROBUST
+respectively.
+
+Note that the
+.IR attr
+argument of
+.IR pthread_mutexattr_getrobust()
+and
+.IR pthread_mutexattr_setrobust()
+should refer to a mutex attribute object that was initialized by
+.IR pthread_mutexattr_init (3)
+, otherwise the behavior is undefined.
+.SH RETURN VALUE
+On success, zero is returned by
+.IR pthread_mutexattr_getrobust()
+and the value pointed to by the
+.IR robustness
+parameter is set to the robustness attribute of
+.IR attr.
+Otherwise, an error number shall be returned. On success
+.IR pthread_mutexattr_setrobust()
+set the robustness attribute into the mutex attribute object
+.IR attr
+and return zero, otherwise a error number is returned to indicate the error.
+.SS Glibc\-specificed features
+In glibc's implementation,
+.IR pthread_mutexattr_getrobust()
+always return zero.
+.SH ERRORS
+.TP
+.B EINVAL
+A value other than
+.B PTHREAD_MUTEX_STALLED
+or
+.B PTHREAD_MUTEX_ROBUST
+is passed into
+.IR pthread_mutexattr_setrobust().
+
+.SH EXAMPLE
+.PP
+The program demonstrate a simple usecase of the robustness attribute of a
+pthread mutex attribute object. In this program, a thread holding the mutex
+dies prematurely withough unlocking the mutex. Another thread acquires it
+successfully and get EOWNERDEAD.
+
+.SS Program source
+.EX
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+
+pthread_mutex_t lock;
+
+void *original_owner_thread(void *ptr)
+{
+ printf("[original owner] Setting lock...\\n");
+ pthread_mutex_lock(&lock);
+ printf("[original owner] Locked. Now exiting without unlocking.\\n");
+ pthread_exit(NULL);
+}
+
+int main(int argc, char *argv[])
+{
+ pthread_t lock_getter;
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr); /* initialize the attribute object */
+ pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST); /* set robustness */
+
+ pthread_mutex_init(&lock, &attr); /* initialize the lock */
+
+ pthread_create(&lock_getter, NULL, original_owner_thread, NULL);
+ sleep(2); /* original_owner_thread should have exited now */
+
+ printf("Attempting to acquire the unlocked robust mutex.\\n");
+ int ret_code = pthread_mutex_lock(&lock);
+ if(EOWNERDEAD == ret_code) {
+ printf("EOWNERDEAD returned. Make the mutex consistent now\\n");
+ pthread_mutex_consistent(&lock);
+ }
+
+ pthread_mutex_unlock(&lock);
+
+ return 0;
+}
+.EE
+.SH SEE ALSO
+.ad l
+.nh
+.BR pthread_mutex_init (3),
+.BR pthread_mutex_consistent (3),
+.BR pthread_mutex_lock (3)
+.BR pthreads (7)
--
2.7.4
/*
* This program is used to verify that when the owner of a robust lock exit
* prematurely without unlocking the mutex, the next owner will be successfully
* acquire the lock and get EOWNERDEAD returned.
*
* Compile and link with -pthread
*/
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
pthread_mutex_t lock;
void *original_owner_thread(void *ptr)
{
printf("[original owner] Setting lock...\n");
pthread_mutex_lock(&lock);
printf("[original owner] Locked. Now exiting without unlocking.\n");
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t lock_getter;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr); /* initialize the attribute object */
pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
pthread_mutex_init(&lock, &attr); /* initialize the lock */
pthread_create(&lock_getter, NULL, original_owner_thread, NULL);
sleep(2); /* original_owner_thread should have exited now */
printf("Attempting to acquire unlock robust mutex.\n");
int ret_code = pthread_mutex_lock(&lock);
if(EOWNERDEAD == ret_code) {
printf("EOWNERDEAD returned. Make the mutex consistent now\n");
pthread_mutex_consistent(&lock);
}
pthread_mutex_unlock(&lock);
return 0;
}
/*
* This program is used to verify that when the owner of a non-robust lock exit
* prematurely without unlocking the mutex, the next owner will be block
* indefintely.
*
* Compile and link with -pthread
*/
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
pthread_mutex_t lock;
void *original_owner_thread(void *ptr)
{
printf("[original owner] Setting lock...\n");
pthread_mutex_lock(&lock);
printf("[original owner] Locked. Now exiting without unlocking.\n");
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t lock_getter;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr); /* initialize the attribute object */
/* the following line can be commented out because PTHREAD_MUTEX_STALLED is
* the default value for a mutex attribute object */
pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_STALLED);
pthread_mutex_init(&lock, &attr); /* initialize the lock */
pthread_create(&lock_getter, NULL, original_owner_thread, NULL);
sleep(2); /* original_owner_thread should have exited now */
printf("Attempting to acquire unlock robust mutex.\n");
int ret_code = pthread_mutex_lock(&lock);
if(EOWNERDEAD == ret_code) {
printf("EOWNERDEAD returned. Make the mutex consistent now\n");
pthread_mutex_consistent(&lock);
}
pthread_mutex_unlock(&lock);
return 0;
}
/*
* This program is used to verify that when the owner of a robust mutex exit
* prematurely without unlocking the mutex, the next owner will be successfully
* acquire the mutex and get EOWNERDEAD returned. And, if that "next owner"
* unlock this mutex without making it consistent, it will be unusable
* permanently and any subsequent attempts to lock it using
* "pthread_mutex_lock(3)" with return ENORECOVERABLE.
*
* Compile and link with -pthread
*/
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
pthread_mutex_t lock;
void *original_owner_thread(void *ptr)
{
printf("[original owner] Setting lock...\n");
pthread_mutex_lock(&lock);
printf("[original owner] Locked. Now exiting without unlocking.\n");
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t lock_getter;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr); /* initialize the attribute object */
pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
pthread_mutex_init(&lock, &attr); /* initialize the lock */
pthread_create(&lock_getter, NULL, original_owner_thread, NULL);
sleep(2); /* original_owner_thread should have exited now */
int ret_code;
printf("Attempting to acquire unlock robust mutex.\n");
ret_code = pthread_mutex_lock(&lock);
if(EOWNERDEAD == ret_code) {
printf("EOWNERDEAD returned. Unlock the mutex without making it consistent.\n");
pthread_mutex_unlock(&lock);
}
/* try to acquire the lock again, and ENORECOVERABLE will be returned */
ret_code = pthread_mutex_lock(&lock);
if(ENOTRECOVERABLE == ret_code) {
printf("ENOTRECOVERABLE returned. This mutex is not recoverable now\n");
}
return 0;
}