From owner-freebsd-threads@FreeBSD.ORG Mon Aug 9 11:07:06 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 8761B1065679 for ; Mon, 9 Aug 2010 11:07:06 +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 6B1A98FC0A for ; Mon, 9 Aug 2010 11:07:06 +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 o79B76oc049163 for ; Mon, 9 Aug 2010 11:07:06 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o79B75dm049161 for freebsd-threads@FreeBSD.org; Mon, 9 Aug 2010 11:07:05 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 9 Aug 2010 11:07:05 GMT Message-Id: <201008091107.o79B75dm049161@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, 09 Aug 2010 11:07:06 -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 Wed Aug 11 21:19:29 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 1893F106566C for ; Wed, 11 Aug 2010 21:19:29 +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 A95C18FC12 for ; Wed, 11 Aug 2010 21:19:28 +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 o7BKlw4r049940 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 11 Aug 2010 23:47:58 +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 o7BKlw6i097703 for ; Wed, 11 Aug 2010 23:47:58 +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 o7BKlwYk097702 for freebsd-threads@freebsd.org; Wed, 11 Aug 2010 23:47:58 +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, 11 Aug 2010 23:47:58 +0300 From: Kostik Belousov To: freebsd-threads@freebsd.org Message-ID: <20100811204758.GQ2396@deviant.kiev.zoral.com.ua> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="wwtQuX191/I956S7" Content-Disposition: inline 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 Subject: 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, 11 Aug 2010 21:19:29 -0000 --wwtQuX191/I956S7 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, Let consider the thread in the state where the cancelation is enabled and cancelation mode set to the PTHREAD_CANCEL_DEFERRED. SUSv4 says the following: Whenever a thread has cancelability enabled and a cancellation request has been made with that thread as the target, and the thread then calls any function that is a cancellation point (such as pthread_testcancel() or read()), the cancellation request shall be acted upon before the function returns. If a thread has cancelability enabled and a cancellation request is made with the thread as a target while the thread is suspended at a cancellation point, the thread shall be awakened and the cancellation request shall be acted upon. Take the close(2) as example, and assume that the cancel is enabled for the thread in deferred mode. libthr wrapper around the syscall executes this: curthread->cancel_point++; testcancel(curthread); __sys_close(fd); curthread->cancel_point--; The pthread_cancel() sends the SIGCANCEL signal to the thread. SIGCANCEL handler calls pthread_exit() if thread has the cancel_point greater then 0. I think this is not right. For instance, thread can be canceled due to SIGCANCEL delivery at the point after the return into the usermode from close(), but before cancel_point is decremented. IMO, the cited statements from the SUSv4 prohibit such behaviour. We should cancel either before closing fd, or during the sleep in close(), but then the syscall should be aborted ("as if signal is delivered"), and again fd should not be closed. Actually, besides not being compliant, I think that the current behaviour is not useful, since in deferred case, we cannot know whether the action by the call that is cancelation point was performed or not. This is not a rant, I probably will fix the issue if it is agreed upon. Opinions ? --wwtQuX191/I956S7 Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkxjDH0ACgkQC3+MBN1Mb4ibaQCfRzmKgUwxbaIyWxwnGeL7qlX4 ZdwAoOoEdCqsQcxeWK0FelHXInamXgma =nLnJ -----END PGP SIGNATURE----- --wwtQuX191/I956S7-- From owner-freebsd-threads@FreeBSD.ORG Thu Aug 12 02:42:36 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 7A4671065672; Thu, 12 Aug 2010 02:42:36 +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 4F4978FC13; Thu, 12 Aug 2010 02:42:36 +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 o7C2gY2m023345; Thu, 12 Aug 2010 02:42:35 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C63D01B.5080709@freebsd.org> Date: Thu, 12 Aug 2010 10:42:35 +0000 From: David Xu User-Agent: Thunderbird 2.0.0.24 (X11/20100630) MIME-Version: 1.0 To: linimon@freebsd.org References: <201008061455.o76EtCQI024539@freefall.freebsd.org> In-Reply-To: <201008061455.o76EtCQI024539@freefall.freebsd.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-bugs@freebsd.org, freebsd-threads@freebsd.org Subject: Re: threads/149366: pthread_cleanup_pop never runs the configured routine 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, 12 Aug 2010 02:42:36 -0000 linimon@FreeBSD.org wrote: > Synopsis: pthread_cleanup_pop never runs the configured routine > > Responsible-Changed-From-To: freebsd-bugs->freebsd-threads > Responsible-Changed-By: linimon > Responsible-Changed-When: Fri Aug 6 14:54:30 UTC 2010 > Responsible-Changed-Why: > Over to maintainer(s). > > http://www.freebsd.org/cgi/query-pr.cgi?pr=149366 > _______________________________________________ You should link your program with libpthread, otherwise, it won't work. Regards, David Xu From owner-freebsd-threads@FreeBSD.ORG Thu Aug 12 02:59: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 924FD1065675 for ; Thu, 12 Aug 2010 02:59: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 67AB38FC14; Thu, 12 Aug 2010 02:59:58 +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 o7C2xuuO032696; Thu, 12 Aug 2010 02:59:57 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C63D42D.8040606@freebsd.org> Date: Thu, 12 Aug 2010 10:59:57 +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> In-Reply-To: <20100811204758.GQ2396@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, 12 Aug 2010 02:59:58 -0000 Kostik Belousov wrote: > Hi, > Let consider the thread in the state where the cancelation is enabled > and cancelation mode set to the PTHREAD_CANCEL_DEFERRED. > > SUSv4 says the following: > Whenever a thread has cancelability enabled and a cancellation request > has been made with that thread as the target, and the thread then > calls any function that is a cancellation point (such as > pthread_testcancel() or read()), the cancellation request shall be > acted upon before the function returns. If a thread has cancelability > enabled and a cancellation request is made with the thread as a target > while the thread is suspended at a cancellation point, the thread > shall be awakened and the cancellation request shall be acted upon. > > Take the close(2) as example, and assume that the cancel is enabled > for the thread in deferred mode. libthr wrapper around the syscall > executes this: > > curthread->cancel_point++; > testcancel(curthread); > __sys_close(fd); > curthread->cancel_point--; > > The pthread_cancel() sends the SIGCANCEL signal to the > thread. SIGCANCEL handler calls pthread_exit() if thread has the > cancel_point greater then 0. > > I think this is not right. For instance, thread can be canceled due to > SIGCANCEL delivery at the point after the return into the usermode > from close(), but before cancel_point is decremented. IMO, the cited > statements from the SUSv4 prohibit such behaviour. We should cancel > either before closing fd, or during the sleep in close(), but then the > syscall should be aborted ("as if signal is delivered"), and again fd > should not be closed. > > Actually, besides not being compliant, I think that the current > behaviour is not useful, since in deferred case, we cannot know > whether the action by the call that is cancelation point was performed > or not. > > This is not a rant, I probably will fix the issue if it is agreed > upon. Opinions ? it is true that a cancellation point does not return when cancellation happens, so we really does not know if it did something or not, and SUSv4 does not say cancellation point is an atomic transaction, and whether it will rollback when cancellation happens, the problem may happen even if you want to fix it, if the cancellation request is sent after int 0x80 instruction returns (on i386) but before libc close() stub returns, the cancellation still can happen, so could you tell if the file handle is closed or not ? there is no way to tell caller that the close() really did something. I found the issue when I wrote the code, and it seems Linux does it in same way, so I had not done further work on it. From owner-freebsd-threads@FreeBSD.ORG Thu Aug 12 08:30:14 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 2A67A1065670; Thu, 12 Aug 2010 08:30:14 +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 B70758FC0A; Thu, 12 Aug 2010 08:30:13 +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 o7C8U7av000446 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 12 Aug 2010 11:30:07 +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 o7C8U67n004741; Thu, 12 Aug 2010 11:30:06 +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 o7C8U6dB004740; Thu, 12 Aug 2010 11:30:06 +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, 12 Aug 2010 11:30:06 +0300 From: Kostik Belousov To: David Xu Message-ID: <20100812083006.GR2396@deviant.kiev.zoral.com.ua> References: <20100811204758.GQ2396@deviant.kiev.zoral.com.ua> <4C63D42D.8040606@freebsd.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="YC8Ek3FeOE8ywfXk" Content-Disposition: inline In-Reply-To: <4C63D42D.8040606@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, 12 Aug 2010 08:30:14 -0000 --YC8Ek3FeOE8ywfXk Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Aug 12, 2010 at 10:59:57AM +0000, David Xu wrote: > Kostik Belousov wrote: > >Hi, > >Let consider the thread in the state where the cancelation is enabled > >and cancelation mode set to the PTHREAD_CANCEL_DEFERRED. > > > >SUSv4 says the following: > >Whenever a thread has cancelability enabled and a cancellation request > >has been made with that thread as the target, and the thread then > >calls any function that is a cancellation point (such as > >pthread_testcancel() or read()), the cancellation request shall be > >acted upon before the function returns. If a thread has cancelability > >enabled and a cancellation request is made with the thread as a target > >while the thread is suspended at a cancellation point, the thread > >shall be awakened and the cancellation request shall be acted upon. > > > >Take the close(2) as example, and assume that the cancel is enabled > >for the thread in deferred mode. libthr wrapper around the syscall > >executes this: > > > > curthread->cancel_point++; > > testcancel(curthread); > > __sys_close(fd); > > curthread->cancel_point--; > > > >The pthread_cancel() sends the SIGCANCEL signal to the > >thread. SIGCANCEL handler calls pthread_exit() if thread has the > >cancel_point greater then 0. > > > >I think this is not right. For instance, thread can be canceled due to > >SIGCANCEL delivery at the point after the return into the usermode > >from close(), but before cancel_point is decremented. IMO, the cited > >statements from the SUSv4 prohibit such behaviour. We should cancel > >either before closing fd, or during the sleep in close(), but then the > >syscall should be aborted ("as if signal is delivered"), and again fd > >should not be closed. > > > >Actually, besides not being compliant, I think that the current > >behaviour is not useful, since in deferred case, we cannot know > >whether the action by the call that is cancelation point was performed > >or not. > > > >This is not a rant, I probably will fix the issue if it is agreed > >upon. Opinions ? >=20 > it is true that a cancellation point does not return when cancellation > happens, so we really does not know if it did something or not, > and SUSv4 does not say cancellation point is an atomic transaction, > and whether it will rollback when cancellation happens, the problem may > happen even if you want to fix it, if the cancellation request is sent > after int 0x80 instruction returns (on i386) but before libc close() > stub returns, the cancellation still can happen, so could you tell > if the file handle is closed or not ? there is no way to tell > caller that the close() really did something. > I found the issue when I wrote the code, and it seems Linux does > it in same way, so I had not done further work on it. What I am proposing is to not cancel if close() indeed closed the descriptor. The same could be done for all other cancelation points that are syscalls. I evaluated the possible implementation. It looks like it is enough, when thread is switched to cancel enabled and deferred mode, to make SIGCANCEL delivery special. Namely, it should be only delivered at the cancelable syscall _entry_ point and on syscall return when error is EINTR or ERESTART. pthread_testcancel() is also becoming a dummy syscall, with the same rules of SIGCANCEL delivery. Cancelable syscalls would be marked in the syscall table, the cost of the change is that pthread_setcanceltype() becomes a syscall. --YC8Ek3FeOE8ywfXk Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkxjsQ4ACgkQC3+MBN1Mb4iBXACgunzE3IlNJ2LftZX7I9L2Kf23 gFYAnA2Nd1w8Q+O+Ykql+Fih3iyUY1FB =F1KZ -----END PGP SIGNATURE----- --YC8Ek3FeOE8ywfXk-- From owner-freebsd-threads@FreeBSD.ORG Thu Aug 12 09:02:40 2010 Return-Path: Delivered-To: freebsd-threads@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4BCFD1065689 for ; Thu, 12 Aug 2010 09:02:40 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 213188FC1A for ; Thu, 12 Aug 2010 09:02:40 +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 o7C92eLj027244 for ; Thu, 12 Aug 2010 09:02:40 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o7C92daJ027243; Thu, 12 Aug 2010 09:02:39 GMT (envelope-from gnats) Date: Thu, 12 Aug 2010 09:02:39 GMT Message-Id: <201008120902.o7C92daJ027243@freefall.freebsd.org> To: freebsd-threads@FreeBSD.org From: David Xu Cc: Subject: Re: threads/149366: pthread_cleanup_pop never runs the configured routine X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: David Xu List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Aug 2010 09:02:40 -0000 The following reply was made to PR threads/149366; it has been noted by GNATS. From: David Xu To: bug-followup@freebsd.org, fernando@netfilter.com.br Cc: Subject: Re: threads/149366: pthread_cleanup_pop never runs the configured routine Date: Thu, 12 Aug 2010 10:44:12 +0000 Oops, sorry, I have sent reply to wrong person. The answer is, you should link your program with libpthread, otherwise, it won't work. Regards, David Xu From owner-freebsd-threads@FreeBSD.ORG Thu Aug 12 09:02:42 2010 Return-Path: Delivered-To: freebsd-threads@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3E2F51065696 for ; Thu, 12 Aug 2010 09:02:42 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 28C808FC18 for ; Thu, 12 Aug 2010 09:02:42 +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 o7C92flc027258 for ; Thu, 12 Aug 2010 09:02:41 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o7C92fqH027257; Thu, 12 Aug 2010 09:02:41 GMT (envelope-from gnats) Date: Thu, 12 Aug 2010 09:02:41 GMT Message-Id: <201008120902.o7C92fqH027257@freefall.freebsd.org> To: freebsd-threads@FreeBSD.org From: Mark Linimon Cc: Subject: Re: threads/149366: pthread_cleanup_pop never runs the configured routine X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Mark Linimon List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Aug 2010 09:02:42 -0000 The following reply was made to PR threads/149366; it has been noted by GNATS. From: Mark Linimon To: bug-followup@FreeBSD.org Cc: Subject: Re: threads/149366: pthread_cleanup_pop never runs the configured routine Date: Wed, 11 Aug 2010 22:44:01 -0500 ----- Forwarded message from David Xu ----- From: David Xu To: linimon@freebsd.org CC: freebsd-bugs@freebsd.org, freebsd-threads@freebsd.org Subject: Re: threads/149366: pthread_cleanup_pop never runs the configured routine You should link your program with libpthread, otherwise, it won't work. Regards, David Xu ----- End forwarded message ----- From owner-freebsd-threads@FreeBSD.ORG Thu Aug 12 09:03:05 2010 Return-Path: Delivered-To: freebsd-threads@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 81FEA1065696 for ; Thu, 12 Aug 2010 09:03:05 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 576CC8FC18 for ; Thu, 12 Aug 2010 09:03:05 +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 o7C935ln027399 for ; Thu, 12 Aug 2010 09:03:05 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o7C935gu027398; Thu, 12 Aug 2010 09:03:05 GMT (envelope-from gnats) Date: Thu, 12 Aug 2010 09:03:05 GMT Message-Id: <201008120903.o7C935gu027398@freefall.freebsd.org> To: freebsd-threads@FreeBSD.org From: David Xu Cc: Subject: Re: threads/149366: pthread_cleanup_pop never runs the configured routine X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: David Xu List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Aug 2010 09:03:05 -0000 The following reply was made to PR threads/149366; it has been noted by GNATS. From: David Xu To: bug-followup@freebsd.org, fernando@netfilter.com.br Cc: Subject: Re: threads/149366: pthread_cleanup_pop never runs the configured routine Date: Thu, 12 Aug 2010 10:44:12 +0000 Oops, sorry, I have sent reply to wrong person. The answer is, you should link your program with libpthread, otherwise, it won't work. Regards, David Xu From owner-freebsd-threads@FreeBSD.ORG Thu Aug 12 09:03:07 2010 Return-Path: Delivered-To: freebsd-threads@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 65A7910656A5 for ; Thu, 12 Aug 2010 09:03:07 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 5505D8FC1C for ; Thu, 12 Aug 2010 09:03:07 +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 o7C937sT027415 for ; Thu, 12 Aug 2010 09:03:07 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o7C9376o027414; Thu, 12 Aug 2010 09:03:07 GMT (envelope-from gnats) Date: Thu, 12 Aug 2010 09:03:07 GMT Message-Id: <201008120903.o7C9376o027414@freefall.freebsd.org> To: freebsd-threads@FreeBSD.org From: Mark Linimon Cc: Subject: Re: threads/149366: pthread_cleanup_pop never runs the configured routine X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Mark Linimon List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Aug 2010 09:03:07 -0000 The following reply was made to PR threads/149366; it has been noted by GNATS. From: Mark Linimon To: bug-followup@FreeBSD.org Cc: Subject: Re: threads/149366: pthread_cleanup_pop never runs the configured routine Date: Wed, 11 Aug 2010 22:44:01 -0500 ----- Forwarded message from David Xu ----- From: David Xu To: linimon@freebsd.org CC: freebsd-bugs@freebsd.org, freebsd-threads@freebsd.org Subject: Re: threads/149366: pthread_cleanup_pop never runs the configured routine You should link your program with libpthread, otherwise, it won't work. Regards, David Xu ----- End forwarded message ----- From owner-freebsd-threads@FreeBSD.ORG Thu Aug 12 09:25:48 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 4F03010656A6 for ; Thu, 12 Aug 2010 09:25:48 +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 3D57F8FC13; Thu, 12 Aug 2010 09:25:48 +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 o7C9Pkmc047440; Thu, 12 Aug 2010 09:25:47 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C642E9B.8000300@freebsd.org> Date: Thu, 12 Aug 2010 17:25:47 +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> In-Reply-To: <20100812083006.GR2396@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, 12 Aug 2010 09:25:48 -0000 Kostik Belousov wrote: > On Thu, Aug 12, 2010 at 10:59:57AM +0000, David Xu wrote: >> Kostik Belousov wrote: >>> Hi, >>> Let consider the thread in the state where the cancelation is enabled >>> and cancelation mode set to the PTHREAD_CANCEL_DEFERRED. >>> >>> SUSv4 says the following: >>> Whenever a thread has cancelability enabled and a cancellation request >>> has been made with that thread as the target, and the thread then >>> calls any function that is a cancellation point (such as >>> pthread_testcancel() or read()), the cancellation request shall be >>> acted upon before the function returns. If a thread has cancelability >>> enabled and a cancellation request is made with the thread as a target >>> while the thread is suspended at a cancellation point, the thread >>> shall be awakened and the cancellation request shall be acted upon. >>> >>> Take the close(2) as example, and assume that the cancel is enabled >>> for the thread in deferred mode. libthr wrapper around the syscall >>> executes this: >>> >>> curthread->cancel_point++; >>> testcancel(curthread); >>> __sys_close(fd); >>> curthread->cancel_point--; >>> >>> The pthread_cancel() sends the SIGCANCEL signal to the >>> thread. SIGCANCEL handler calls pthread_exit() if thread has the >>> cancel_point greater then 0. >>> >>> I think this is not right. For instance, thread can be canceled due to >>> SIGCANCEL delivery at the point after the return into the usermode >> >from close(), but before cancel_point is decremented. IMO, the cited >>> statements from the SUSv4 prohibit such behaviour. We should cancel >>> either before closing fd, or during the sleep in close(), but then the >>> syscall should be aborted ("as if signal is delivered"), and again fd >>> should not be closed. >>> >>> Actually, besides not being compliant, I think that the current >>> behaviour is not useful, since in deferred case, we cannot know >>> whether the action by the call that is cancelation point was performed >>> or not. >>> >>> This is not a rant, I probably will fix the issue if it is agreed >>> upon. Opinions ? >> it is true that a cancellation point does not return when cancellation >> happens, so we really does not know if it did something or not, >> and SUSv4 does not say cancellation point is an atomic transaction, >> and whether it will rollback when cancellation happens, the problem may >> happen even if you want to fix it, if the cancellation request is sent >> after int 0x80 instruction returns (on i386) but before libc close() >> stub returns, the cancellation still can happen, so could you tell >> if the file handle is closed or not ? there is no way to tell >> caller that the close() really did something. >> I found the issue when I wrote the code, and it seems Linux does >> it in same way, so I had not done further work on it. > > What I am proposing is to not cancel if close() indeed closed the > descriptor. The same could be done for all other cancelation points that > are syscalls. > > I evaluated the possible implementation. It looks like it is enough, > when thread is switched to cancel enabled and deferred mode, to make > SIGCANCEL delivery special. Namely, it should be only delivered at the > cancelable syscall _entry_ point and on syscall return when error is > EINTR or ERESTART. pthread_testcancel() is also becoming a dummy syscall, > with the same rules of SIGCANCEL delivery. > > Cancelable syscalls would be marked in the syscall table, the cost of > the change is that pthread_setcanceltype() becomes a syscall. This might be not enough, because I found a scenario: suppose there are two threads A and B: B: pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED) A: pthread_cancel(B) it sets cancel_pending to 1 and send SIGCANCEL to B B: got SIGCANCEL delivered to userland and did nothing because it is not at cancel point. B: still doing other things... B: call close() B: sleep in kernel because no SIGCANCEL found. if you don't call testcancel() in close() stub like current libthr did, B won't response to the cancel request, you lost the race. From owner-freebsd-threads@FreeBSD.ORG Thu Aug 12 09:33: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 EDEE3106564A; Thu, 12 Aug 2010 09:33:58 +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 6F1558FC13; Thu, 12 Aug 2010 09:33:58 +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 o7C9XrBf006722 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 12 Aug 2010 12:33:53 +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 o7C9XrfC005628; Thu, 12 Aug 2010 12:33:53 +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 o7C9Xr9B005627; Thu, 12 Aug 2010 12:33:53 +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, 12 Aug 2010 12:33:53 +0300 From: Kostik Belousov To: David Xu Message-ID: <20100812093353.GS2396@deviant.kiev.zoral.com.ua> References: <20100811204758.GQ2396@deviant.kiev.zoral.com.ua> <4C63D42D.8040606@freebsd.org> <20100812083006.GR2396@deviant.kiev.zoral.com.ua> <4C642E9B.8000300@freebsd.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="2uzDqHpccQJpqF2n" Content-Disposition: inline In-Reply-To: <4C642E9B.8000300@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, 12 Aug 2010 09:33:59 -0000 --2uzDqHpccQJpqF2n Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Aug 12, 2010 at 05:25:47PM +0000, David Xu wrote: > Kostik Belousov wrote: > >On Thu, Aug 12, 2010 at 10:59:57AM +0000, David Xu wrote: > >>Kostik Belousov wrote: > >>>Hi, > >>>Let consider the thread in the state where the cancelation is enabled > >>>and cancelation mode set to the PTHREAD_CANCEL_DEFERRED. > >>> > >>>SUSv4 says the following: > >>>Whenever a thread has cancelability enabled and a cancellation request > >>>has been made with that thread as the target, and the thread then > >>>calls any function that is a cancellation point (such as > >>>pthread_testcancel() or read()), the cancellation request shall be > >>>acted upon before the function returns. If a thread has cancelability > >>>enabled and a cancellation request is made with the thread as a target > >>>while the thread is suspended at a cancellation point, the thread > >>>shall be awakened and the cancellation request shall be acted upon. > >>> > >>>Take the close(2) as example, and assume that the cancel is enabled > >>>for the thread in deferred mode. libthr wrapper around the syscall > >>>executes this: > >>> > >>> curthread->cancel_point++; > >>> testcancel(curthread); > >>> __sys_close(fd); > >>> curthread->cancel_point--; > >>> > >>>The pthread_cancel() sends the SIGCANCEL signal to the > >>>thread. SIGCANCEL handler calls pthread_exit() if thread has the > >>>cancel_point greater then 0. > >>> > >>>I think this is not right. For instance, thread can be canceled due to > >>>SIGCANCEL delivery at the point after the return into the usermode > >>>from close(), but before cancel_point is decremented. IMO, the cited > >>>statements from the SUSv4 prohibit such behaviour. We should cancel > >>>either before closing fd, or during the sleep in close(), but then the > >>>syscall should be aborted ("as if signal is delivered"), and again fd > >>>should not be closed. > >>> > >>>Actually, besides not being compliant, I think that the current > >>>behaviour is not useful, since in deferred case, we cannot know > >>>whether the action by the call that is cancelation point was performed > >>>or not. > >>> > >>>This is not a rant, I probably will fix the issue if it is agreed > >>>upon. Opinions ? > >>it is true that a cancellation point does not return when cancellation > >>happens, so we really does not know if it did something or not, > >>and SUSv4 does not say cancellation point is an atomic transaction, > >>and whether it will rollback when cancellation happens, the problem may > >>happen even if you want to fix it, if the cancellation request is sent > >>after int 0x80 instruction returns (on i386) but before libc close() > >>stub returns, the cancellation still can happen, so could you tell > >>if the file handle is closed or not ? there is no way to tell > >>caller that the close() really did something. > >>I found the issue when I wrote the code, and it seems Linux does > >>it in same way, so I had not done further work on it. > > > >What I am proposing is to not cancel if close() indeed closed the > >descriptor. The same could be done for all other cancelation points that > >are syscalls. > > > >I evaluated the possible implementation. It looks like it is enough, > >when thread is switched to cancel enabled and deferred mode, to make > >SIGCANCEL delivery special. Namely, it should be only delivered at the > >cancelable syscall _entry_ point and on syscall return when error is > >EINTR or ERESTART. pthread_testcancel() is also becoming a dummy syscall, > >with the same rules of SIGCANCEL delivery. > > > >Cancelable syscalls would be marked in the syscall table, the cost of > >the change is that pthread_setcanceltype() becomes a syscall. >=20 > This might be not enough, because I found a scenario: > suppose there are two threads A and B: >=20 > B: pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED) > A: pthread_cancel(B) > it sets cancel_pending to 1 and send SIGCANCEL to B > B: got SIGCANCEL delivered to userland and did nothing > because it is not at cancel point. [1] > B: still doing other things... > B: call close() [2] > B: sleep in kernel because no SIGCANCEL found. >=20 > if you don't call testcancel() in close() stub like current libthr did, > B won't response to the cancel request, you lost the race. This situation should be handled by my proposal, since SIGCANCEL is delivered only - at the syscall entry point - at the syscall premature return Userspace would not get SIGCANCEL at time of [1], instead, signal will be delivered at [2]. --2uzDqHpccQJpqF2n Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkxjwAEACgkQC3+MBN1Mb4jk1QCg96cshPEi1eqB6PqzMYLB0caU C9EAoLXYRM8eQHm0Qxtx/TCiT4ISe4r2 =X/WM -----END PGP SIGNATURE----- --2uzDqHpccQJpqF2n-- From owner-freebsd-threads@FreeBSD.ORG Fri Aug 13 01:14:57 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 6B0EA10656A5 for ; Fri, 13 Aug 2010 01:14:57 +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 0DFB08FC21; Fri, 13 Aug 2010 01:14: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 o7D1Etrd081675; Fri, 13 Aug 2010 01:14:56 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C650D0F.9060905@freebsd.org> Date: Fri, 13 Aug 2010 09:14:55 +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> In-Reply-To: <20100812093353.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: Fri, 13 Aug 2010 01:14:57 -0000 Kostik Belousov wrote: > On Thu, Aug 12, 2010 at 05:25:47PM +0000, David Xu wrote: >> Kostik Belousov wrote: >>> On Thu, Aug 12, 2010 at 10:59:57AM +0000, David Xu wrote: >>>> Kostik Belousov wrote: >>>>> Hi, >>>>> Let consider the thread in the state where the cancelation is enabled >>>>> and cancelation mode set to the PTHREAD_CANCEL_DEFERRED. >>>>> >>>>> SUSv4 says the following: >>>>> Whenever a thread has cancelability enabled and a cancellation request >>>>> has been made with that thread as the target, and the thread then >>>>> calls any function that is a cancellation point (such as >>>>> pthread_testcancel() or read()), the cancellation request shall be >>>>> acted upon before the function returns. If a thread has cancelability >>>>> enabled and a cancellation request is made with the thread as a target >>>>> while the thread is suspended at a cancellation point, the thread >>>>> shall be awakened and the cancellation request shall be acted upon. >>>>> >>>>> Take the close(2) as example, and assume that the cancel is enabled >>>>> for the thread in deferred mode. libthr wrapper around the syscall >>>>> executes this: >>>>> >>>>> curthread->cancel_point++; >>>>> testcancel(curthread); >>>>> __sys_close(fd); >>>>> curthread->cancel_point--; >>>>> >>>>> The pthread_cancel() sends the SIGCANCEL signal to the >>>>> thread. SIGCANCEL handler calls pthread_exit() if thread has the >>>>> cancel_point greater then 0. >>>>> >>>>> I think this is not right. For instance, thread can be canceled due to >>>>> SIGCANCEL delivery at the point after the return into the usermode >>>> >from close(), but before cancel_point is decremented. IMO, the cited >>>>> statements from the SUSv4 prohibit such behaviour. We should cancel >>>>> either before closing fd, or during the sleep in close(), but then the >>>>> syscall should be aborted ("as if signal is delivered"), and again fd >>>>> should not be closed. >>>>> >>>>> Actually, besides not being compliant, I think that the current >>>>> behaviour is not useful, since in deferred case, we cannot know >>>>> whether the action by the call that is cancelation point was performed >>>>> or not. >>>>> >>>>> This is not a rant, I probably will fix the issue if it is agreed >>>>> upon. Opinions ? >>>> it is true that a cancellation point does not return when cancellation >>>> happens, so we really does not know if it did something or not, >>>> and SUSv4 does not say cancellation point is an atomic transaction, >>>> and whether it will rollback when cancellation happens, the problem may >>>> happen even if you want to fix it, if the cancellation request is sent >>>> after int 0x80 instruction returns (on i386) but before libc close() >>>> stub returns, the cancellation still can happen, so could you tell >>>> if the file handle is closed or not ? there is no way to tell >>>> caller that the close() really did something. >>>> I found the issue when I wrote the code, and it seems Linux does >>>> it in same way, so I had not done further work on it. >>> What I am proposing is to not cancel if close() indeed closed the >>> descriptor. The same could be done for all other cancelation points that >>> are syscalls. >>> >>> I evaluated the possible implementation. It looks like it is enough, >>> when thread is switched to cancel enabled and deferred mode, to make >>> SIGCANCEL delivery special. Namely, it should be only delivered at the >>> cancelable syscall _entry_ point and on syscall return when error is >>> EINTR or ERESTART. pthread_testcancel() is also becoming a dummy syscall, >>> with the same rules of SIGCANCEL delivery. >>> >>> Cancelable syscalls would be marked in the syscall table, the cost of >>> the change is that pthread_setcanceltype() becomes a syscall. >> This might be not enough, because I found a scenario: >> suppose there are two threads A and B: >> >> B: pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED) >> A: pthread_cancel(B) >> it sets cancel_pending to 1 and send SIGCANCEL to B >> B: got SIGCANCEL delivered to userland and did nothing >> because it is not at cancel point. > [1] > >> B: still doing other things... >> B: call close() > [2] > >> B: sleep in kernel because no SIGCANCEL found. >> >> if you don't call testcancel() in close() stub like current libthr did, >> B won't response to the cancel request, you lost the race. > This situation should be handled by my proposal, since SIGCANCEL is > delivered only > - at the syscall entry point > - at the syscall premature return > Userspace would not get SIGCANCEL at time of [1], instead, signal will > be delivered at [2]. kernel may don't know if the syscall is cancelable, because it depends on usage, if the close() syscall is used by fclose(), then the syscall is not cancellation point, libc avoids this by using _close(), and libthr does not override it. if kernel knows when a thread is at cancellation point, then it needs another syscall to set and unset the flag, but that's too expensive and in practical it is not acceptable. Regards, David Xu From owner-freebsd-threads@FreeBSD.ORG Fri Aug 13 01:23: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 5E9031065679 for ; Fri, 13 Aug 2010 01:23: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 4AF078FC08; Fri, 13 Aug 2010 01:23:52 +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 o7D1NoAT090889; Fri, 13 Aug 2010 01:23:51 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4C650F27.1000305@freebsd.org> Date: Fri, 13 Aug 2010 09:23:51 +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> In-Reply-To: <4C650D0F.9060905@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: Fri, 13 Aug 2010 01:23:52 -0000 David Xu wrote: >>> if you don't call testcancel() in close() stub like current libthr did, >>> B won't response to the cancel request, you lost the race. >> This situation should be handled by my proposal, since SIGCANCEL is >> delivered only >> - at the syscall entry point >> - at the syscall premature return >> Userspace would not get SIGCANCEL at time of [1], instead, signal will >> be delivered at [2]. > kernel may don't know if the syscall is cancelable, because it depends > on usage, if the close() syscall is used by fclose(), then the syscall > is not cancellation point, libc avoids this by using _close(), > and libthr does not override it. if kernel knows when a thread is at > cancellation point, then it needs another syscall to set and unset > the flag, but that's too expensive and in practical it is not > acceptable. > a bit out of topic, I also think that thread cancellation is not better than a simple signal, because it does not return to caller and force you to push and pop somethings, it may also be incompatible with some language's exception handling, why does not just use signal to interrupt syscall and let caller to check if the thread should exit, the UNIX is quite good at this. From owner-freebsd-threads@FreeBSD.ORG Fri Aug 13 12: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 614E6106564A for ; Fri, 13 Aug 2010 12:51:15 +0000 (UTC) (envelope-from jilles@stack.nl) Received: from mx1.stack.nl (relay04.stack.nl [IPv6:2001:610:1108:5010::107]) by mx1.freebsd.org (Postfix) with ESMTP id C1D818FC08 for ; Fri, 13 Aug 2010 12:51:14 +0000 (UTC) Received: from turtle.stack.nl (turtle.stack.nl [IPv6:2001:610:1108:5010::132]) by mx1.stack.nl (Postfix) with ESMTP id 9FD341DD650; Fri, 13 Aug 2010 14:51:13 +0200 (CEST) Received: by turtle.stack.nl (Postfix, from userid 1677) id 93892172B1; Fri, 13 Aug 2010 14:51:13 +0200 (CEST) Date: Fri, 13 Aug 2010 14:51:13 +0200 From: Jilles Tjoelker To: Kostik Belousov Message-ID: <20100813125113.GA73073@stack.nl> References: <20100811204758.GQ2396@deviant.kiev.zoral.com.ua> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20100811204758.GQ2396@deviant.kiev.zoral.com.ua> User-Agent: Mutt/1.5.20 (2009-06-14) 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, 13 Aug 2010 12:51:15 -0000 On Wed, Aug 11, 2010 at 11:47:58PM +0300, Kostik Belousov wrote: > Let consider the thread in the state where the cancelation is enabled > and cancelation mode set to the PTHREAD_CANCEL_DEFERRED. > SUSv4 says the following: > Whenever a thread has cancelability enabled and a cancellation request > has been made with that thread as the target, and the thread then > calls any function that is a cancellation point (such as > pthread_testcancel() or read()), the cancellation request shall be > acted upon before the function returns. If a thread has cancelability > enabled and a cancellation request is made with the thread as a target > while the thread is suspended at a cancellation point, the thread > shall be awakened and the cancellation request shall be acted upon. > Take the close(2) as example, and assume that the cancel is enabled > for the thread in deferred mode. libthr wrapper around the syscall > executes this: > curthread->cancel_point++; > testcancel(curthread); > __sys_close(fd); > curthread->cancel_point--; > The pthread_cancel() sends the SIGCANCEL signal to the > thread. SIGCANCEL handler calls pthread_exit() if thread has the > cancel_point greater then 0. > I think this is not right. For instance, thread can be canceled due to > SIGCANCEL delivery at the point after the return into the usermode > from close(), but before cancel_point is decremented. IMO, the cited > statements from the SUSv4 prohibit such behaviour. We should cancel > either before closing fd, or during the sleep in close(), but then the > syscall should be aborted ("as if signal is delivered"), and again fd > should not be closed. This reasoning is entirely valid for syscalls like open() and wait4() without WNOWAIT, but close() is a bit different. Regardless of what the underlying fo_close function returned, it continues cleaning up the file descriptor (even if the error is EINTR or ERESTART). It seems that ERESTART could cause another close for the same fd number after the signal handler returns, which can have disastrous consequences in multi-threaded applications (data sent to wrong files). Similarly, applications that think they have to retry close() when it returns EINTR may cause problems. It would be safest to avoid EINTR or ERESTART errors from close() entirely, either changing it to another errno or pretending the close succeeded. POSIX leaves the state of a file descriptor after close() failed with EINTR or EIO unspecified. So the only thing a portable application can do is forget about the file descriptor and hope the implementation freed it; otherwise, if the implementation frees the file descriptor, the application may act on a new file opened by another thread. An example of a type of file that can block on close is a tty. However, the tty layer ignores any error that could result from this and always succeeds a close. It seems that the kernel code in general would become more complicated by allowing close() to be restarted. Perhaps it is better to change the libthr wrapper to decrement cancel_point before calling __sys_close(). If a cancel had come in before close(), it will be acted upon like before, and the cleanup handlers will be called with fd still open. If a cancel comes in during a blocking close(), it will not be acted upon yet but the close will abort with EINTR (or just pretend to succeed if it is a tty); the cancel will be acted upon at the next cancellation point. As usual with things that rely on EINTR there is a race window, between the decrement and entering close(), where a cancel may not be acted upon before close() finishes its thing. > Actually, besides not being compliant, I think that the current > behaviour is not useful, since in deferred case, we cannot know > whether the action by the call that is cancelation point was performed > or not. > This is not a rant, I probably will fix the issue if it is agreed > upon. Opinions ? I think this is indeed a problem. In fact, I have a similar issue in sh(1). sh catches SIGINT, with a signal handler that either sets a flag or longjmp()s to an exception handler, similar to libthr's cancellation handling. System call restart is disabled for SIGINT. It would be best to use the longjmp() approach for blocking operations, as this avoids the race conditions associated with EINTR, but this is not possible if the blocking operation also changes state such as when opening a fifo. Therefore, a SIGINT that comes in just before the blocking open is tried is not processed until the open is done. Admittedly, because sh is single-threaded, I could predict the fd that open() would return and (void)close it after an interruption, but that is very ugly. What I have seen from glibc's implementation is that it is similar to ours, except that it avoids sending a signal when the signal handler would not pthread_exit() right away. An idea for a fix: add a new bit of state for each signal which means that the signal interrupts sleep(9) functions with PCATCH, but is not delivered while the thread is executing on a CPU. Actually delivering the signal in this state would require another bit to track if the signal has interrupted a sleep, which would be checked at return from the syscall. Alternatively, userland would receive EINTR on all blocking syscalls until it either disables the new mode or accepts the signal using sigwait() or similar. The latter is simplest on the kernel but may cause a user program to spin waiting for the EINTR to go away. The EINTR could be replaced by a different error. In either case, pthread_testcancel() would use a sigtimedwait() for SIGCANCEL with a zero-valued timespec, invoking cancellation processing if it succeeds. Hmm, there is also a slight problem here with syscalls that are cancellation points, but do not block, such as close() on a regular file (weird NFS intr stuff excluded). Preserving the semantics requires an additional syscall to check for cancellation, which is unfortunate because cancellation is not used much. Another (ugly) fix is to use some sort of timer to interrupt blocking operations if processing had apparently not yet started due to the race condition. This means that functions like open() and wait4() are wrapped more like curthread->cancel_point++; testcancel(curthread); curthread->cancel_point--; ret = __sys_wait4(pid, status, options, rusage); if (ret == -1 && errno == EINTR) { curthread->cancel_point++; testcancel(curthread); curthread->cancel_point--; } The signal handler for SIGCANCEL enables a timer that resends SIGCANCEL to the thread after some time. It looks like the facility underlying timer_create() provides such timers. -- Jilles Tjoelker From owner-freebsd-threads@FreeBSD.ORG Fri Aug 13 14:14:07 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 6053610656A4; Fri, 13 Aug 2010 14:14:07 +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 D03948FC24; Fri, 13 Aug 2010 14:14:06 +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 o7DEE2Ep053704 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 13 Aug 2010 17:14:02 +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 o7DEE2rV023451; Fri, 13 Aug 2010 17:14:02 +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 o7DEE239023450; Fri, 13 Aug 2010 17:14:02 +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, 13 Aug 2010 17:14:02 +0300 From: Kostik Belousov To: David Xu Message-ID: <20100813141402.GW2396@deviant.kiev.zoral.com.ua> 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> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="wYXww9TlNKyqAMAe" Content-Disposition: inline In-Reply-To: <4C650F27.1000305@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: Fri, 13 Aug 2010 14:14:07 -0000 --wYXww9TlNKyqAMAe Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Aug 13, 2010 at 09:23:51AM +0000, David Xu wrote: > David Xu wrote: >=20 > >>>if you don't call testcancel() in close() stub like current libthr did, > >>>B won't response to the cancel request, you lost the race. > >>This situation should be handled by my proposal, since SIGCANCEL is > >>delivered only > >>- at the syscall entry point > >>- at the syscall premature return > >>Userspace would not get SIGCANCEL at time of [1], instead, signal will > >>be delivered at [2]. > >kernel may don't know if the syscall is cancelable, because it depends > >on usage, if the close() syscall is used by fclose(), then the syscall > >is not cancellation point, libc avoids this by using _close(), > >and libthr does not override it. if kernel knows when a thread is at > >cancellation point, then it needs another syscall to set and unset > >the flag, but that's too expensive and in practical it is not > >acceptable. The kernel only decides whether to process SIGCANCEL specially. The decision about the cancel point is still at the hands of the threading library. The delivered SIGCANCEL goes through the same checks of eligibility for cancellation as before. But it is only delivered now at potential cancellation points for deferred case. Please see the patch at http://people.freebsd.org/~kib//misc/cancel_defer.1.patch for the proof of concept prototype. > > > a bit out of topic, I also think that thread cancellation is not > better than a simple signal, because it does not return to caller > and force you to push and pop somethings, it may also be incompatible > with some language's exception handling, why does not just use > signal to interrupt syscall and let caller to check if the thread > should exit, the UNIX is quite good at this. This still does not give the answer of whether the syscall was executed. I have to check for %pc to see when the signal was delivered. Also, to be able to use signal in the way you suggested, I need a signal handler installed. This is very inconvenient from the library. BTW, I looked at the Solaris cancellation(5) man page, and it seems that Solaris implements the proper (from my POV) deferred cancellation: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D When cancellation is deferred (the default case), cancellation occurs only within the scope of a function defined as a cancellation point (after the function is called and before the function returns). =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --wYXww9TlNKyqAMAe Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkxlUykACgkQC3+MBN1Mb4gO2gCgpTwyqghw1i+OasAHe6sMQttX 7sIAoJR61UxpeivMZl0I/LKwTAMtoNd8 =X3zg -----END PGP SIGNATURE----- --wYXww9TlNKyqAMAe-- From owner-freebsd-threads@FreeBSD.ORG Sat Aug 14 00:19:14 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 AF1651065673; Sat, 14 Aug 2010 00:19:13 +0000 (UTC) (envelope-from davidxu@freebsd.org) Message-ID: <4C65E0FE.2030803@freebsd.org> Date: Sat, 14 Aug 2010 08:19:10 +0800 From: David Xu User-Agent: Thunderbird 2.0.0.21 (X11/20090522) 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> In-Reply-To: <20100813141402.GW2396@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: Sat, 14 Aug 2010 00:19:14 -0000 Kostik Belousov wrote: > On Fri, Aug 13, 2010 at 09:23:51AM +0000, David Xu wrote: > >> David Xu wrote: >> >> >>>>> if you don't call testcancel() in close() stub like current libthr did, >>>>> B won't response to the cancel request, you lost the race. >>>>> >>>> This situation should be handled by my proposal, since SIGCANCEL is >>>> delivered only >>>> - at the syscall entry point >>>> - at the syscall premature return >>>> Userspace would not get SIGCANCEL at time of [1], instead, signal will >>>> be delivered at [2]. >>>> >>> kernel may don't know if the syscall is cancelable, because it depends >>> on usage, if the close() syscall is used by fclose(), then the syscall >>> is not cancellation point, libc avoids this by using _close(), >>> and libthr does not override it. if kernel knows when a thread is at >>> cancellation point, then it needs another syscall to set and unset >>> the flag, but that's too expensive and in practical it is not >>> acceptable. >>> > The kernel only decides whether to process SIGCANCEL specially. The > decision about the cancel point is still at the hands of the threading > library. The delivered SIGCANCEL goes through the same checks of > eligibility for cancellation as before. But it is only delivered now at > potential cancellation points for deferred case. > > Please see the patch at > http://people.freebsd.org/~kib//misc/cancel_defer.1.patch > for the proof of concept prototype. > > >> a bit out of topic, I also think that thread cancellation is not >> better than a simple signal, because it does not return to caller >> and force you to push and pop somethings, it may also be incompatible >> with some language's exception handling, why does not just use >> signal to interrupt syscall and let caller to check if the thread >> should exit, the UNIX is quite good at this. >> > > This still does not give the answer of whether the syscall was executed. > I have to check for %pc to see when the signal was delivered. Also, to > be able to use signal in the way you suggested, I need a signal handler > installed. This is very inconvenient from the library. > > BTW, I looked at the Solaris cancellation(5) man page, and it seems that > Solaris implements the proper (from my POV) deferred cancellation: > ============== > When cancellation is deferred (the default case), cancellation occurs > only within the scope of a function defined as a cancellation point > (after the function is called and before the function returns). > ============== > while the above patch may work, there could have exceptions: just before syscall close() enters kernel, a user signal is received, and the user signal handler calls a syscall which happens to be cancellation point, I saw some programs print a log in signal handler, and thread is canceled, e.g write(2, msg, strlen(msg)) to log a message, close() syscall is still not called, though it is arguable that if this signal handler code is legal. thread suspending in libthr uses SIGCANCEL to check suspending state, the code needs to be adjusted, it seems I have to use another signal. From owner-freebsd-threads@FreeBSD.ORG Sat Aug 14 14:47:19 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 DCB3D1065695; Sat, 14 Aug 2010 14:47:19 +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 763D68FC1A; Sat, 14 Aug 2010 14:47: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 o7EElFLB067541 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 14 Aug 2010 17:47:15 +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 o7EElFZn016556; Sat, 14 Aug 2010 17:47:15 +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 o7EElFWx016555; Sat, 14 Aug 2010 17:47:15 +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: Sat, 14 Aug 2010 17:47:15 +0300 From: Kostik Belousov To: David Xu Message-ID: <20100814144715.GB2396@deviant.kiev.zoral.com.ua> 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> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="j+D14l8Ki1YJdzYp" Content-Disposition: inline In-Reply-To: <4C65E0FE.2030803@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: Sat, 14 Aug 2010 14:47:19 -0000 --j+D14l8Ki1YJdzYp Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sat, Aug 14, 2010 at 08:19:10AM +0800, David Xu wrote: > Kostik Belousov wrote: > >On Fri, Aug 13, 2010 at 09:23:51AM +0000, David Xu wrote: > > =20 > >>David Xu wrote: > >> > >> =20 > >>>>>if you don't call testcancel() in close() stub like current libthr d= id, > >>>>>B won't response to the cancel request, you lost the race. > >>>>> =20 > >>>>This situation should be handled by my proposal, since SIGCANCEL is > >>>>delivered only > >>>>- at the syscall entry point > >>>>- at the syscall premature return > >>>>Userspace would not get SIGCANCEL at time of [1], instead, signal will > >>>>be delivered at [2]. > >>>> =20 > >>>kernel may don't know if the syscall is cancelable, because it depends > >>>on usage, if the close() syscall is used by fclose(), then the syscall > >>>is not cancellation point, libc avoids this by using _close(), > >>>and libthr does not override it. if kernel knows when a thread is at > >>>cancellation point, then it needs another syscall to set and unset > >>>the flag, but that's too expensive and in practical it is not > >>>acceptable. > >>> =20 > >The kernel only decides whether to process SIGCANCEL specially. The > >decision about the cancel point is still at the hands of the threading > >library. The delivered SIGCANCEL goes through the same checks of > >eligibility for cancellation as before. But it is only delivered now at > >potential cancellation points for deferred case. > > > >Please see the patch at > >http://people.freebsd.org/~kib//misc/cancel_defer.1.patch > >for the proof of concept prototype. > > > > =20 > >>a bit out of topic, I also think that thread cancellation is not > >>better than a simple signal, because it does not return to caller > >>and force you to push and pop somethings, it may also be incompatible > >>with some language's exception handling, why does not just use > >>signal to interrupt syscall and let caller to check if the thread > >>should exit, the UNIX is quite good at this. > >> =20 > > > >This still does not give the answer of whether the syscall was executed. > >I have to check for %pc to see when the signal was delivered. Also, to > >be able to use signal in the way you suggested, I need a signal handler > >installed. This is very inconvenient from the library. > > > >BTW, I looked at the Solaris cancellation(5) man page, and it seems that > >Solaris implements the proper (from my POV) deferred cancellation: > >=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > >When cancellation is deferred (the default case), cancellation occurs > >only within the scope of a function defined as a cancellation point > >(after the function is called and before the function returns). > >=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > =20 > while the above patch may work, there could have exceptions: >=20 > just before syscall close() enters kernel, a user signal is received,=20 > and the user > signal handler calls a syscall which happens to be cancellation point, I= =20 > saw some > programs print a log in signal handler, and thread is canceled, > e.g write(2, msg, strlen(msg)) to log a message, > close() syscall is still not called, though it is arguable that if this= =20 > signal handler > code is legal. Sorry, I cannot fully understand the point. Do you mean that close() could not be called if signal handler calls function that is a cancelation point ? This seems to be ok, my rush is against the situation where the state-changing call is done, but I cannot determine was it actually done or not, due to cancellation. >=20 > thread suspending in libthr uses SIGCANCEL to check suspending state, > the code needs to be adjusted, it seems I have to use another signal. Missed this, thank you for pointing it out. Updated patch is at http://people.freebsd.org/~kib//misc/cancel_defer.2.patch --j+D14l8Ki1YJdzYp Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkxmrHMACgkQC3+MBN1Mb4h/rwCg0/JGSkbPHyP21GvRu79gx2jX 6j4Anj4HhGPMWdh3KPIf4gWTKxGhd6OP =c8Xf -----END PGP SIGNATURE----- --j+D14l8Ki1YJdzYp--