forked from snowie2000/mactype
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ownedcs.cpp
61 lines (55 loc) · 1.65 KB
/
ownedcs.cpp
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
#include "ownedcs.h"
#include "windows.h"
#define InterlockedIncrementInt(x) InterlockedIncrement((volatile LONG *)&(x))
#define InterlockedDecrementInt(x) InterlockedDecrement((volatile LONG *)&(x))
#define InterlockedExchangeInt(x, y) InterlockedExchange((volatile LONG *)&(x), LONG(y))
void WINAPI InitializeOwnedCritialSection(POWNED_CRITIAL_SECTION cs)
{
cs->nOwner = -1;
cs->nRecursiveCount = 0;
cs->nRequests = -1;
cs->hEvent = CreateEvent(NULL, false, false, NULL);
InitializeCriticalSection(&cs->threadLock);
}
void WINAPI DeleteOwnedCritialSection(POWNED_CRITIAL_SECTION cs)
{
CloseHandle(cs->hEvent);
DeleteCriticalSection(&cs->threadLock);
}
void WINAPI EnterOwnedCritialSection(POWNED_CRITIAL_SECTION cs, WORD Owner)
{
EnterCriticalSection(&cs->threadLock);
if (cs->nOwner == Owner)
{
InterlockedIncrementInt(cs->nRecursiveCount);
LeaveCriticalSection(&cs->threadLock);
}
else
{
if (InterlockedIncrementInt(cs->nRequests)>0) //等待获取所有权
{
LeaveCriticalSection(&cs->threadLock);
WaitForSingleObject(cs->hEvent, INFINITE);
}
else
LeaveCriticalSection(&cs->threadLock);
InterlockedExchangeInt(cs->nOwner, Owner);//更改所有者
InterlockedExchangeInt(cs->nRecursiveCount, 1);//增加占用计数
}
}
void WINAPI LeaveOwnedCritialSection(POWNED_CRITIAL_SECTION cs, WORD Owner)
{
EnterCriticalSection(&cs->threadLock);
if (cs->nOwner == Owner)
{
if (InterlockedDecrementInt(cs->nRecursiveCount)<=0)
{
InterlockedExchangeInt(cs->nOwner, -1);//归还所有权
if (InterlockedDecrementInt(cs->nRequests)>=0)
SetEvent(cs->hEvent);
}
}
else
InterlockedDecrementInt(cs->nRecursiveCount);
LeaveCriticalSection(&cs->threadLock);
}