@@ -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
3445lock_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
4356void 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
5367void 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