blob: e9951a9a6933478a77e7dc561249f3b9e2092c97 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#ifndef _CRITSEC_H
#define _CRITSEC_H
#ifdef _WIN32
#include <windows.h>
#elif defined(__APPLE__)
#include <CoreServices/CoreServices.h>
#endif
#include <bfc/common.h>
#include <bfc/bfc_assert.h>
/**
CriticalSection is a portable object that implements a critical section,
which is to say, it ensures that no two threads can be in that same
section of code at the same time. Usually you make them a global object
or allocate them with new and pass them to both threads.
@short Critical section class.
@author Nullsoft
@ver 1.0
@see Thread
@see InCriticalSection
*/
class CriticalSection {
public:
CriticalSection();
virtual ~CriticalSection();
/**
Enters the critical section. If another thread is already in the critical
section, the calling thread will be blocked until the other thread calls
leave().
@see leave()
*/
void enter();
/**
Leaves the critical section. If another thread is currently blocked on
this critical section, it will be unblocked. If multiple threads are blocking
only one will be unblocked.
@see enter()
*/
void leave();
/**
Calls enter() and leave() in quick succession. Useful to make sure that no
other thread is in the critical section (although another thread could
immediately re-enter)
@see enter()
@see leave()
*/
void inout();
private:
#ifdef ASSERTS_ENABLED
int within;
#endif
#ifdef _WIN32
CRITICAL_SECTION cs;
#elif defined(__APPLE__)
MPCriticalRegionID cr;
#endif
};
/**
This is a little helper class to ease the use of class CriticalSection.
When it is instantiated, it enters a given critical section. When it is
destroyed, it leaves the given critical section.
CriticalSection a_cs;
void blah() {
InCriticalSection cs(a_cs); // critical section protection begins
if (test) {
return 0; // critical section protection ends
}
// critical section protection still active!
doSomething();
return 1; // critical section protection ends
}
@author Nullsoft
@see CriticalSection
*/
class InCriticalSection {
public:
InCriticalSection(CriticalSection *cs) : m_cs(cs) { m_cs->enter(); }
InCriticalSection(CriticalSection &cs) : m_cs(&cs) { m_cs->enter(); }
~InCriticalSection() { m_cs->leave(); }
private:
CriticalSection *m_cs;
};
#define _INCRITICALSECTION(id, x) InCriticalSection __I_C_S__##id(x)
#define INCRITICALSECTION(x) _INCRITICALSECTION(__LINE__, x)
#endif
|