svn commit: r309630 - head/lib/libthr/thread

Konstantin Belousov kib at FreeBSD.org
Tue Dec 6 17:13:18 UTC 2016


Author: kib
Date: Tue Dec  6 17:13:17 2016
New Revision: 309630
URL: https://svnweb.freebsd.org/changeset/base/309630

Log:
  Do not leak curthread->inact_mtx when cancelling in pthread_cond_wait(3).
  
  Leave robust-protected region before checking for cancellation by
  calling _thr_testcancel().  Otherwise, if cancelling request was
  pending, the cancel handler is called with the dandling inact_mtx,
  which triggers an assert if any mutex operation is performed by the
  handler.
  
  Reported and tested by:	Dimitri Staessens <dimitri.staessens at intec.ugent.be>
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/lib/libthr/thread/thr_cond.c

Modified: head/lib/libthr/thread/thr_cond.c
==============================================================================
--- head/lib/libthr/thread/thr_cond.c	Tue Dec  6 17:10:17 2016	(r309629)
+++ head/lib/libthr/thread/thr_cond.c	Tue Dec  6 17:13:17 2016	(r309630)
@@ -224,16 +224,26 @@ cond_wait_kernel(struct pthread_cond *cv
 		 * 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)


More information about the svn-src-head mailing list