Skip to content

Commit 657ef8e

Browse files
committed
Merge pull request #1869 from cpeterso/master
rt: lock_and_signal fixes
2 parents 4a3d551 + fed81c2 commit 657ef8e

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

src/rt/sync/lock_and_signal.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,18 @@ lock_and_signal::lock_and_signal()
1919
: _holding_thread(INVALID_THREAD)
2020
{
2121
_event = CreateEvent(NULL, FALSE, FALSE, NULL);
22-
InitializeCriticalSection(&_cs);
22+
23+
// If a CRITICAL_SECTION is not initialized with a spin count, it will
24+
// default to 0, even on multi-processor systems. MSDN suggests using
25+
// 4000. On single-processor systems, the spin count parameter is ignored
26+
// and the critical section's spin count defaults to 0.
27+
const DWORD SPIN_COUNT = 4000;
28+
CHECKED(!InitializeCriticalSectionAndSpinCount(&_cs, SPIN_COUNT));
29+
30+
// TODO? Consider checking GetProcAddress("InitializeCriticalSectionEx")
31+
// so Windows >= Vista we can use CRITICAL_SECTION_NO_DEBUG_INFO to avoid
32+
// allocating CRITICAL_SECTION debug info that is never released. See:
33+
// http://stackoverflow.com/questions/804848/critical-sections-leaking-memory-on-vista-win2008#889853
2334
}
2435

2536
#else
@@ -32,15 +43,18 @@ lock_and_signal::lock_and_signal()
3243
#endif
3344

3445
lock_and_signal::~lock_and_signal() {
46+
assert(_holding_thread == INVALID_THREAD);
3547
#if defined(__WIN32__)
3648
CloseHandle(_event);
49+
DeleteCriticalSection(&_cs);
3750
#else
3851
CHECKED(pthread_cond_destroy(&_cond));
3952
CHECKED(pthread_mutex_destroy(&_mutex));
4053
#endif
4154
}
4255

4356
void lock_and_signal::lock() {
57+
assert(!lock_held_by_current_thread());
4458
#if defined(__WIN32__)
4559
EnterCriticalSection(&_cs);
4660
_holding_thread = GetCurrentThreadId();
@@ -51,6 +65,7 @@ void lock_and_signal::lock() {
5165
}
5266

5367
void lock_and_signal::unlock() {
68+
assert(lock_held_by_current_thread());
5469
_holding_thread = INVALID_THREAD;
5570
#if defined(__WIN32__)
5671
LeaveCriticalSection(&_cs);
@@ -69,9 +84,11 @@ void lock_and_signal::wait() {
6984
LeaveCriticalSection(&_cs);
7085
WaitForSingleObject(_event, INFINITE);
7186
EnterCriticalSection(&_cs);
87+
assert(_holding_thread == INVALID_THREAD);
7288
_holding_thread = GetCurrentThreadId();
7389
#else
7490
CHECKED(pthread_cond_wait(&_cond, &_mutex));
91+
assert(_holding_thread == INVALID_THREAD);
7592
_holding_thread = pthread_self();
7693
#endif
7794
}

0 commit comments

Comments
 (0)