blob: 1326a841ecea3502c1cd798c78554ea7f62c7482 (
plain)
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
|
/*
* Copyright (C) 2007-2023 Xagasoft, All rights reserved.
*
* This file is part of the libbu++ library and is released under the
* terms of the license contained in the file LICENSE.
*/
#include "bu/readwritemutex.h"
Bu::ReadWriteMutex::ReadWriteMutex() :
iCounter( 0 ),
bWantWrite( false )
{
}
Bu::ReadWriteMutex::~ReadWriteMutex()
{
}
void Bu::ReadWriteMutex::lockRead()
{
// Check to see if someone wants to write
cWrite.lock();
if( bWantWrite )
{
// If so, wait patiently for them to finish
cWrite.wait();
}
cWrite.unlock();
// Now lock the read counter
mRead.lock();
iCounter++;
// If the lock counter is one, we just locked for the first time,
// so we lock the writer.
if( iCounter == 1 )
mWrite.lock();
mRead.unlock();
}
void Bu::ReadWriteMutex::unlockRead()
{
// Lock the read counter
mRead.lock();
iCounter--;
// If we just decremented the counter back to zero then we can
// release the write lock
if( iCounter == 0 )
mWrite.unlock();
mRead.unlock();
}
//
// The bWantWrite could be a counter like the read lock counter, however
// once a write lock occurs and bWantWrite is set at least one write
// will definately occur. In practice most writes all happen one after
// the other anyway and this way reads get a chance to mingle in.
//
// Really, just getting all current reads to stop so a write can happen
// I think is sufficient right now.
//
void Bu::ReadWriteMutex::lockWrite()
{
// Lock the read counter
mRead.lock();
if( iCounter > 0 )
{
// If there is an active read in progress then we set the bWantWrite
// flag to make sure no more readers start working.
cWrite.lock();
bWantWrite = true;
cWrite.unlock();
}
mRead.unlock();
// Lock the write lock
mWrite.lock();
}
void Bu::ReadWriteMutex::unlockWrite()
{
// Just always set the bWantWrite flag to false at this point, as long
// as we're locked.
cWrite.lock();
bWantWrite = false;
cWrite.unlock();
// Release all waiting readers, they won't actually do much until we
// unlock the write lock though
cWrite.broadcast();
// Unlock the write lock
mWrite.unlock();
}
|