Re: Thread-unsafe access to lock->owner in PR_Lock
Dave Hylands <[email protected]> Thu, 19 Dec 2013 15:08:24 -0800 (PST)
| Newsgroups | gmane.comp.mozilla.devel.nspr |
|---|---|
| Message-ID | <[email protected]> |
Hi Alexander, ----- Original Message ----- > From: "Alexander Potapenko" <[email protected]> > To: [email protected] > Sent: Wednesday, December 18, 2013 3:46:30 AM > Subject: Thread-unsafe access to lock->owner in PR_Lock > > Hi NSPR developers, > > while running Chromium tests under ThreadSanitizer > (https://code.google.com/p/data-race-test/) we've encountered a report about > a data race between PR_Lock and PR_Unlock: http://crbug.com/328521 > > It turns out that the lock->owner variable is being read by PR_Lock at the > same time other threads read or write it in PR_Lock or PR_Unlock: > > 189 PR_IMPLEMENT(void) PR_Lock(PRLock *lock) > 190 { > 191 PRThread *me = _PR_MD_CURRENT_THREAD(); > 192 PRIntn is; > 193 PRThread *t; > 194 PRCList *q; > 195 > 196 PR_ASSERT(me != suspendAllThread); > 197 PR_ASSERT(!(me->flags & _PR_IDLE_THREAD)); > 198 PR_ASSERT(lock != NULL); > 199 #ifdef _PR_GLOBAL_THREADS_ONLY > 200 PR_ASSERT(lock->owner != me); > 201 _PR_MD_LOCK(&lock->ilock); > 202 lock->owner = me; > 203 return; > 204 #else /* _PR_GLOBAL_THREADS_ONLY */ > > (code from nspr-4.9.5/mozilla/nsprpub/pr/src/threads/combined/prulock.c in > Ubuntu Precise) > > In the case the optimizer is conservative enough nothing will break (during > the race lock->owner will be either another thread or NULL, but not |me|), > but this is undefined behavior in C++11 and can possibly break in newer > compilers. > > Is there a reason to do this check before the lock is taken? I'm guessing > it's there to avoid reentrancy, so it should be fine to swap lines 200 and > 201. If my understanding is correct, if you swap the 2 lines, then you may deadlock yourself rather than see the assert. http://mozilla.6506.n7.nabble.com/Are-PR-Locks-thread-re-entrant-td244962.html Dave Hylands