Date: Tue, 6 Dec 2016 16:48:12 +0200 From: Konstantin Belousov <kostikbel@gmail.com> To: Dimitri Staessens <dimitri.staessens@intec.ugent.be> Cc: freebsd-threads@freebsd.org Subject: Re: Unlocking a robust mutex in a cleanup handler Message-ID: <20161206144812.GS54029@kib.kiev.ua> In-Reply-To: <6a7139cd-b6db-d078-ee5e-b7c590eb13d1@intec.ugent.be> References: <119e59d4-6125-f313-e6e6-67055a15d224@intec.ugent.be> <20161206112558.GN54029@kib.kiev.ua> <6a7139cd-b6db-d078-ee5e-b7c590eb13d1@intec.ugent.be>
next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Dec 06, 2016 at 03:17:41PM +0100, Dimitri Staessens wrote: > Dear Konstantin, > > thanks for your immediate response. Please find attached a minimal code > example. I do hope I'm sending in the correct format, I'm new to the > community. > > The test creates an integer, robust mutex and condition variable in > shared memory. A thread blocks on that condition variable with the > associated mutex. After one second, the main thread cancels the blocking > thread. > > I compile as follows: > > gcc robust_test.c -lpthread -lrt -o robust_test > > and run > > ./robust_test > > On linux it gives the following output: > [dstaesse@phoneutria]$ ./robust_test > Initializing... > Starting thread... > Sleeping for one second... > Thread started... > Cancelling thread... > Thread finished. > Bye. > > On FreeBSD I get the following: > $ ./robust_test > Initializing... > Starting thread... > Sleeping for one second... > Thread started... > Cancelling thread... > Fatal error 'inact_mtx enter' at line 188 in file > /usr/src/lib/libthr/thread/thr_mutex.c (errno = 0) > Abort trap (core dumped) Try this patch. It worked for me. It is enough to patch and then rebuild only libthr: cd /usr/src patch -p1 <patch (cd lib/libthr && make WITHOUT_TESTS=yes all install) diff --git a/lib/libthr/thread/thr_cond.c b/lib/libthr/thread/thr_cond.c index 506b8eca9e7..64d075ca06f 100644 --- a/lib/libthr/thread/thr_cond.c +++ b/lib/libthr/thread/thr_cond.c @@ -224,16 +224,26 @@ cond_wait_kernel(struct pthread_cond *cvp, struct pthread_mutex *mp, * state and unlock the mutex without making the state * consistent and the state will be unrecoverable. */ - if (error2 == 0 && cancel) + if (error2 == 0 && cancel) { + if (robust) { + _mutex_leave_robust(curthread, mp); + robust = false; + } _thr_testcancel(curthread); + } if (error == EINTR) error = 0; } else { /* We know that it didn't unlock the mutex. */ _mutex_cv_attach(mp, recurse); - if (cancel) + if (cancel) { + if (robust) { + _mutex_leave_robust(curthread, mp); + robust = false; + } _thr_testcancel(curthread); + } error2 = 0; } if (robust)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20161206144812.GS54029>