From owner-freebsd-threads@FreeBSD.ORG Mon Aug 16 03:53:53 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 29C2110656A3 for ; Mon, 16 Aug 2010 03:53:53 +0000 (UTC) (envelope-from davidxu@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 14E2C8FC13; Mon, 16 Aug 2010 03:53:53 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o7G3rpC2000324; Mon, 16 Aug 2010 03:53:52 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C6926D0.2020909@freebsd.org> Date: Mon, 16 Aug 2010 11:53:52 +0000 From: David Xu User-Agent: Thunderbird 2.0.0.24 (X11/20100630) MIME-Version: 1.0 To: Kostik Belousov References: <20100811204758.GQ2396@deviant.kiev.zoral.com.ua> <4C63D42D.8040606@freebsd.org> <20100812083006.GR2396@deviant.kiev.zoral.com.ua> <4C642E9B.8000300@freebsd.org> <20100812093353.GS2396@deviant.kiev.zoral.com.ua> <4C650D0F.9060905@freebsd.org> <4C650F27.1000305@freebsd.org> <20100813141402.GW2396@deviant.kiev.zoral.com.ua> <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> In-Reply-To: <20100814144715.GB2396@deviant.kiev.zoral.com.ua> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Aug 2010 03:53:53 -0000 Kostik Belousov wrote: > Missed this, thank you for pointing it out. Updated patch is at > http://people.freebsd.org/~kib//misc/cancel_defer.2.patch I found SIGCANCEL is masked by thr_cancel_deferred(THR_CANCEL_DEFERRED_ENABLE), issignal() does not return the masked signal, so how a cancellation point syscall can be interrupted by SIGCANCEL ? I think if a thread being canceled calls msleep(PCATCH), it should find the signal and return EINTR. From owner-freebsd-threads@FreeBSD.ORG Mon Aug 16 08:20:27 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 44A1110656A4; Mon, 16 Aug 2010 08:20:27 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id B14868FC1F; Mon, 16 Aug 2010 08:20:26 +0000 (UTC) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id o7G8KMZm056677 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 16 Aug 2010 11:20:22 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4) with ESMTP id o7G8KMgM025674; Mon, 16 Aug 2010 11:20:22 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4/Submit) id o7G8KMlE025673; Mon, 16 Aug 2010 11:20:22 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Mon, 16 Aug 2010 11:20:22 +0300 From: Kostik Belousov To: David Xu Message-ID: <20100816082022.GO2396@deviant.kiev.zoral.com.ua> References: <4C63D42D.8040606@freebsd.org> <20100812083006.GR2396@deviant.kiev.zoral.com.ua> <4C642E9B.8000300@freebsd.org> <20100812093353.GS2396@deviant.kiev.zoral.com.ua> <4C650D0F.9060905@freebsd.org> <4C650F27.1000305@freebsd.org> <20100813141402.GW2396@deviant.kiev.zoral.com.ua> <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> <4C6926D0.2020909@freebsd.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="dDdTYOCAbkFo0FQC" Content-Disposition: inline In-Reply-To: <4C6926D0.2020909@freebsd.org> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-3.5 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00, DNS_FROM_OPENWHOIS autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Aug 2010 08:20:27 -0000 --dDdTYOCAbkFo0FQC Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Aug 16, 2010 at 11:53:52AM +0000, David Xu wrote: > Kostik Belousov wrote: >=20 > >Missed this, thank you for pointing it out. Updated patch is at > >http://people.freebsd.org/~kib//misc/cancel_defer.2.patch >=20 > I found SIGCANCEL is masked by > thr_cancel_deferred(THR_CANCEL_DEFERRED_ENABLE), issignal() does not > return the masked signal, so how a cancellation point syscall can be > interrupted by SIGCANCEL ? I think if a thread being canceled calls > msleep(PCATCH), it should find the signal and return EINTR. >=20 Yes, for EINTR and ERESTART case, the thread should be canceled. Please look at the check_cancel() helper that is called at the syscall entry and before return. If the check_cancel() decided that the syscall is cancellation point and the thread in the deferred cancel mode, and EINTR or ERESTART is supplied as error code, then SIGCANCEL is removed from the thread signal mask. It is restored in the mask by ast(). --dDdTYOCAbkFo0FQC Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkxo9MYACgkQC3+MBN1Mb4jAWQCdEG8Xj3rfSPgmIi1j3sDDpW5R Fq8AoPY7vH6ph1gGyZHMkVey7BePOFLe =hWdZ -----END PGP SIGNATURE----- --dDdTYOCAbkFo0FQC-- From owner-freebsd-threads@FreeBSD.ORG Mon Aug 16 08:43:03 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0031C106566C for ; Mon, 16 Aug 2010 08:43:02 +0000 (UTC) (envelope-from davidxu@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id C3E748FC14; Mon, 16 Aug 2010 08:43:02 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o7G8h1ha019142; Mon, 16 Aug 2010 08:43:01 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C696A96.7020709@freebsd.org> Date: Mon, 16 Aug 2010 16:43:02 +0000 From: David Xu User-Agent: Thunderbird 2.0.0.24 (X11/20100630) MIME-Version: 1.0 To: Kostik Belousov References: <4C63D42D.8040606@freebsd.org> <20100812083006.GR2396@deviant.kiev.zoral.com.ua> <4C642E9B.8000300@freebsd.org> <20100812093353.GS2396@deviant.kiev.zoral.com.ua> <4C650D0F.9060905@freebsd.org> <4C650F27.1000305@freebsd.org> <20100813141402.GW2396@deviant.kiev.zoral.com.ua> <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> In-Reply-To: <20100816082022.GO2396@deviant.kiev.zoral.com.ua> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Aug 2010 08:43:03 -0000 Kostik Belousov wrote: > On Mon, Aug 16, 2010 at 11:53:52AM +0000, David Xu wrote: >> Kostik Belousov wrote: >> >>> Missed this, thank you for pointing it out. Updated patch is at >>> http://people.freebsd.org/~kib//misc/cancel_defer.2.patch >> I found SIGCANCEL is masked by >> thr_cancel_deferred(THR_CANCEL_DEFERRED_ENABLE), issignal() does not >> return the masked signal, so how a cancellation point syscall can be >> interrupted by SIGCANCEL ? I think if a thread being canceled calls >> msleep(PCATCH), it should find the signal and return EINTR. >> > Yes, for EINTR and ERESTART case, the thread should be canceled. > Please look at the check_cancel() helper that is called at the syscall > entry and before return. If the check_cancel() decided that the syscall > is cancellation point and the thread in the deferred cancel mode, and > EINTR or ERESTART is supplied as error code, then SIGCANCEL is removed > from the thread signal mask. It is restored in the mask by ast(). I saw your patch has following lines, on syscall entry, if the check_cancel finds that the syscall is cancellation point and SIGCANCEL exists, it returns non-zero value, then the real syscall body at line 319 of subr_trap.c is not executed and prematurely returns. This is not what I want,as you said the syscall's implementation should always be executed, and if the thread will be blocked, then it should be interrupted by existing SIGCANCEL via issignal() which is called by sleepqueue routines. I think the current patch also has potential performance problem, the check_cancel uses PROC_LOCK, which might be a performance hit. @@ -300,6 +332,9 @@ syscallenter(struct thread *td, struct syscall_args *sa) if (error != 0) goto retval; } + error = check_cancel(td, sa->callp, EINTR); + if (error != 0) + goto retval; error = syscall_thread_enter(td, sa->callp); if (error != 0) goto retval; From owner-freebsd-threads@FreeBSD.ORG Mon Aug 16 10:43:08 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 88D0510656AC; Mon, 16 Aug 2010 10:43:08 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id 24E598FC26; Mon, 16 Aug 2010 10:43:07 +0000 (UTC) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id o7GAh3fX068565 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 16 Aug 2010 13:43:04 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4) with ESMTP id o7GAh3Tn026462; Mon, 16 Aug 2010 13:43:03 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4/Submit) id o7GAh3YA026461; Mon, 16 Aug 2010 13:43:03 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Mon, 16 Aug 2010 13:43:03 +0300 From: Kostik Belousov To: David Xu Message-ID: <20100816104303.GP2396@deviant.kiev.zoral.com.ua> References: <4C642E9B.8000300@freebsd.org> <20100812093353.GS2396@deviant.kiev.zoral.com.ua> <4C650D0F.9060905@freebsd.org> <4C650F27.1000305@freebsd.org> <20100813141402.GW2396@deviant.kiev.zoral.com.ua> <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> <4C696A96.7020709@freebsd.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="eUGqGfkt69yEwRle" Content-Disposition: inline In-Reply-To: <4C696A96.7020709@freebsd.org> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-2.2 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_50, DNS_FROM_OPENWHOIS autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Aug 2010 10:43:08 -0000 --eUGqGfkt69yEwRle Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Aug 16, 2010 at 04:43:02PM +0000, David Xu wrote: > Kostik Belousov wrote: > >On Mon, Aug 16, 2010 at 11:53:52AM +0000, David Xu wrote: > >>Kostik Belousov wrote: > >> > >>>Missed this, thank you for pointing it out. Updated patch is at > >>>http://people.freebsd.org/~kib//misc/cancel_defer.2.patch > >>I found SIGCANCEL is masked by > >>thr_cancel_deferred(THR_CANCEL_DEFERRED_ENABLE), issignal() does not > >>return the masked signal, so how a cancellation point syscall can be > >>interrupted by SIGCANCEL ? I think if a thread being canceled calls > >>msleep(PCATCH), it should find the signal and return EINTR. > >> > >Yes, for EINTR and ERESTART case, the thread should be canceled. > >Please look at the check_cancel() helper that is called at the syscall > >entry and before return. If the check_cancel() decided that the syscall > >is cancellation point and the thread in the deferred cancel mode, and > >EINTR or ERESTART is supplied as error code, then SIGCANCEL is removed > >from the thread signal mask. It is restored in the mask by ast(). >=20 > I saw your patch has following lines, on syscall entry, if the > check_cancel finds that the syscall is cancellation point and > SIGCANCEL exists, it returns non-zero value, then the real syscall > body at line 319 of subr_trap.c is not executed and prematurely returns. > This is not what I want,as you said the syscall's implementation should > always be executed, and if the thread will be blocked, then it should be > interrupted by existing SIGCANCEL via issignal() which is called by > sleepqueue routines. I think the current patch also has potential=20 No, I do not think what you describe is completely right behaviour. As I understand SUSv4, the deferred cancel behaviour should be as following: - when we reach cancellation point with cancel already pending, the syscall should not be executed at all, cancel happens and cleanup handlers executed before thread exiting. - when we reach cancellation point without cancel pending, and syscall goes to sleep, and cancellation request arrives during the sleep, again the syscall should be aborted, and cancellation happens. So I check for the cancellation at two points: one is the syscall entry, to catch already pending cancellation request. Second is on the syscall exit path, where cancellation is only checked in the case the sleep was aborted. > performance problem, the check_cancel uses PROC_LOCK, which might be a=20 > performance hit. Might be. Lets first make sure that the semantic is right. >=20 > @@ -300,6 +332,9 @@ syscallenter(struct thread *td, struct syscall_args *= sa) > if (error !=3D 0) > goto retval; > } > + error =3D check_cancel(td, sa->callp, EINTR); > + if (error !=3D 0) > + goto retval; > error =3D syscall_thread_enter(td, sa->callp); > if (error !=3D 0) > goto retval; >=20 --eUGqGfkt69yEwRle Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkxpFjcACgkQC3+MBN1Mb4hCawCfclQJULuAgsYI/SKyNkpbx/VK JrYAmgO98aEv0Jydq/ETSdd3IDL0wAe/ =59mj -----END PGP SIGNATURE----- --eUGqGfkt69yEwRle-- From owner-freebsd-threads@FreeBSD.ORG Mon Aug 16 11:07:10 2010 Return-Path: Delivered-To: freebsd-threads@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9444110656A5 for ; Mon, 16 Aug 2010 11:07:10 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 778D48FC23 for ; Mon, 16 Aug 2010 11:07:10 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o7GB7AJp059036 for ; Mon, 16 Aug 2010 11:07:10 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o7GB7972059034 for freebsd-threads@FreeBSD.org; Mon, 16 Aug 2010 11:07:09 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 16 Aug 2010 11:07:09 GMT Message-Id: <201008161107.o7GB7972059034@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: gnats set sender to owner-bugmaster@FreeBSD.org using -f From: FreeBSD bugmaster To: freebsd-threads@FreeBSD.org Cc: Subject: Current problem reports assigned to freebsd-threads@FreeBSD.org X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Aug 2010 11:07:10 -0000 Note: to view an individual PR, use: http://www.freebsd.org/cgi/query-pr.cgi?pr=(number). The following is a listing of current problems submitted by FreeBSD users. These represent problem reports covering all versions including experimental development code and obsolete releases. S Tracker Resp. Description -------------------------------------------------------------------------------- o threa/149366 threads pthread_cleanup_pop never runs the configured routine o threa/148515 threads Memory / syslog strangeness in FreeBSD 8.x ( possible o threa/141721 threads rtprio(1): (id|rt)prio priority resets when new thread o threa/141198 threads [libc] src/lib/libc/stdio does not properly initialize o threa/136345 threads Recursive read rwlocks in thread A cause deadlock with o threa/135673 threads databases/mysql50-server - MySQL query lock-ups on 7.2 o threa/133734 threads 32 bit libthr failing pthread_create() o threa/128922 threads threads hang with xorg running o threa/127225 threads bug in lib/libthr/thread/thr_init.c o threa/122923 threads 'nice' does not prevent background process from steali o threa/121336 threads lang/neko threading ok on UP, broken on SMP (FreeBSD 7 o threa/116668 threads can no longer use jdk15 with libthr on -stable SMP o threa/116181 threads /dev/io-related io access permissions are not propagat o threa/115211 threads pthread_atfork misbehaves in initial thread o threa/110636 threads [request] gdb(1): using gdb with multi thread applicat o threa/110306 threads apache 2.0 segmentation violation when calling gethost o threa/103975 threads Implicit loading/unloading of libpthread.so may crash o threa/101323 threads [patch] fork(2) in threaded programs broken. s threa/100815 threads FBSD 5.5 broke nanosleep in libc_r s threa/94467 threads send(), sendto() and sendmsg() are not correct in libc s threa/84483 threads problems with devel/nspr and -lc_r on 4.x o threa/80992 threads abort() sometimes not caught by gdb depending on threa o threa/79887 threads [patch] freopen() isn't thread-safe o threa/79683 threads svctcp_create() fails if multiple threads call at the s threa/76694 threads fork cause hang in dup()/close() function in child (-l s threa/76690 threads fork hang in child for -lc_r s threa/69020 threads pthreads library leaks _gc_mutex s threa/49087 threads Signals lost in programs linked with libc_r s threa/48856 threads Setting SIGCHLD to SIG_IGN still leaves zombies under s threa/40671 threads pthread_cancel doesn't remove thread from condition qu s threa/39922 threads [threads] [patch] Threaded applications executed with s threa/37676 threads libc_r: msgsnd(), msgrcv(), pread(), pwrite() need wra s threa/34536 threads accept() blocks other threads s threa/32295 threads [libc_r] [patch] pthread(3) dont dequeue signals s threa/30464 threads pthread mutex attributes -- pshared s threa/24632 threads libc_r delicate deviation from libc in handling SIGCHL s threa/24472 threads libc_r does not honor SO_SNDTIMEO/SO_RCVTIMEO socket o 37 problems total. From owner-freebsd-threads@FreeBSD.ORG Tue Aug 17 01:29:53 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8C4F81065697 for ; Tue, 17 Aug 2010 01:29:53 +0000 (UTC) (envelope-from davidxu@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 5B4298FC19; Tue, 17 Aug 2010 01:29:53 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o7H1TpK6006345; Tue, 17 Aug 2010 01:29:52 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C6A5690.6060000@freebsd.org> Date: Tue, 17 Aug 2010 09:29:52 +0000 From: David Xu User-Agent: Thunderbird 2.0.0.24 (X11/20100630) MIME-Version: 1.0 To: Kostik Belousov References: <4C642E9B.8000300@freebsd.org> <20100812093353.GS2396@deviant.kiev.zoral.com.ua> <4C650D0F.9060905@freebsd.org> <4C650F27.1000305@freebsd.org> <20100813141402.GW2396@deviant.kiev.zoral.com.ua> <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> In-Reply-To: <20100816104303.GP2396@deviant.kiev.zoral.com.ua> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Aug 2010 01:29:53 -0000 Kostik Belousov wrote: > On Mon, Aug 16, 2010 at 04:43:02PM +0000, David Xu wrote: >> Kostik Belousov wrote: >>> On Mon, Aug 16, 2010 at 11:53:52AM +0000, David Xu wrote: >>>> Kostik Belousov wrote: >>>> >>>>> Missed this, thank you for pointing it out. Updated patch is at >>>>> http://people.freebsd.org/~kib//misc/cancel_defer.2.patch >>>> I found SIGCANCEL is masked by >>>> thr_cancel_deferred(THR_CANCEL_DEFERRED_ENABLE), issignal() does not >>>> return the masked signal, so how a cancellation point syscall can be >>>> interrupted by SIGCANCEL ? I think if a thread being canceled calls >>>> msleep(PCATCH), it should find the signal and return EINTR. >>>> >>> Yes, for EINTR and ERESTART case, the thread should be canceled. >>> Please look at the check_cancel() helper that is called at the syscall >>> entry and before return. If the check_cancel() decided that the syscall >>> is cancellation point and the thread in the deferred cancel mode, and >>> EINTR or ERESTART is supplied as error code, then SIGCANCEL is removed >> >from the thread signal mask. It is restored in the mask by ast(). >> >> I saw your patch has following lines, on syscall entry, if the >> check_cancel finds that the syscall is cancellation point and >> SIGCANCEL exists, it returns non-zero value, then the real syscall >> body at line 319 of subr_trap.c is not executed and prematurely returns. >> This is not what I want,as you said the syscall's implementation should >> always be executed, and if the thread will be blocked, then it should be >> interrupted by existing SIGCANCEL via issignal() which is called by >> sleepqueue routines. I think the current patch also has potential > No, I do not think what you describe is completely right behaviour. > As I understand SUSv4, the deferred cancel behaviour should be > as following: > - when we reach cancellation point with cancel already pending, > the syscall should not be executed at all, cancel happens and > cleanup handlers executed before thread exiting. > - when we reach cancellation point without cancel pending, and syscall > goes to sleep, and cancellation request arrives during the sleep, > again the syscall should be aborted, and cancellation happens. > so what's the problem with current libthr code ? it already did above in this way. using close() as an example, what does your modification gains ? is the kern_close() always executed for close() syscall? or if the cancellation is already pending and the syscall prematurely returns, will the file descriptor be leaked ? if it is leaked, then your modification is not better than current libthr code, it is even worse than current one, because your code involves kernel. > So I check for the cancellation at two points: one is the syscall > entry, to catch already pending cancellation request. Second is on > the syscall exit path, where cancellation is only checked in the > case the sleep was aborted. >> performance problem, the check_cancel uses PROC_LOCK, which might be a >> performance hit. > Might be. Lets first make sure that the semantic is right. > >> @@ -300,6 +332,9 @@ syscallenter(struct thread *td, struct syscall_args *sa) >> if (error != 0) >> goto retval; >> } >> + error = check_cancel(td, sa->callp, EINTR); >> + if (error != 0) >> + goto retval; >> error = syscall_thread_enter(td, sa->callp); >> if (error != 0) >> goto retval; >> From owner-freebsd-threads@FreeBSD.ORG Tue Aug 17 06:45:39 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CE5421065695 for ; Tue, 17 Aug 2010 06:45:39 +0000 (UTC) (envelope-from davidxu@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 9DDF28FC1E; Tue, 17 Aug 2010 06:45:39 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o7H6jb2q026689; Tue, 17 Aug 2010 06:45:38 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C6AA092.40708@freebsd.org> Date: Tue, 17 Aug 2010 14:45:38 +0000 From: David Xu User-Agent: Thunderbird 2.0.0.24 (X11/20100630) MIME-Version: 1.0 To: Kostik Belousov References: <4C642E9B.8000300@freebsd.org> <20100812093353.GS2396@deviant.kiev.zoral.com.ua> <4C650D0F.9060905@freebsd.org> <4C650F27.1000305@freebsd.org> <20100813141402.GW2396@deviant.kiev.zoral.com.ua> <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> In-Reply-To: <20100816104303.GP2396@deviant.kiev.zoral.com.ua> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Aug 2010 06:45:40 -0000 My idea is to always let close() syscall run, until it will be blocked by lower layer, e.g tty or socket layer, as manual of close() said it always release the file descriptor despite whether it returns EINTR or EWOULDBLOCK, when it is going to sleep, a flag will cause it to abort the sleep. if the thread does not found the flag at that time, a latter signal SIGCANCEL sent by pthread_cancel will unblock it, this is how signal works. A flag called TDP_WAKEUP is checked in sleepq_catch_signals(), if the flag is set, the sleepq_catch_signals return EINTR. In fact, a similar mechanism was already implemented in libthr's condition variable, if you carefully read the code in libthr's sigcancel_handler(), there are following lines: static void sigcancel_handler(int sig __unused, siginfo_t *info __unused, ucontext_t *ucp __unused) { struct pthread *curthread = _get_curthread(); if (curthread->cancel_defer && curthread->cancel_pending) thr_wake(curthread->tid); --- If cancellation is in defer mode and canceling request is pending, the above code turns on kernel thread's flag TDP_WAKEUP, if now a syscall is started, if kernel code finds this flag, it won't sleep and immediately return to userland. However the cancel_defer now is only used by condition variable implementation. it can be used by every cancellation point functions if sleepq_catch_signals checks the flag. As current we do, if the sigcancel_handler found the thread is in asynchronous mode, we immediately kill the thread. Please read the code in kernel function kern_umtx.c:do_cv_wait(), it checks the flag, but I think it is better to make the scope wider, and just let subr_sleepq.c: sleepq_catch_signals() check it, so we can do every cancellation point in cooperative way. Once a cancellation point syscall returns, the code in libthr's function _thr_cancel_leave_defer() checks cancellation request, and cancel the thread, yes, it calls pthread_exit to kill the current thread. it was already implemented in libthr's cond_wait_common() function. If we check TDP_WAKEUP in sleepq_catch_signals, then the close() problem will be resolved, we even can check return value of very cancellation point syscall, for example, if a recv/send syscall return value greater than zero, we may not kill the thread, this is really fun. so the close() syscall wrapper in libthr would looks like this: 1. enter cancellation point 2. call syscall __sys_close() 3. leave cancalltion point, check cancellation request, if set, kill the thread. Finally, I only need to slightly tweak libthr to fix the problem you have found, I don't need to change kernel's signal code at all, no performance problem for thread cancellation. I am working on the patch. Regards, David Xu From owner-freebsd-threads@FreeBSD.ORG Tue Aug 17 10:54:35 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4C39310656A6; Tue, 17 Aug 2010 10:54:35 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id D825D8FC24; Tue, 17 Aug 2010 10:54:34 +0000 (UTC) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id o7HAsU1Y006539 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 17 Aug 2010 13:54:30 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4) with ESMTP id o7HAsUDL038494; Tue, 17 Aug 2010 13:54:30 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4/Submit) id o7HAsUTl038493; Tue, 17 Aug 2010 13:54:30 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Tue, 17 Aug 2010 13:54:30 +0300 From: Kostik Belousov To: David Xu Message-ID: <20100817105430.GE2396@deviant.kiev.zoral.com.ua> References: <4C650D0F.9060905@freebsd.org> <4C650F27.1000305@freebsd.org> <20100813141402.GW2396@deviant.kiev.zoral.com.ua> <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> <4C6A5690.6060000@freebsd.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="fzoBs0edN2XpEQF6" Content-Disposition: inline In-Reply-To: <4C6A5690.6060000@freebsd.org> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-2.2 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_50, DNS_FROM_OPENWHOIS autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Aug 2010 10:54:35 -0000 --fzoBs0edN2XpEQF6 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, Aug 17, 2010 at 09:29:52AM +0000, David Xu wrote: > Kostik Belousov wrote: > >On Mon, Aug 16, 2010 at 04:43:02PM +0000, David Xu wrote: > >>Kostik Belousov wrote: > >>>On Mon, Aug 16, 2010 at 11:53:52AM +0000, David Xu wrote: > >>>>Kostik Belousov wrote: > >>>> > >>>>>Missed this, thank you for pointing it out. Updated patch is at > >>>>>http://people.freebsd.org/~kib//misc/cancel_defer.2.patch > >>>>I found SIGCANCEL is masked by > >>>>thr_cancel_deferred(THR_CANCEL_DEFERRED_ENABLE), issignal() does not > >>>>return the masked signal, so how a cancellation point syscall can be > >>>>interrupted by SIGCANCEL ? I think if a thread being canceled calls > >>>>msleep(PCATCH), it should find the signal and return EINTR. > >>>> > >>>Yes, for EINTR and ERESTART case, the thread should be canceled. > >>>Please look at the check_cancel() helper that is called at the syscall > >>>entry and before return. If the check_cancel() decided that the syscall > >>>is cancellation point and the thread in the deferred cancel mode, and > >>>EINTR or ERESTART is supplied as error code, then SIGCANCEL is removed > >>>from the thread signal mask. It is restored in the mask by ast(). > >> > >>I saw your patch has following lines, on syscall entry, if the > >>check_cancel finds that the syscall is cancellation point and > >>SIGCANCEL exists, it returns non-zero value, then the real syscall > >>body at line 319 of subr_trap.c is not executed and prematurely returns. > >>This is not what I want,as you said the syscall's implementation should > >>always be executed, and if the thread will be blocked, then it should be > >>interrupted by existing SIGCANCEL via issignal() which is called by > >>sleepqueue routines. I think the current patch also has potential=20 > >No, I do not think what you describe is completely right behaviour. > >As I understand SUSv4, the deferred cancel behaviour should be > >as following: > >- when we reach cancellation point with cancel already pending, > > the syscall should not be executed at all, cancel happens and > > cleanup handlers executed before thread exiting. > >- when we reach cancellation point without cancel pending, and syscall > > goes to sleep, and cancellation request arrives during the sleep, > > again the syscall should be aborted, and cancellation happens. > > >=20 > so what's the problem with current libthr code ? it already did above > in this way. > using close() as an example, what does your modification gains ? The thread in the deferred cancellation mode currently is also cancelled after close() (or write() or any other cancel-point syscall) returned without being interrupted. The window is between syscall starts syscall return sequence in the kernel and up to the point when _thr_cancel_leave() is executed by syscall wrapper in libthr. My reading of both SUSv4 and Solaris cancellation(5) page is that this is wrong. I described this is my first message that started the thread. Patch prevents cancellation after syscall is executed successfully but before libthr has a chance to mark thread as not executing the cancellation point. > is the kern_close() always executed for close() syscall? > or if the cancellation is already pending and the syscall prematurely=20 > returns, will the file descriptor be leaked ? if it is leaked, then > your modification is not better than current libthr code, it is even > worse than current one, because your code involves kernel. Close() issue pointed out by Jilles, where kernel ignores error from close fop and always clears fd, is different from this. My point is also valid for other syscalls with externally observable side-effects, like write(). --fzoBs0edN2XpEQF6 Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkxqamYACgkQC3+MBN1Mb4gBygCgmOBoTa/JjDS77m5YW4fmbx/Y 89AAoJvvNx6Veqcl/+PnL4ZVFBo/sKF6 =RyFR -----END PGP SIGNATURE----- --fzoBs0edN2XpEQF6-- From owner-freebsd-threads@FreeBSD.ORG Wed Aug 18 05:32:40 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5FB641065672 for ; Wed, 18 Aug 2010 05:32:40 +0000 (UTC) (envelope-from davidxu@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 496CB8FC18; Wed, 18 Aug 2010 05:32:40 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o7I5Wcga004422; Wed, 18 Aug 2010 05:32:39 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C6BE0F7.10207@freebsd.org> Date: Wed, 18 Aug 2010 13:32:39 +0000 From: David Xu User-Agent: Thunderbird 2.0.0.24 (X11/20100630) MIME-Version: 1.0 To: Kostik Belousov References: <4C642E9B.8000300@freebsd.org> <20100812093353.GS2396@deviant.kiev.zoral.com.ua> <4C650D0F.9060905@freebsd.org> <4C650F27.1000305@freebsd.org> <20100813141402.GW2396@deviant.kiev.zoral.com.ua> <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> <4C6AA092.40708@freebsd.org> In-Reply-To: <4C6AA092.40708@freebsd.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Aug 2010 05:32:40 -0000 David Xu wrote: > My idea is to always let close() syscall run, until it will be > blocked by lower layer, e.g tty or socket layer, as manual of close() > said it always release the file descriptor despite whether > it returns EINTR or EWOULDBLOCK, when it is going to sleep, > a flag will cause it to abort the sleep. > if the thread does not found the flag at that time, > a latter signal SIGCANCEL sent by pthread_cancel will unblock it, > this is how signal works. > I have worked out a patch: http://people.freebsd.org/~davidxu/patch/thread_cancel.patch From owner-freebsd-threads@FreeBSD.ORG Wed Aug 18 10:04:10 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E91861065670; Wed, 18 Aug 2010 10:04:10 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id 61C998FC12; Wed, 18 Aug 2010 10:04:09 +0000 (UTC) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id o7IA45UF017313 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 18 Aug 2010 13:04:05 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4) with ESMTP id o7IA456d013710; Wed, 18 Aug 2010 13:04:05 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4/Submit) id o7IA45Ca013709; Wed, 18 Aug 2010 13:04:05 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Wed, 18 Aug 2010 13:04:03 +0300 From: Kostik Belousov To: David Xu Message-ID: <20100818100403.GS2396@deviant.kiev.zoral.com.ua> References: <4C650F27.1000305@freebsd.org> <20100813141402.GW2396@deviant.kiev.zoral.com.ua> <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> <4C6AA092.40708@freebsd.org> <4C6BE0F7.10207@freebsd.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="viPXr9xSpacAnv0s" Content-Disposition: inline In-Reply-To: <4C6BE0F7.10207@freebsd.org> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-2.3 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_40, DNS_FROM_OPENWHOIS autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Aug 2010 10:04:11 -0000 --viPXr9xSpacAnv0s Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Aug 18, 2010 at 01:32:39PM +0000, David Xu wrote: > David Xu wrote: > >My idea is to always let close() syscall run, until it will be > >blocked by lower layer, e.g tty or socket layer, as manual of close() > >said it always release the file descriptor despite whether > >it returns EINTR or EWOULDBLOCK, when it is going to sleep, > >a flag will cause it to abort the sleep. > >if the thread does not found the flag at that time, > >a latter signal SIGCANCEL sent by pthread_cancel will unblock it, > >this is how signal works. > > >=20 > I have worked out a patch: > http://people.freebsd.org/~davidxu/patch/thread_cancel.patch >=20 Ok, the patch is definitely better then my proposal. But it has several details that seems to need correction. First, if TDP_WAKEUP-marked thread receives any non-cancellation signal, then a syscall returns with EINTR. This breaks SA_RESTART. Also, I think that a condition to perform cancellation in thr_syscalls.c should be not (ret =3D=3D -1), but (ret =3D=3D -1 && errno =3D=3D EINTR). --viPXr9xSpacAnv0s Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkxrsBMACgkQC3+MBN1Mb4jHJACgzVVP9f6BqiiU8kp38JWlA2mn pJ0AoLfssacTaKIHw254auwDhMP6Tt9i =E/yl -----END PGP SIGNATURE----- --viPXr9xSpacAnv0s-- From owner-freebsd-threads@FreeBSD.ORG Wed Aug 18 22:41:10 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from alona.my.domain (localhost [127.0.0.1]) by hub.freebsd.org (Postfix) with ESMTP id C34DE1065698; Wed, 18 Aug 2010 22:41:09 +0000 (UTC) (envelope-from davidxu@freebsd.org) Message-ID: <4C6C6184.9030602@freebsd.org> Date: Thu, 19 Aug 2010 06:41:08 +0800 From: David Xu User-Agent: Thunderbird 2.0.0.21 (X11/20090522) MIME-Version: 1.0 To: Kostik Belousov References: <4C650F27.1000305@freebsd.org> <20100813141402.GW2396@deviant.kiev.zoral.com.ua> <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> <4C6AA092.40708@freebsd.org> <4C6BE0F7.10207@freebsd.org> <20100818100403.GS2396@deviant.kiev.zoral.com.ua> In-Reply-To: <20100818100403.GS2396@deviant.kiev.zoral.com.ua> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Aug 2010 22:41:10 -0000 Kostik Belousov wrote: > On Wed, Aug 18, 2010 at 01:32:39PM +0000, David Xu wrote: > >> David Xu wrote: >> >>> My idea is to always let close() syscall run, until it will be >>> blocked by lower layer, e.g tty or socket layer, as manual of close() >>> said it always release the file descriptor despite whether >>> it returns EINTR or EWOULDBLOCK, when it is going to sleep, >>> a flag will cause it to abort the sleep. >>> if the thread does not found the flag at that time, >>> a latter signal SIGCANCEL sent by pthread_cancel will unblock it, >>> this is how signal works. >>> >>> >> I have worked out a patch: >> http://people.freebsd.org/~davidxu/patch/thread_cancel.patch >> >> > Ok, the patch is definitely better then my proposal. But it has several > details that seems to need correction. > > First, if TDP_WAKEUP-marked thread receives any non-cancellation signal, > then a syscall returns with EINTR. This breaks SA_RESTART. > > I don't think it breaks SA_RESTART, there are reasons this is allowed: 1) POSIX explicitly specifies that the EINTR should be returned: http://www.opengroup.org/onlinepubs/000095399/functions/xsh_chap02_09.html I copied it here: The side effects of acting upon a cancellation request while suspended during a call of a function are the same as the side effects that may be seen in a single-threaded program when a call to a function is interrupted by a signal and the given function returns [EINTR]. Any such side effects occur before any cancellation cleanup handlers are called. 2) Traditional UNIX signal does not delivered in queued order, for example, BSD delivers signal from lowest number to highest, like issignal() does, it only returns lowest number signal which is not masked. a later signal may be delivered first because it has lower number. so if a lower number signal returns EINTR, but a higher signal returns ERESTART, the final result still is EINTR. 3) Some system calls are not restartable, it always return EINTR when interrupted by signal. 4) Most of program already prepared for EINTR, it is seldom to find a program does not consider EINTR. > Also, I think that a condition to perform cancellation in thr_syscalls.c > should be not (ret == -1), but (ret == -1 && errno == EINTR). > Yes, you are right, errno may be checked. From owner-freebsd-threads@FreeBSD.ORG Thu Aug 19 08:38:17 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C13C51065679; Thu, 19 Aug 2010 08:38:17 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id 5A5268FC08; Thu, 19 Aug 2010 08:38:16 +0000 (UTC) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id o7J8c9aJ018810 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 19 Aug 2010 11:38:09 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4) with ESMTP id o7J8c95v023065; Thu, 19 Aug 2010 11:38:09 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4/Submit) id o7J8c9PG023064; Thu, 19 Aug 2010 11:38:09 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Thu, 19 Aug 2010 11:38:09 +0300 From: Kostik Belousov To: David Xu Message-ID: <20100819083809.GC2396@deviant.kiev.zoral.com.ua> References: <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> <4C6AA092.40708@freebsd.org> <4C6BE0F7.10207@freebsd.org> <20100818100403.GS2396@deviant.kiev.zoral.com.ua> <4C6C6184.9030602@freebsd.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="+8CbEAItL+VIz8WN" Content-Disposition: inline In-Reply-To: <4C6C6184.9030602@freebsd.org> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-2.2 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_50, DNS_FROM_OPENWHOIS autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Aug 2010 08:38:17 -0000 --+8CbEAItL+VIz8WN Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Aug 19, 2010 at 06:41:08AM +0800, David Xu wrote: > Kostik Belousov wrote: > >On Wed, Aug 18, 2010 at 01:32:39PM +0000, David Xu wrote: > > =20 > >>David Xu wrote: > >> =20 > >>>My idea is to always let close() syscall run, until it will be > >>>blocked by lower layer, e.g tty or socket layer, as manual of close() > >>>said it always release the file descriptor despite whether > >>>it returns EINTR or EWOULDBLOCK, when it is going to sleep, > >>>a flag will cause it to abort the sleep. > >>>if the thread does not found the flag at that time, > >>>a latter signal SIGCANCEL sent by pthread_cancel will unblock it, > >>>this is how signal works. > >>> > >>> =20 > >>I have worked out a patch: > >>http://people.freebsd.org/~davidxu/patch/thread_cancel.patch > >> > >> =20 > >Ok, the patch is definitely better then my proposal. But it has several > >details that seems to need correction. > > > >First, if TDP_WAKEUP-marked thread receives any non-cancellation signal, > >then a syscall returns with EINTR. This breaks SA_RESTART. > > > > =20 > I don't think it breaks SA_RESTART, there are reasons this is allowed: I think I need to be more verbose. What I am saying is that if the posted signal is not SIGCANCEL, then the sleepq_catch_signal() change does two things wrong, IMO: 1. it will return EINTR while the signal marked as SA_RESTART interrupted restartable syscall. 2. TDP_WAKEUP should not be cleared for this case, since we should still be prepared for special handling of SIGCANCEL, if it arrives. In other words, I propose to clear TDP_WAKEUP only when the posted=20 signal is SIGCANCEL. > 1) POSIX explicitly specifies that the EINTR should be returned: > =20 > http://www.opengroup.org/onlinepubs/000095399/functions/xsh_chap02_09.html >=20 > I copied it here: > The side effects of acting upon a cancellation request while=20 > suspended during a call > of a function are the same as the side effects that may be seen in a=20 > single-threaded > program when a call to a function is interrupted by a signal and the=20 > given function > returns [EINTR]. Any such side effects occur before any cancellation=20 > cleanup > handlers are called. >=20 > 2) Traditional UNIX signal does not delivered in queued order, for exampl= e, > BSD delivers signal from lowest number to highest, like issignal() doe= s, > it only returns lowest number signal which is not masked. a later sign= al > may be delivered first because it has lower number. so if a lower=20 > number > signal returns EINTR, but a higher signal returns ERESTART, the=20 > final result > still is EINTR. >=20 > 3) Some system calls are not restartable, it always return EINTR when=20 > interrupted > by signal. >=20 > 4) Most of program already prepared for EINTR, it is seldom to find a=20 > program > does not consider EINTR. >=20 > >Also, I think that a condition to perform cancellation in thr_syscalls.c > >should be not (ret =3D=3D -1), but (ret =3D=3D -1 && errno =3D=3D EINTR). > > =20 > Yes, you are right, errno may be checked. --+8CbEAItL+VIz8WN Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkxs7XAACgkQC3+MBN1Mb4gFSQCeNZv1XAFeZmGcRZe1r5mfvV6A RPgAoKiW0+Pz9YcjijiPBFLMAuGXetVz =EDPi -----END PGP SIGNATURE----- --+8CbEAItL+VIz8WN-- From owner-freebsd-threads@FreeBSD.ORG Thu Aug 19 09:01:58 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1933F1065696 for ; Thu, 19 Aug 2010 09:01:58 +0000 (UTC) (envelope-from davidxu@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id DCE4F8FC28; Thu, 19 Aug 2010 09:01:57 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o7J91tVW094575; Thu, 19 Aug 2010 09:01:56 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C6D6384.7080506@freebsd.org> Date: Thu, 19 Aug 2010 17:01:56 +0000 From: David Xu User-Agent: Thunderbird 2.0.0.24 (X11/20100630) MIME-Version: 1.0 To: Kostik Belousov References: <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> <4C6AA092.40708@freebsd.org> <4C6BE0F7.10207@freebsd.org> <20100818100403.GS2396@deviant.kiev.zoral.com.ua> <4C6C6184.9030602@freebsd.org> <20100819083809.GC2396@deviant.kiev.zoral.com.ua> In-Reply-To: <20100819083809.GC2396@deviant.kiev.zoral.com.ua> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Aug 2010 09:01:58 -0000 Kostik Belousov wrote: > On Thu, Aug 19, 2010 at 06:41:08AM +0800, David Xu wrote: >> Kostik Belousov wrote: >>> On Wed, Aug 18, 2010 at 01:32:39PM +0000, David Xu wrote: >>> >>>> David Xu wrote: >>>> >>>>> My idea is to always let close() syscall run, until it will be >>>>> blocked by lower layer, e.g tty or socket layer, as manual of close() >>>>> said it always release the file descriptor despite whether >>>>> it returns EINTR or EWOULDBLOCK, when it is going to sleep, >>>>> a flag will cause it to abort the sleep. >>>>> if the thread does not found the flag at that time, >>>>> a latter signal SIGCANCEL sent by pthread_cancel will unblock it, >>>>> this is how signal works. >>>>> >>>>> >>>> I have worked out a patch: >>>> http://people.freebsd.org/~davidxu/patch/thread_cancel.patch >>>> >>>> >>> Ok, the patch is definitely better then my proposal. But it has several >>> details that seems to need correction. >>> >>> First, if TDP_WAKEUP-marked thread receives any non-cancellation signal, >>> then a syscall returns with EINTR. This breaks SA_RESTART. >>> >>> >> I don't think it breaks SA_RESTART, there are reasons this is allowed: > I think I need to be more verbose. What I am saying is that if the > posted signal is not SIGCANCEL, then the sleepq_catch_signal() change > does two things wrong, IMO: > 1. it will return EINTR while the signal marked as SA_RESTART interrupted > restartable syscall. > 2. TDP_WAKEUP should not be cleared for this case, since we should > still be prepared for special handling of SIGCANCEL, if it arrives. > In other words, I propose to clear TDP_WAKEUP only when the posted > signal is SIGCANCEL. > TDP_WAKEUP is only set by the current thread itself, it is unrelated to any signal, it is that current libthr library code is acting upon the cancellation request for its user code, POSIX explicitly said EINTR should be returned for cancellation. libthr installs a signal handler for signal 32, other threads just sends the signal to a target thread which should be canceled, the target thread than sets TDP_WAKEUP for itself in signal 32 handler, it is used to unblock next syscall which is a cancellation point from pthread view. SIGCANCEL should not be treated specially by kernel, kernel should not know it is a pthread application, non-threaded application should use signal 32 without any side effect. Having a pthread knowledge in kernel is crappy, no kernel function should know there is a concept called cancellation point. From owner-freebsd-threads@FreeBSD.ORG Thu Aug 19 09:17:52 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0F46B1065695 for ; Thu, 19 Aug 2010 09:17:52 +0000 (UTC) (envelope-from davidxu@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id D387B8FC1C; Thu, 19 Aug 2010 09:17:51 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o7J9Ho3S005814; Thu, 19 Aug 2010 09:17:51 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C6D673F.4010405@freebsd.org> Date: Thu, 19 Aug 2010 17:17:51 +0000 From: David Xu User-Agent: Thunderbird 2.0.0.24 (X11/20100630) MIME-Version: 1.0 To: Kostik Belousov References: <4C65E0FE.2030803@freebsd.org> <20100814144715.GB2396@deviant.kiev.zoral.com.ua> <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> <4C6AA092.40708@freebsd.org> <4C6BE0F7.10207@freebsd.org> <20100818100403.GS2396@deviant.kiev.zoral.com.ua> <4C6C6184.9030602@freebsd.org> <20100819083809.GC2396@deviant.kiev.zoral.com.ua> <4C6D6384.7080506@freebsd.org> In-Reply-To: <4C6D6384.7080506@freebsd.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Aug 2010 09:17:52 -0000 I have updated the patch again, this time I added more determinable cancellation behavior. http://people.freebsd.org/~davidxu/patch/thread_cancel2.patch From owner-freebsd-threads@FreeBSD.ORG Thu Aug 19 14:42:20 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 499561065694; Thu, 19 Aug 2010 14:42:20 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id DA7D88FC08; Thu, 19 Aug 2010 14:42:19 +0000 (UTC) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id o7JEgI3B047347 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 19 Aug 2010 17:42:18 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4) with ESMTP id o7JEgIwZ000239; Thu, 19 Aug 2010 17:42:18 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4/Submit) id o7JEgIwF000238; Thu, 19 Aug 2010 17:42:18 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Thu, 19 Aug 2010 17:42:18 +0300 From: Kostik Belousov To: David Xu Message-ID: <20100819144218.GH2396@deviant.kiev.zoral.com.ua> References: <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> <4C6AA092.40708@freebsd.org> <4C6BE0F7.10207@freebsd.org> <20100818100403.GS2396@deviant.kiev.zoral.com.ua> <4C6C6184.9030602@freebsd.org> <20100819083809.GC2396@deviant.kiev.zoral.com.ua> <4C6D6384.7080506@freebsd.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="EZN6irWB3fS+DSGO" Content-Disposition: inline In-Reply-To: <4C6D6384.7080506@freebsd.org> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Aug 2010 14:42:20 -0000 --EZN6irWB3fS+DSGO Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Aug 19, 2010 at 05:01:56PM +0000, David Xu wrote: > Kostik Belousov wrote: > >On Thu, Aug 19, 2010 at 06:41:08AM +0800, David Xu wrote: > >>Kostik Belousov wrote: > >>>On Wed, Aug 18, 2010 at 01:32:39PM +0000, David Xu wrote: > >>>=20 > >>>>David Xu wrote: > >>>> =20 > >>>>>My idea is to always let close() syscall run, until it will be > >>>>>blocked by lower layer, e.g tty or socket layer, as manual of close() > >>>>>said it always release the file descriptor despite whether > >>>>>it returns EINTR or EWOULDBLOCK, when it is going to sleep, > >>>>>a flag will cause it to abort the sleep. > >>>>>if the thread does not found the flag at that time, > >>>>>a latter signal SIGCANCEL sent by pthread_cancel will unblock it, > >>>>>this is how signal works. > >>>>> > >>>>> =20 > >>>>I have worked out a patch: > >>>>http://people.freebsd.org/~davidxu/patch/thread_cancel.patch > >>>> > >>>> =20 > >>>Ok, the patch is definitely better then my proposal. But it has several > >>>details that seems to need correction. > >>> > >>>First, if TDP_WAKEUP-marked thread receives any non-cancellation signa= l, > >>>then a syscall returns with EINTR. This breaks SA_RESTART. > >>> > >>>=20 > >>I don't think it breaks SA_RESTART, there are reasons this is allowed: > >I think I need to be more verbose. What I am saying is that if the > >posted signal is not SIGCANCEL, then the sleepq_catch_signal() change > >does two things wrong, IMO: > >1. it will return EINTR while the signal marked as SA_RESTART interrupted > > restartable syscall. > >2. TDP_WAKEUP should not be cleared for this case, since we should > > still be prepared for special handling of SIGCANCEL, if it arrives. > >In other words, I propose to clear TDP_WAKEUP only when the posted=20 > >signal is SIGCANCEL. > > >=20 > TDP_WAKEUP is only set by the current thread itself, it is unrelated to > any signal, it is that current libthr library code is acting upon the=20 > cancellation request for its user code, POSIX explicitly said EINTR > should be returned for cancellation. >=20 > libthr installs a signal handler for signal 32, other threads just > sends the signal to a target thread which should be canceled, the target= =20 > thread than sets TDP_WAKEUP for itself in signal 32 handler, it is used > to unblock next syscall which is a cancellation point from pthread view. >=20 > SIGCANCEL should not be treated specially by kernel, kernel should not > know it is a pthread application, non-threaded application should use > signal 32 without any side effect. Having a pthread knowledge in kernel > is crappy, no kernel function should know there is a concept called > cancellation point. >=20 >=20 What would happen in the following situation: thr_wake() is called; some syscall is started executing and slept, assume that SA_RESTART is for SIGHUP (just an example); SIGHUP is sent to the process and the thread is selected for delivery, also assume that handler is installed. As I understand, in this situation, EINTR is returned from syscall. --EZN6irWB3fS+DSGO Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkxtQskACgkQC3+MBN1Mb4iRAACcC+9YtU4JD4npsDITskt4jsjP 2kUAoMkQ8K5/Mu7xJM4OXV/mNjd5NlON =/biT -----END PGP SIGNATURE----- --EZN6irWB3fS+DSGO-- From owner-freebsd-threads@FreeBSD.ORG Fri Aug 20 01:14:56 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2328910656A7 for ; Fri, 20 Aug 2010 01:14:56 +0000 (UTC) (envelope-from davidxu@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 0DAED8FC16; Fri, 20 Aug 2010 01:14:56 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o7K1Esxo051443; Fri, 20 Aug 2010 01:14:55 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C6DD70F.5070803@freebsd.org> Date: Fri, 20 Aug 2010 01:14:55 +0000 From: David Xu User-Agent: Thunderbird 2.0.0.24 (X11/20100630) MIME-Version: 1.0 To: Kostik Belousov References: <4C6926D0.2020909@freebsd.org> <20100816082022.GO2396@deviant.kiev.zoral.com.ua> <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> <4C6AA092.40708@freebsd.org> <4C6BE0F7.10207@freebsd.org> <20100818100403.GS2396@deviant.kiev.zoral.com.ua> <4C6C6184.9030602@freebsd.org> <20100819083809.GC2396@deviant.kiev.zoral.com.ua> <4C6D6384.7080506@freebsd.org> <20100819144218.GH2396@deviant.kiev.zoral.com.ua> In-Reply-To: <20100819144218.GH2396@deviant.kiev.zoral.com.ua> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Aug 2010 01:14:56 -0000 Kostik Belousov wrote: > > What would happen in the following situation: > thr_wake() is called; > some syscall is started executing and slept, assume that SA_RESTART is > for SIGHUP (just an example); > SIGHUP is sent to the process and the thread is selected > for delivery, also assume that handler is installed. > > As I understand, in this situation, EINTR is returned from syscall. Yes, because cancellation should have higher priority over signals, if signal always causes ERESTART to be returned, and system call is always restarted, the system call may not return forever because its event it is waiting never happens, for example, it is reading a byte from a socket, but it is never available, we end up not being able to cancel the thread, this is incorrect. From owner-freebsd-threads@FreeBSD.ORG Fri Aug 20 08:57:27 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7D54610656A6; Fri, 20 Aug 2010 08:57:27 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id C2B068FC27; Fri, 20 Aug 2010 08:57:26 +0000 (UTC) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id o7K8uLiO026057 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 20 Aug 2010 11:56:21 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4) with ESMTP id o7K8uL5c020925; Fri, 20 Aug 2010 11:56:21 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4/Submit) id o7K8uLl0020924; Fri, 20 Aug 2010 11:56:21 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Fri, 20 Aug 2010 11:56:21 +0300 From: Kostik Belousov To: David Xu Message-ID: <20100820085621.GK2396@deviant.kiev.zoral.com.ua> References: <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> <4C6AA092.40708@freebsd.org> <4C6BE0F7.10207@freebsd.org> <20100818100403.GS2396@deviant.kiev.zoral.com.ua> <4C6C6184.9030602@freebsd.org> <20100819083809.GC2396@deviant.kiev.zoral.com.ua> <4C6D6384.7080506@freebsd.org> <20100819144218.GH2396@deviant.kiev.zoral.com.ua> <4C6DD70F.5070803@freebsd.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="uVi4s/+X6ihGtnOs" Content-Disposition: inline In-Reply-To: <4C6DD70F.5070803@freebsd.org> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-2.7 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_05, DNS_FROM_OPENWHOIS autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Aug 2010 08:57:27 -0000 --uVi4s/+X6ihGtnOs Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Aug 20, 2010 at 01:14:55AM +0000, David Xu wrote: > Kostik Belousov wrote: >=20 > > > >What would happen in the following situation: > >thr_wake() is called; > >some syscall is started executing and slept, assume that SA_RESTART is > >for SIGHUP (just an example); > >SIGHUP is sent to the process and the thread is selected > >for delivery, also assume that handler is installed. > > > >As I understand, in this situation, EINTR is returned from syscall. >=20 > Yes, because cancellation should have higher priority over signals, > if signal always causes ERESTART to be returned, and system call > is always restarted, the system call may not return forever because > its event it is waiting never happens, for example, it is reading a byte > from a socket, but it is never available, we end up not being able to > cancel the thread, this is incorrect. Again, this is not exactly what I mean. Assume that the cancellation is not requested at all. I see no reason to return EINTR. As I see, you do not check errno when seeing syscall error return in the committed patch. Anyway, below is mostly cosmetic change to reduce code duplication, saved from the reverted patch of mine. Any objections ? diff --git a/lib/libthr/thread/thr_sig.c b/lib/libthr/thread/thr_sig.c index eed6fdb..115aa65 100644 --- a/lib/libthr/thread/thr_sig.c +++ b/lib/libthr/thread/thr_sig.c @@ -268,23 +268,26 @@ _pthread_sigmask(int how, const sigset_t *set, sigset= _t *oset) =20 __weak_reference(__sigsuspend, sigsuspend); =20 -int -_sigsuspend(const sigset_t * set) +static const sigset_t * +thr_remove_thr_signals(const sigset_t *set, sigset_t *newset) { - sigset_t newset; const sigset_t *pset; - int ret; =20 if (SIGISMEMBER(*set, SIGCANCEL)) { - newset =3D *set; - SIGDELSET(newset, SIGCANCEL); - pset =3D &newset; + *newset =3D *set; + SIGDELSET(*newset, SIGCANCEL); + pset =3D newset; } else pset =3D set; + return (pset); +} =20 - ret =3D __sys_sigsuspend(pset); +int +_sigsuspend(const sigset_t * set) +{ + sigset_t newset; =20 - return (ret); + return (__sys_sigsuspend(thr_remove_thr_signals(set, &newset))); } =20 int @@ -292,18 +295,10 @@ __sigsuspend(const sigset_t * set) { struct pthread *curthread =3D _get_curthread(); sigset_t newset; - const sigset_t *pset; int ret; =20 - if (SIGISMEMBER(*set, SIGCANCEL)) { - newset =3D *set; - SIGDELSET(newset, SIGCANCEL); - pset =3D &newset; - } else - pset =3D set; - _thr_cancel_enter(curthread); - ret =3D __sys_sigsuspend(pset); + ret =3D __sys_sigsuspend(thr_remove_thr_signals(set, &newset)); _thr_cancel_leave(curthread); =20 return (ret); @@ -318,17 +313,9 @@ _sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec * timeout) { sigset_t newset; - const sigset_t *pset; - int ret; =20 - if (SIGISMEMBER(*set, SIGCANCEL)) { - newset =3D *set; - SIGDELSET(newset, SIGCANCEL); - pset =3D &newset; - } else - pset =3D set; - ret =3D __sys_sigtimedwait(pset, info, timeout); - return (ret); + return (__sys_sigtimedwait(thr_remove_thr_signals(set, &newset), info, + timeout)); } =20 /* @@ -342,17 +329,11 @@ __sigtimedwait(const sigset_t *set, siginfo_t *info, { struct pthread *curthread =3D _get_curthread(); sigset_t newset; - const sigset_t *pset; int ret; =20 - if (SIGISMEMBER(*set, SIGCANCEL)) { - newset =3D *set; - SIGDELSET(newset, SIGCANCEL); - pset =3D &newset; - } else - pset =3D set; _thr_cancel_enter_defer(curthread, 1); - ret =3D __sys_sigtimedwait(pset, info, timeout); + ret =3D __sys_sigtimedwait(thr_remove_thr_signals(set, &newset), info, + timeout); _thr_cancel_leave_defer(curthread, (ret =3D=3D -1)); return (ret); } @@ -361,18 +342,8 @@ int _sigwaitinfo(const sigset_t *set, siginfo_t *info) { sigset_t newset; - const sigset_t *pset; - int ret; - - if (SIGISMEMBER(*set, SIGCANCEL)) { - newset =3D *set; - SIGDELSET(newset, SIGCANCEL); - pset =3D &newset; - } else - pset =3D set; =20 - ret =3D __sys_sigwaitinfo(pset, info); - return (ret); + return (__sys_sigwaitinfo(thr_remove_thr_signals(set, &newset), info)); } =20 /* @@ -385,18 +356,10 @@ __sigwaitinfo(const sigset_t *set, siginfo_t *info) { struct pthread *curthread =3D _get_curthread(); sigset_t newset; - const sigset_t *pset; int ret; =20 - if (SIGISMEMBER(*set, SIGCANCEL)) { - newset =3D *set; - SIGDELSET(newset, SIGCANCEL); - pset =3D &newset; - } else - pset =3D set; - _thr_cancel_enter_defer(curthread, 1); - ret =3D __sys_sigwaitinfo(pset, info); + ret =3D __sys_sigwaitinfo(thr_remove_thr_signals(set, &newset), info); _thr_cancel_leave_defer(curthread, ret =3D=3D -1); return (ret); } @@ -405,18 +368,8 @@ int _sigwait(const sigset_t *set, int *sig) { sigset_t newset; - const sigset_t *pset; - int ret; - - if (SIGISMEMBER(*set, SIGCANCEL)) { - newset =3D *set; - SIGDELSET(newset, SIGCANCEL); - pset =3D &newset; - } else=20 - pset =3D set; =20 - ret =3D __sys_sigwait(pset, sig); - return (ret); + return (__sys_sigwait(thr_remove_thr_signals(set, &newset), sig)); } =20 /* @@ -429,18 +382,10 @@ __sigwait(const sigset_t *set, int *sig) { struct pthread *curthread =3D _get_curthread(); sigset_t newset; - const sigset_t *pset; int ret; =20 - if (SIGISMEMBER(*set, SIGCANCEL)) { - newset =3D *set; - SIGDELSET(newset, SIGCANCEL); - pset =3D &newset; - } else=20 - pset =3D set; - _thr_cancel_enter_defer(curthread, 1); - ret =3D __sys_sigwait(pset, sig); + ret =3D __sys_sigwait(thr_remove_thr_signals(set, &newset), sig); _thr_cancel_leave_defer(curthread, (ret !=3D 0)); return (ret); } --uVi4s/+X6ihGtnOs Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkxuQzUACgkQC3+MBN1Mb4hIPACfSm79lI2SSygTCWHnVSK0q7bo PDgAoJL5XeXFDwwZ5lO2llP2J9hfsaid =Wt6B -----END PGP SIGNATURE----- --uVi4s/+X6ihGtnOs-- From owner-freebsd-threads@FreeBSD.ORG Fri Aug 20 09:51:15 2010 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 81BF610656A7 for ; Fri, 20 Aug 2010 09:51:15 +0000 (UTC) (envelope-from davidxu@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 50EB58FC0C; Fri, 20 Aug 2010 09:51:15 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o7K9pDiX077262; Fri, 20 Aug 2010 09:51:14 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C6EC012.7000506@freebsd.org> Date: Fri, 20 Aug 2010 17:49:06 +0000 From: David Xu User-Agent: Thunderbird 2.0.0.24 (X11/20100630) MIME-Version: 1.0 To: Kostik Belousov References: <4C696A96.7020709@freebsd.org> <20100816104303.GP2396@deviant.kiev.zoral.com.ua> <4C6AA092.40708@freebsd.org> <4C6BE0F7.10207@freebsd.org> <20100818100403.GS2396@deviant.kiev.zoral.com.ua> <4C6C6184.9030602@freebsd.org> <20100819083809.GC2396@deviant.kiev.zoral.com.ua> <4C6D6384.7080506@freebsd.org> <20100819144218.GH2396@deviant.kiev.zoral.com.ua> <4C6DD70F.5070803@freebsd.org> <20100820085621.GK2396@deviant.kiev.zoral.com.ua> In-Reply-To: <20100820085621.GK2396@deviant.kiev.zoral.com.ua> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-threads@freebsd.org Subject: Re: PTHREAD_CANCEL_DEFERRED X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Aug 2010 09:51:15 -0000 Kostik Belousov wrote: > On Fri, Aug 20, 2010 at 01:14:55AM +0000, David Xu wrote: >> Kostik Belousov wrote: >> >>> What would happen in the following situation: >>> thr_wake() is called; >>> some syscall is started executing and slept, assume that SA_RESTART is >>> for SIGHUP (just an example); >>> SIGHUP is sent to the process and the thread is selected >>> for delivery, also assume that handler is installed. >>> >>> As I understand, in this situation, EINTR is returned from syscall. >> Yes, because cancellation should have higher priority over signals, >> if signal always causes ERESTART to be returned, and system call >> is always restarted, the system call may not return forever because >> its event it is waiting never happens, for example, it is reading a byte >> from a socket, but it is never available, we end up not being able to >> cancel the thread, this is incorrect. > > Again, this is not exactly what I mean. Assume that the cancellation is > not requested at all. I see no reason to return EINTR. This flag is only turned on when the target thread has cancellation enabled and it is at cancellation point and pthread_cancel() was issued for it. > > As I see, you do not check errno when seeing syscall error return > in the committed patch. > Yes, I don't check it now. This becauses I can not figure out a reliable behavior, not because I want to offend you. There are two requirements I remembered: 1) At a cancellation point, it must have a chance to cancel thread. 2) Its behavior must be reliable. at present, I check cancellation at start of a cancellation point function, it may kill the thread itself, this fits requirement 1. then if the thread is still alive, it invokes system call, when system call returns, it checks cancellation request again, and may kill the thread itself. This fits requirement 2. because of requirement 1, at the start of cancellation point, the thread may be killed, error code is not returned even if caller provided invalid argument to system call because system call is not issued ! if later, system call returns error, if I use your idea, the cancellation point function should return error code to caller, then this is not a reliable behavior! The cancellation point ends up that it either returns error or not, even if the provided argument to kernel is always invalid at all! If you eliminates requirement 1, and use your idea to not cancel thread on error, if user always provides an invalid argument to kernel syscall, then the cancellation point never can cancel the thread, this is incorrect. So at present, I can only find the stable behavior as current code does, if you can find a better behavior, feel free to improve it. > Anyway, below is mostly cosmetic change to reduce code duplication, > saved from the reverted patch of mine. Any objections ? > will commit it, thanks! > diff --git a/lib/libthr/thread/thr_sig.c b/lib/libthr/thread/thr_sig.c > index eed6fdb..115aa65 100644 > --- a/lib/libthr/thread/thr_sig.c > +++ b/lib/libthr/thread/thr_sig.c > @@ -268,23 +268,26 @@ _pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) > > __weak_reference(__sigsuspend, sigsuspend); > > -int > -_sigsuspend(const sigset_t * set) > +static const sigset_t * > +thr_remove_thr_signals(const sigset_t *set, sigset_t *newset) > { > - sigset_t newset; > const sigset_t *pset; > - int ret; > > if (SIGISMEMBER(*set, SIGCANCEL)) { > - newset = *set; > - SIGDELSET(newset, SIGCANCEL); > - pset = &newset; > + *newset = *set; > + SIGDELSET(*newset, SIGCANCEL); > + pset = newset; > } else > pset = set; > + return (pset); > +} > > - ret = __sys_sigsuspend(pset); > +int > +_sigsuspend(const sigset_t * set) > +{ > + sigset_t newset; > > - return (ret); > + return (__sys_sigsuspend(thr_remove_thr_signals(set, &newset))); > } > > int > @@ -292,18 +295,10 @@ __sigsuspend(const sigset_t * set) > { > struct pthread *curthread = _get_curthread(); > sigset_t newset; > - const sigset_t *pset; > int ret; > > - if (SIGISMEMBER(*set, SIGCANCEL)) { > - newset = *set; > - SIGDELSET(newset, SIGCANCEL); > - pset = &newset; > - } else > - pset = set; > - > _thr_cancel_enter(curthread); > - ret = __sys_sigsuspend(pset); > + ret = __sys_sigsuspend(thr_remove_thr_signals(set, &newset)); > _thr_cancel_leave(curthread); > > return (ret); > @@ -318,17 +313,9 @@ _sigtimedwait(const sigset_t *set, siginfo_t *info, > const struct timespec * timeout) > { > sigset_t newset; > - const sigset_t *pset; > - int ret; > > - if (SIGISMEMBER(*set, SIGCANCEL)) { > - newset = *set; > - SIGDELSET(newset, SIGCANCEL); > - pset = &newset; > - } else > - pset = set; > - ret = __sys_sigtimedwait(pset, info, timeout); > - return (ret); > + return (__sys_sigtimedwait(thr_remove_thr_signals(set, &newset), info, > + timeout)); > } > > /* > @@ -342,17 +329,11 @@ __sigtimedwait(const sigset_t *set, siginfo_t *info, > { > struct pthread *curthread = _get_curthread(); > sigset_t newset; > - const sigset_t *pset; > int ret; > > - if (SIGISMEMBER(*set, SIGCANCEL)) { > - newset = *set; > - SIGDELSET(newset, SIGCANCEL); > - pset = &newset; > - } else > - pset = set; > _thr_cancel_enter_defer(curthread, 1); > - ret = __sys_sigtimedwait(pset, info, timeout); > + ret = __sys_sigtimedwait(thr_remove_thr_signals(set, &newset), info, > + timeout); > _thr_cancel_leave_defer(curthread, (ret == -1)); > return (ret); > } > @@ -361,18 +342,8 @@ int > _sigwaitinfo(const sigset_t *set, siginfo_t *info) > { > sigset_t newset; > - const sigset_t *pset; > - int ret; > - > - if (SIGISMEMBER(*set, SIGCANCEL)) { > - newset = *set; > - SIGDELSET(newset, SIGCANCEL); > - pset = &newset; > - } else > - pset = set; > > - ret = __sys_sigwaitinfo(pset, info); > - return (ret); > + return (__sys_sigwaitinfo(thr_remove_thr_signals(set, &newset), info)); > } > > /* > @@ -385,18 +356,10 @@ __sigwaitinfo(const sigset_t *set, siginfo_t *info) > { > struct pthread *curthread = _get_curthread(); > sigset_t newset; > - const sigset_t *pset; > int ret; > > - if (SIGISMEMBER(*set, SIGCANCEL)) { > - newset = *set; > - SIGDELSET(newset, SIGCANCEL); > - pset = &newset; > - } else > - pset = set; > - > _thr_cancel_enter_defer(curthread, 1); > - ret = __sys_sigwaitinfo(pset, info); > + ret = __sys_sigwaitinfo(thr_remove_thr_signals(set, &newset), info); > _thr_cancel_leave_defer(curthread, ret == -1); > return (ret); > } > @@ -405,18 +368,8 @@ int > _sigwait(const sigset_t *set, int *sig) > { > sigset_t newset; > - const sigset_t *pset; > - int ret; > - > - if (SIGISMEMBER(*set, SIGCANCEL)) { > - newset = *set; > - SIGDELSET(newset, SIGCANCEL); > - pset = &newset; > - } else > - pset = set; > > - ret = __sys_sigwait(pset, sig); > - return (ret); > + return (__sys_sigwait(thr_remove_thr_signals(set, &newset), sig)); > } > > /* > @@ -429,18 +382,10 @@ __sigwait(const sigset_t *set, int *sig) > { > struct pthread *curthread = _get_curthread(); > sigset_t newset; > - const sigset_t *pset; > int ret; > > - if (SIGISMEMBER(*set, SIGCANCEL)) { > - newset = *set; > - SIGDELSET(newset, SIGCANCEL); > - pset = &newset; > - } else > - pset = set; > - > _thr_cancel_enter_defer(curthread, 1); > - ret = __sys_sigwait(pset, sig); > + ret = __sys_sigwait(thr_remove_thr_signals(set, &newset), sig); > _thr_cancel_leave_defer(curthread, (ret != 0)); > return (ret); > }