Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Jul 2009 09:31:04 +0000 (UTC)
From:      Attilio Rao <attilio@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r195403 - head/lib/libthr/thread
Message-ID:  <200907060931.n669V4Zc074488@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: attilio
Date: Mon Jul  6 09:31:04 2009
New Revision: 195403
URL: http://svn.freebsd.org/changeset/base/195403

Log:
  In the current code, rdlock_count is not correctly handled for some cases.
  The most notable is that it is not bumped in rwlock_rdlock_common() when
  the hard path (__thr_rwlock_rdlock()) returns successfully.
  This can lead to deadlocks in libthr when rwlocks recursion in read mode
  happens.
  Fix the interested parts by correctly handling rdlock_count.
  
  PR:		threads/136345
  Reported by:	rink
  Tested by:	rink
  Reviewed by:	jeff
  Approved by:	re (kib)
  MFC:		2 weeks

Modified:
  head/lib/libthr/thread/thr_rtld.c
  head/lib/libthr/thread/thr_rwlock.c

Modified: head/lib/libthr/thread/thr_rtld.c
==============================================================================
--- head/lib/libthr/thread/thr_rtld.c	Mon Jul  6 09:07:35 2009	(r195402)
+++ head/lib/libthr/thread/thr_rtld.c	Mon Jul  6 09:31:04 2009	(r195403)
@@ -114,6 +114,7 @@ _thr_rtld_rlock_acquire(void *lock)
 	THR_CRITICAL_ENTER(curthread);
 	while (_thr_rwlock_rdlock(&l->lock, 0, NULL) != 0)
 		;
+	curthread->rdlock_count++;
 	RESTORE_ERRNO();
 }
 
@@ -148,6 +149,7 @@ _thr_rtld_lock_release(void *lock)
 	
 	state = l->lock.rw_state;
 	if (_thr_rwlock_unlock(&l->lock) == 0) {
+		curthread->rdlock_count--;
 		if ((state & URWLOCK_WRITE_OWNER) == 0) {
 			THR_CRITICAL_LEAVE(curthread);
 		} else {

Modified: head/lib/libthr/thread/thr_rwlock.c
==============================================================================
--- head/lib/libthr/thread/thr_rwlock.c	Mon Jul  6 09:07:35 2009	(r195402)
+++ head/lib/libthr/thread/thr_rwlock.c	Mon Jul  6 09:31:04 2009	(r195403)
@@ -177,10 +177,11 @@ rwlock_rdlock_common(pthread_rwlock_t *r
 		/* if interrupted, try to lock it in userland again. */
 		if (_thr_rwlock_tryrdlock(&prwlock->lock, flags) == 0) {
 			ret = 0;
-			curthread->rdlock_count++;
 			break;
 		}
 	}
+	if (ret == 0)
+		curthread->rdlock_count++;
 	return (ret);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907060931.n669V4Zc074488>