Index: nspr/pr/src/md/windows/w95cv.c |
=================================================================== |
--- nspr/pr/src/md/windows/w95cv.c (revision 233722) |
+++ nspr/pr/src/md/windows/w95cv.c (working copy) |
@@ -304,6 +304,59 @@ |
return; |
} |
+typedef BOOL (WINAPI *INITIALIZECRITICALSECTIONEX)( |
+ CRITICAL_SECTION *lpCriticalSection, |
+ DWORD dwSpinCount, |
+ DWORD Flags); |
+ |
+static INITIALIZECRITICALSECTIONEX sInitializeCriticalSectionEx; |
+ |
+void _PR_MD_INIT_LOCKS(void) |
+{ |
+ /* |
+ * Starting with Windows Vista, every CRITICAL_SECTION allocates an extra |
+ * RTL_CRITICAL_SECTION_DEBUG object. Unfortunately, this debug object is |
+ * not reclaimed by DeleteCriticalSection(), causing an apparent memory |
+ * leak. This is a debugging "feature", not a bug. If we are running on |
+ * Vista or later, use InitializeCriticalSectionEx() to allocate |
+ * CRITICAL_SECTIONs without debug objects. |
+ */ |
+ HMODULE hKernel32 = GetModuleHandle("kernel32.dll"); |
+ PR_ASSERT(hKernel32); |
+ PR_ASSERT(!sInitializeCriticalSectionEx); |
+ sInitializeCriticalSectionEx = (INITIALIZECRITICALSECTIONEX) |
+ GetProcAddress(hKernel32, "InitializeCriticalSectionEx"); |
+} |
+ |
+/* |
+ * By default, CRITICAL_SECTIONs are initialized with a spin count of 0. |
+ * Joe Duffy's "Concurrent Programming on Windows" book suggests 1500 is |
+ * a "reasonable starting point". On single-processor systems, the spin |
+ * count is ignored and the critical section spin count is set to 0. |
+ */ |
+#define LOCK_SPIN_COUNT 1500 |
+ |
+PRStatus _PR_MD_NEW_LOCK(_MDLock *lock) |
+{ |
+ CRITICAL_SECTION *cs = &lock->mutex; |
+ BOOL ok; |
+ |
+ if (sInitializeCriticalSectionEx) { |
+ ok = sInitializeCriticalSectionEx(cs, LOCK_SPIN_COUNT, |
+ CRITICAL_SECTION_NO_DEBUG_INFO); |
+ } else { |
+ ok = InitializeCriticalSectionAndSpinCount(cs, LOCK_SPIN_COUNT); |
+ } |
+ if (!ok) { |
+ _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); |
+ return PR_FAILURE; |
+ } |
+ |
+ lock->notified.length = 0; |
+ lock->notified.link = NULL; |
+ return PR_SUCCESS; |
+} |
+ |
void _PR_MD_UNLOCK(_MDLock *lock) |
{ |
if (0 != lock->notified.length) { |
@@ -311,5 +364,4 @@ |
} else { |
LeaveCriticalSection(&lock->mutex); |
} |
- return; |
} |