From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 120371 invoked by alias); 26 Aug 2017 14:10:14 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Received: (qmail 116990 invoked by uid 89); 26 Aug 2017 14:10:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.0 required=5.0 tests=BAYES_00,DATE_IN_FUTURE_06_12,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=ALSO, renew, professionally, omissions X-HELO: mail-pf0-f182.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=6NYAy+Ot2jHevzjcOuEhKGG9IqUmPRDSHPvGAsOnEb0=; b=GrpiMWbrlv8BmVqFefIxn+bVp4YP1Mby5CxgmP8LwLdnk0JiweVAA3vXdkaxG8L5dP JMQDIuepdJWdm4akLk7+rNvowK3O76qPKkPVgTbVLPbeJiznQofEZcfDlllrJSY7X37x MW7eE5onENc/i84MT0sBfL+K9T3CmAJYWsnbu4nE5F1czvYv7ho3/iNmsmfvh1pDgYSY k7MqGlIPJquvWXXzyM6hG1qH8IOGCRH1QDY1HkXmvIcsZIvVPTJXgYP7YqlfHYiF1Sjw 2qTTfZZKozB1R9hxZnpaudAQBNcNDQ0FXAjmLPm9mzrJWvnsC33WuzOp7i+GGq6r2Rls 9L7g== X-Gm-Message-State: AHYfb5jbMs+cJSBGz522g+zPI7Na2TAftXNnLjg/bYIwr8LF9uuuAoQ5 Hlfchg5DK0GXuA== X-Received: by 10.84.177.131 with SMTP id x3mr2067493plb.280.1503756608377; Sat, 26 Aug 2017 07:10:08 -0700 (PDT) Date: Sat, 26 Aug 2017 14:10:00 -0000 From: Yubin Ruan To: "Michael Kerrisk (man-pages)" Cc: linux-man@vger.kernel.org, libc-alpha@sourceware.org Subject: Re: [PATCTH 0/2] pthread_mutexattr_setrobust() and pthread_mutex_consistent() Message-ID: <20170826210528.GA32472@HP.internal.baidu.com> References: <36ab9ec0-b496-c007-c12f-065fd618e7fd@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="ibTvN161/egqYuK8" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) X-SW-Source: 2017-08/txt/msg01175.txt.bz2 --ibTvN161/egqYuK8 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 11464 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) : > > 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 ". 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 --- 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 +.\" +.\" %%%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 +.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 +.\" +.\" %%%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 +.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 +#include +#include +#include + +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 --ibTvN161/egqYuK8 Content-Type: text/x-csrc; charset=us-ascii Content-Disposition: attachment; filename="verify_robustness.1.c" Content-length: 1319 /* * 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 #include #include #include 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; } --ibTvN161/egqYuK8 Content-Type: text/x-csrc; charset=us-ascii Content-Disposition: attachment; filename="verify_robustness.2.c" Content-length: 1421 /* * 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 #include #include #include 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; } --ibTvN161/egqYuK8 Content-Type: text/x-csrc; charset=us-ascii Content-Disposition: attachment; filename="verify_robustness.3.c" Content-length: 1772 /* * 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 #include #include #include 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; } --ibTvN161/egqYuK8--