From owner-freebsd-threads@FreeBSD.ORG Thu Jan 31 09:20:09 2008 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 9AFBA16A418 for ; Thu, 31 Jan 2008 09:20:09 +0000 (UTC) (envelope-from landonf@bikemonkey.org) Received: from secure.bikemonkey.org (bluefish.bikemonkey.org [69.80.211.101]) by mx1.freebsd.org (Postfix) with ESMTP id 6D22013C465 for ; Thu, 31 Jan 2008 09:20:09 +0000 (UTC) (envelope-from landonf@bikemonkey.org) Received: from [172.16.99.14] (unknown [172.16.99.14]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by secure.bikemonkey.org (Postfix) with ESMTP id 12B531703A; Thu, 31 Jan 2008 01:20:09 -0800 (PST) Message-Id: <01819294-7795-493D-A054-D4ACEC8706D6@bikemonkey.org> From: Landon Fuller To: Julian Elischer In-Reply-To: <47A18DCD.2070101@elischer.org> Content-Type: multipart/signed; protocol="application/pgp-signature"; micalg=pgp-sha1; boundary="Apple-Mail-1-125705283" Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v915) Date: Thu, 31 Jan 2008 01:20:04 -0800 References: <200801240850.m0O8o2JQ023500@freefall.freebsd.org> <4798564B.7070500@elischer.org> <488DBC6A-CF33-4E50-B1BB-C396C8957F92@bikemonkey.org> <892A73B3-0114-4718-ABC0-CADD45D9D0FA@bikemonkey.org> <47A0D2DE.9060005@elischer.org> <35535E7A-0804-4DAD-B0A0-CCF9EE7060B0@bikemonkey.org> <47A18DCD.2070101@elischer.org> X-Pgp-Agent: GPGMail d51 (Leopard) X-Mailer: Apple Mail (2.915) Cc: freebsd-threads@freebsd.org Subject: Re: threads/119920: fork broken in libpthread 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, 31 Jan 2008 09:20:09 -0000 This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --Apple-Mail-1-125705283 Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit On Jan 31, 2008, at 12:58 AM, Julian Elischer wrote: > Landon Fuller wrote: > >> Thanks -- pulling in relevant change from sys/lock.c -- plus your >> previous patch -- solves my reproduction case: >> http://landonf.bikemonkey.org/static/code/freebsd/patch-libpthread63-fork > > > is this the patch you used? It's huge.. Are you sure you fetched the patch-libpthread63-fork file? I cherry picked just the changes to _lockuser_reinit() and _kse_single_thread(). Posted patch here, inlined below: http://landonf.bikemonkey.org/static/code/freebsd/patch-libpthread63-fork Cheers, Landon diff -ru lib/libpthread.orig/sys/lock.c lib/libpthread/sys/lock.c --- lib/libpthread.orig/sys/lock.c 2008-01-30 16:30:07.000000000 -0800 +++ lib/libpthread/sys/lock.c 2008-01-30 16:58:59.000000000 -0800 @@ -117,14 +117,23 @@ { if (lu == NULL) return (-1); - /* - * All lockusers keep their watch request and drop their - * own (lu_myreq) request. Their own request is either - * some other lockuser's watch request or is the head of - * the lock. - */ - lu->lu_myreq = lu->lu_watchreq; - if (lu->lu_myreq == NULL) + + if (lu->lu_watchreq != NULL) { + /* + * In this case the lock is active. All lockusers + * keep their watch request and drop their own + * (lu_myreq) request. Their own request is either + * some other lockuser's watch request or is the + * head of the lock. + */ + lu->lu_myreq = lu->lu_watchreq; + lu->lu_watchreq = NULL; + } + if (lu->lu_myreq == NULL) + /* + * Oops, something isn't quite right. Try to + * allocate one. + */ return (_lockuser_init(lu, priv)); else { lu->lu_myreq->lr_locked = 1; diff -ru lib/libpthread.orig/thread/thr_kern.c lib/libpthread/thread/ thr_kern.c --- lib/libpthread.orig/thread/thr_kern.c 2008-01-30 16:30:07.000000000 -0800 +++ lib/libpthread/thread/thr_kern.c 2008-01-30 16:55:19.000000000 -0800 @@ -345,6 +345,17 @@ _LCK_SET_PRIVATE2(&curthread->kse->k_lockusers[i], NULL); } curthread->kse->k_locklevel = 0; + + /* + * Reinitialize the thread and signal locks so that + * sigaction() will work after a fork(). + */ + _lock_reinit(&curthread->lock, LCK_ADAPTIVE, _thr_lock_wait, + _thr_lock_wakeup); + _lock_reinit(&_thread_signal_lock, LCK_ADAPTIVE, _kse_lock_wait, + _kse_lock_wakeup); + + _thr_spinlock_init(); if (__isthreaded) { _thr_rtld_fini(); @@ -354,6 +365,20 @@ curthread->kse->k_kcb->kcb_kmbx.km_curthread = NULL; curthread->attr.flags |= PTHREAD_SCOPE_SYSTEM; + /* + * After a fork, it is possible that an upcall occurs in + * the parent KSE that fork()'d before the child process + * is fully created and before its vm space is copied. + * During the upcall, the tcb is set to null or to another + * thread, and this is what gets copied in the child process + * when the vm space is cloned sometime after the upcall + * occurs. Note that we shouldn't have to set the kcb, but + * we do it for completeness. + */ + _kcb_set(curthread->kse->k_kcb); + _tcb_set(curthread->kse->k_kcb, curthread->tcb); + + /* After a fork(), there child should have no pending signals. */ sigemptyset(&curthread->sigpend); --Apple-Mail-1-125705283 content-type: application/pgp-signature; x-mac-type=70674453; name=PGP.sig content-description: This is a digitally signed message part content-disposition: inline; filename=PGP.sig content-transfer-encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) iD8DBQFHoZLElplZCE/15mMRAv73AJ0eMwfbrarcHAWeg5D026EYtYu08ACeJb1z FD9UQa43xswZF9ugzWCr9Kw= =ACc/ -----END PGP SIGNATURE----- --Apple-Mail-1-125705283--