From owner-freebsd-current@FreeBSD.ORG Thu Oct 1 12:07:35 2009 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 31CF5106568B for ; Thu, 1 Oct 2009 12:07:35 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (skuns.zoral.com.ua [91.193.166.194]) by mx1.freebsd.org (Postfix) with ESMTP id B85B38FC18 for ; Thu, 1 Oct 2009 12:07: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 n91C7UaQ007330 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 1 Oct 2009 15:07: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.3/8.14.3) with ESMTP id n91C7UDp088713; Thu, 1 Oct 2009 15:07:30 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.3/8.14.3/Submit) id n91C7UuK088670; Thu, 1 Oct 2009 15:07: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: Thu, 1 Oct 2009 15:07:30 +0300 From: Kostik Belousov To: Justin Teller Message-ID: <20091001120730.GR3130@deviant.kiev.zoral.com.ua> References: Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="TMgB3/Ch1aWgZB1L" Content-Disposition: inline In-Reply-To: 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=-4.4 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 autolearn=ham version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: freebsd-current@freebsd.org Subject: Re: Signals and an exiting thread X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Oct 2009 12:07:35 -0000 --TMgB3/Ch1aWgZB1L Content-Type: text/plain; charset=koi8-r Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Sep 30, 2009 at 11:02:19AM -0700, Justin Teller wrote: > We're trying to control one process from another process through > signals (I know, revolutionary ;-), and we've found that a signal > occasionally gets lost. =9AThe process we're signaling is > multi-threaded. =9AIt looks like the signal is lost when the kernel > decides to post the signal to a thread that is in the process of dying > (calling pthread_exit, etc). >=20 > Is this expected behavior that we should just handle, or is it a race > in the kernel that should be/will be/already is fixed? >=20 > It may be that a fix is already in current, and I just haven't found > it in my searches through the source code (I'm working off of source > code for an older 8.0 image). If it is fixed, I'd appreciate a > pointer to the code that fixes it. When thread enters the kernel last time to be killed, it is very much bad idea to allow it to return to usermode to handle directed signal. And, there would always be window between entering the kernel and marking the thread as exiting. Moving the thread-directed signals back to the process queue is hard and there is no way to distinguish which signals were sent to process or to the thread. Possibly, we could clear the thread signal mask while still in user mode. I think it would still leave a very narrow window when a process signal could be directed to the dying thread and not be delivered to usermode; this happens when signal is generated while sigsetmask already entered the kernel, but did not changed the mask yet. This is worked around by rechecking the pending signals after setting the block mask and releasing it if needed. Consider the patch as experimental. diff --git a/lib/libthr/thread/thr_exit.c b/lib/libthr/thread/thr_exit.c index 33a2451..f0339c5 100644 --- a/lib/libthr/thread/thr_exit.c +++ b/lib/libthr/thread/thr_exit.c @@ -31,6 +31,7 @@ =20 #include "namespace.h" #include +#include #include #include #include @@ -69,6 +70,8 @@ void _pthread_exit(void *status) { struct pthread *curthread =3D _get_curthread(); + sigset_t block_sig, old_sig, pend_sig; + int i; =20 /* Check if this thread is already in the process of exiting: */ if (curthread->cancelling) { @@ -108,6 +111,30 @@ _pthread_exit(void *status) } THREAD_LIST_UNLOCK(curthread); =20 + /* + * From now on, hint the kernel to not direct signals for + * delivery to this thread. + */ + sigfillset(&block_sig); + for (;;) { + _pthread_sigmask(SIG_SETMASK, &block_sig, &old_sig); + /* + * If the signal was directed to the thread before + * thread sigmask was set to blocked, try to handle + * the signal. + */ + sigpending(&pend_sig); + for (i =3D 0; i < _SIG_MAXSIG; i++) { + if (!sigismember(&old_sig, i) && + sigismember(&pend_sig, i)) { + _pthread_sigmask(SIG_SETMASK, &old_sig, NULL); + break; + } + } + if (i =3D=3D _SIG_MAXSIG) + break; + } + /* Tell malloc that the thread is exiting. */ _malloc_thread_cleanup(); =20 --TMgB3/Ch1aWgZB1L Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkrEm4EACgkQC3+MBN1Mb4hPWwCcCajD2NiOdl7PbO7mcmkKsQXQ 9IkAnRZ1tkLmS3Q8GglJtJBuQDIj3VuJ =38D3 -----END PGP SIGNATURE----- --TMgB3/Ch1aWgZB1L--