-
Notifications
You must be signed in to change notification settings - Fork 2
/
windows_condition.h
88 lines (74 loc) · 1.75 KB
/
windows_condition.h
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
#pragma once
#include "mutex_lock.h"
#include <WinBase.h>
namespace util {
bool IsWindowsXP()
{
return true;
static int result = -1;
if (-1 == result) {
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
bool isXp = osvi.dwMajorVersion < 6;
result = isXp ? 1 : 0;
return result ? true : false;
}
return result ? true : false;
}
}
class Condition
{
public:
explicit Condition(CMutexLock &mutex)
: mutex_(mutex)
{
if (util::IsWindowsXP()) {
cond_ = new CondType();
((CondType*)cond_)->signal = CreateEvent(NULL, false, false, NULL);
((CondType*)cond_)->broadcast = CreateEvent(NULL, true, false, NULL);
} else {
cond_ = new CONDITION_VARIABLE();
InitializeConditionVariable((PCONDITION_VARIABLE)cond_);
}
}
Condition::~Condition()
{
if (util::IsWindowsXP()) {
CondType *p = (CondType*)cond_;
CloseHandle(p->signal);
CloseHandle(p->broadcast);
delete p;
} else {
CONDITION_VARIABLE *p = (CONDITION_VARIABLE*)cond_;
delete p;
}
}
void wait()
{
if (util::IsWindowsXP()) {
mutex_.unlock();
HANDLE handles[] = {((CondType*)cond_)->signal, ((CondType*)cond_)->broadcast};
WaitForMultipleObjects(2, handles, false, INFINITE);
mutex_.lock();
} else {
SleepConditionVariableCS((PCONDITION_VARIABLE)cond_, (CRITICAL_SECTION*)(mutex_.cs()), INFINITE);
}
}
void notify()
{
if (util::IsWindowsXP()) {
SetEvent(((CondType*)cond_)->signal);
} else {
WakeConditionVariable((PCONDITION_VARIABLE)cond_);
}
}
private:
Condition(const Condition&);
Condition& operator=(const Condition&);
private:
CMutexLock &mutex_;
void *cond_;
typedef struct { HANDLE signal, broadcast; } CondType;
};