HDK
Main Page
Related Pages
Modules
Namespaces
Classes
Files
Examples
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
UT_DoubleLock.h
Go to the documentation of this file.
1
/*
2
* PROPRIETARY INFORMATION. This software is proprietary to
3
* Side Effects Software Inc., and is not to be reproduced,
4
* transmitted, or disclosed in any way without written permission.
5
*
6
* NAME: UT_DoubleLock.h ( UT Library, C++)
7
*
8
* COMMENTS:
9
*/
10
11
#ifndef __UT_DoubleLock__
12
#define __UT_DoubleLock__
13
14
#include "
UT_API.h
"
15
16
#include "
UT_NonCopyable.h
"
17
#include "
UT_Lock.h
"
18
#include <
SYS/SYS_MemoryOrder.h
>
19
20
///
21
/// A double-checked lock. Only locks the thread lock when the value is 0.
22
///
23
/// To use this lock:
24
///
25
/// static UT_Lock theLock;
26
/// static OBJECT *theObj = 0;
27
///
28
/// OBJECT *
29
/// getSingleton()
30
/// {
31
/// UT_DoubleLock<OBJECT *> lock(theLock, theObj);
32
///
33
/// if (!lock.getValue())
34
/// {
35
/// // NOTE: This doesn't set theObj. theObj is set when
36
/// // destructing lock.
37
/// lock.setValue(new OBJECT());
38
/// }
39
/// return lock.getValue();
40
/// }
41
///
42
/// NOTE: DO NOT roll your own double checked lock! If you
43
/// don't know when to use which memory fences and why,
44
/// odds are high that your custom implementation will be
45
/// thread-unsafe.
46
///
47
/// For simple singleton initialization, consider using UT_Singleton.
48
///
49
template
<
typename
T,
typename
LOCK_T = UT_Lock>
50
class
UT_DoubleLock
:
UT_NonCopyable
51
{
52
public
:
53
UT_DoubleLock
(LOCK_T &lock,
volatile
T
&
val
)
54
: myLock(lock)
55
, myValue(val)
56
, myPendingValue(0)
57
, myIsLocked(false)
58
, myNeedInit(false)
59
{
60
if
(!val)
61
{
62
myLock.lock();
63
myIsLocked =
true
;
64
if
(!val)
65
myNeedInit =
true
;
66
}
67
}
68
69
~UT_DoubleLock
()
70
{
71
if
(myIsLocked)
72
{
73
if
(myNeedInit)
74
{
75
UT_ASSERT_P
(myPendingValue);
76
77
// Ensure that the data that myPendingValue refers to is
78
// written out to main memory before setting myValue.
79
SYSstoreFence
();
80
81
myValue = myPendingValue;
82
83
// NOTE: LOCK_T::unlock also does a store fence before
84
// unlocking, which ensures that myValue is written out to
85
// main memory before the lock is unlocked. If it didn't,
86
// the next thread might read myValue of 0 and try to
87
// initialize it again. The store fence above is also
88
// needed.
89
}
90
myLock.unlock();
91
}
92
}
93
94
T
getValue
()
95
{
96
T
v
= myPendingValue;
97
if
(v)
98
return
v
;
99
100
v = myValue;
101
102
// This load fence is to ensure that any side effects of allocation
103
// in another thread, including values in the heap itself, are not
104
// speculatively read before the read of myValue. Also, some places
105
// do more than allocate a single item pointed to by v, especially
106
// for cases with UT_DoubleLock<bool>, so those count as side
107
// effects here.
108
SYSloadFence
();
109
110
return
v
;
111
}
112
void
setValue
(
T
val
)
113
{
114
UT_ASSERT_P
(myNeedInit);
115
myPendingValue =
val
;
116
}
117
118
/// Abort writing back out to the val passed in the constructor upon
119
/// destruction.
120
void
abort
()
121
{
122
myNeedInit =
false
;
123
}
124
125
private
:
126
LOCK_T &myLock;
127
volatile
T
&myValue;
128
T
myPendingValue;
129
bool
myIsLocked;
130
bool
myNeedInit;
131
};
132
133
#endif
134
SYSloadFence
#define SYSloadFence()
Definition:
SYS_MemoryOrder.h:35
UT_DoubleLock
Definition:
UT_DoubleLock.h:50
UT_API.h
UT_DoubleLock::abort
void abort()
Definition:
UT_DoubleLock.h:120
UT_DoubleLock::UT_DoubleLock
UT_DoubleLock(LOCK_T &lock, volatile T &val)
Definition:
UT_DoubleLock.h:53
UT_DoubleLock::getValue
T getValue()
Definition:
UT_DoubleLock.h:94
UT_ASSERT_P
#define UT_ASSERT_P(ZZ)
Definition:
UT_Assert.h:152
v
const GLdouble * v
Definition:
glcorearb.h:837
UT_DoubleLock::setValue
void setValue(T val)
Definition:
UT_DoubleLock.h:112
SYSstoreFence
#define SYSstoreFence()
Definition:
SYS_MemoryOrder.h:36
OBJ_MatchTransform::T
UT_NonCopyable.h
val
GLuint GLfloat * val
Definition:
glcorearb.h:1608
UT_DoubleLock::~UT_DoubleLock
~UT_DoubleLock()
Definition:
UT_DoubleLock.h:69
SYS_MemoryOrder.h
UT_NonCopyableNS::UT_NonCopyable
Definition:
UT_NonCopyable.h:17
UT_Lock.h
UT
UT_DoubleLock.h
Generated on Wed Aug 10 2022 02:56:38 for HDK by
1.8.6