From: VMware, Inc <> Date: Thu, 17 Jun 2010 21:32:28 +0000 (-0700) Subject: lib/lock: generalize MXUser condVar support X-Git-Tag: 2010.06.16-268169~107 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ff64bc80ee2e5c97042b1bcd8109bab394fc3997;p=thirdparty%2Fopen-vm-tools.git lib/lock: generalize MXUser condVar support The MXUser condVar code dealt only with a lock count of 1, something that is OK for exclusive locks and recursive locks with that lock count but not correct for recursive locks in the general case. Fix this by properly preserving the lock count. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/lib/lock/ulCondVar.c b/open-vm-tools/lib/lock/ulCondVar.c index 1e8057824..af79be90a 100644 --- a/open-vm-tools/lib/lock/ulCondVar.c +++ b/open-vm-tools/lib/lock/ulCondVar.c @@ -233,6 +233,7 @@ MXUserWaitInternal(MXUserHeader *header, // IN: DWORD err; Bool signalled; + uint32 lockCount = MXRecLockCount(lock); DWORD waitTime = (msecWait == MXUSER_WAIT_INFINITE) ? INFINITE : msecWait; if (pSleepConditionVariableCS) { @@ -246,11 +247,11 @@ MXUserWaitInternal(MXUserHeader *header, // IN: * The MXUser internal accounting information must be maintained. */ - MXRecLockDecCount(lock); + MXRecLockDecCount(lock, lockCount); success = (*pSleepConditionVariableCS)(&condVar->x.condObject, &lock->nativeLock, waitTime); err = success ? ERROR_SUCCESS : GetLastError(); - MXRecLockIncCount(lock, GetReturnAddress()); + MXRecLockIncCount(lock, GetReturnAddress(), lockCount); signalled = (err == ERROR_SUCCESS) ? TRUE : FALSE; } else { Bool done = FALSE; @@ -259,6 +260,7 @@ MXUserWaitInternal(MXUserHeader *header, // IN: condVar->x.compat.numWaiters++; LeaveCriticalSection(&condVar->x.compat.condVarLock); + MXRecLockDecCount(lock, lockCount - 1); MXRecLockRelease(lock); do { @@ -305,6 +307,7 @@ MXUserWaitInternal(MXUserHeader *header, // IN: } while (!done); MXRecLockAcquire(lock, GetReturnAddress()); + MXRecLockIncCount(lock, GetReturnAddress(), lockCount - 1); } if (err != ERROR_SUCCESS) { @@ -466,6 +469,7 @@ MXUserWaitInternal(MXUserHeader *header, // IN: { int err; Bool signalled; + uint32 lockCount = MXRecLockCount(lock); /* * When using the native lock found within the MXUser lock, be sure to @@ -475,7 +479,7 @@ MXUserWaitInternal(MXUserHeader *header, // IN: * MXUser internal accounting information must be maintained. */ - MXRecLockDecCount(lock); + MXRecLockDecCount(lock, lockCount); if (msecWait == MXUSER_WAIT_INFINITE) { err = pthread_cond_wait(&condVar->condObject, &lock->nativeLock); @@ -497,7 +501,7 @@ MXUserWaitInternal(MXUserHeader *header, // IN: } } - MXRecLockIncCount(lock, GetReturnAddress()); + MXRecLockIncCount(lock, GetReturnAddress(), lockCount); if (err != 0) { MXUserDumpAndPanic(header, "%s: failure %d on condVar (%p; %s)\n", @@ -633,9 +637,9 @@ MXUserWaitCondVar(MXUserHeader *header, // IN: __FUNCTION__, header->lockName, condVar->name); } - if (MXRecLockCount(lock) == 0) { + if (!MXRecLockIsOwner(lock)) { MXUserDumpAndPanic(header, - "%s: unlocked lock %s with condVar (%p; %s)\n", + "%s: do not own lock %s for condVar (%p; %s)\n", __FUNCTION__, header->lockName, condVar->name); } diff --git a/open-vm-tools/lib/lock/ulInt.h b/open-vm-tools/lib/lock/ulInt.h index b76395000..5d66083aa 100644 --- a/open-vm-tools/lib/lock/ulInt.h +++ b/open-vm-tools/lib/lock/ulInt.h @@ -262,7 +262,8 @@ MXRecLockCount(const MXRecLock *lock) // IN: static INLINE void MXRecLockIncCount(MXRecLock *lock, // IN/OUT: - void *location) // IN: + void *location, // IN: + uint32 count) // IN: { if (MXRecLockCount(lock) == 0) { #if defined(MXUSER_DEBUG) @@ -275,7 +276,7 @@ MXRecLockIncCount(MXRecLock *lock, // IN/OUT: MXRecLockSetOwner(lock); } - lock->referenceCount++; + lock->referenceCount += count; } @@ -313,7 +314,7 @@ MXRecLockAcquire(MXRecLock *lock, // IN/OUT: ASSERT(lock->referenceCount == 0); } - MXRecLockIncCount(lock, location); + MXRecLockIncCount(lock, location, 1); return contended; } @@ -329,7 +330,7 @@ MXRecLockTryAcquire(MXRecLock *lock, // IN/OUT: err = MXRecLockTryAcquireInternal(lock); if (err == 0) { - MXRecLockIncCount(lock, location); + MXRecLockIncCount(lock, location, 1); ASSERT((MXRecLockCount(lock) > 0) && (MXRecLockCount(lock) < MXUSER_MAX_REC_DEPTH)); @@ -348,9 +349,11 @@ MXRecLockTryAcquire(MXRecLock *lock, // IN/OUT: } static INLINE void -MXRecLockDecCount(MXRecLock *lock) // IN/OUT: +MXRecLockDecCount(MXRecLock *lock, // IN/OUT: + uint32 count) // IN: { - lock->referenceCount--; + ASSERT(count <= lock->referenceCount); + lock->referenceCount -= count; if (MXRecLockCount(lock) == 0) { MXRecLockSetNoOwner(lock); @@ -369,7 +372,7 @@ MXRecLockRelease(MXRecLock *lock) // IN/OUT: ASSERT((MXRecLockCount(lock) > 0) && (MXRecLockCount(lock) < MXUSER_MAX_REC_DEPTH)); - MXRecLockDecCount(lock); + MXRecLockDecCount(lock, 1); if (MXRecLockCount(lock) == 0) { int err = MXRecLockReleaseInternal(lock);