This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCTH 0/2] pthread_mutexattr_setrobust() and pthread_mutex_consistent()


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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]