@@ -19,7 +19,18 @@ lock_and_signal::lock_and_signal()
19
19
: _holding_thread(INVALID_THREAD)
20
20
{
21
21
_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
23
34
}
24
35
25
36
#else
@@ -32,15 +43,18 @@ lock_and_signal::lock_and_signal()
32
43
#endif
33
44
34
45
lock_and_signal::~lock_and_signal () {
46
+ assert (_holding_thread == INVALID_THREAD);
35
47
#if defined(__WIN32__)
36
48
CloseHandle (_event);
49
+ DeleteCriticalSection (&_cs);
37
50
#else
38
51
CHECKED (pthread_cond_destroy (&_cond));
39
52
CHECKED (pthread_mutex_destroy (&_mutex));
40
53
#endif
41
54
}
42
55
43
56
void lock_and_signal::lock () {
57
+ assert (!lock_held_by_current_thread ());
44
58
#if defined(__WIN32__)
45
59
EnterCriticalSection (&_cs);
46
60
_holding_thread = GetCurrentThreadId ();
@@ -51,6 +65,7 @@ void lock_and_signal::lock() {
51
65
}
52
66
53
67
void lock_and_signal::unlock () {
68
+ assert (lock_held_by_current_thread ());
54
69
_holding_thread = INVALID_THREAD;
55
70
#if defined(__WIN32__)
56
71
LeaveCriticalSection (&_cs);
@@ -69,9 +84,11 @@ void lock_and_signal::wait() {
69
84
LeaveCriticalSection (&_cs);
70
85
WaitForSingleObject (_event, INFINITE);
71
86
EnterCriticalSection (&_cs);
87
+ assert (_holding_thread == INVALID_THREAD);
72
88
_holding_thread = GetCurrentThreadId ();
73
89
#else
74
90
CHECKED (pthread_cond_wait (&_cond, &_mutex));
91
+ assert (_holding_thread == INVALID_THREAD);
75
92
_holding_thread = pthread_self ();
76
93
#endif
77
94
}
0 commit comments