1 /*
2 * Copyright (c) 2010 SURFnet bv
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 /*****************************************************************************
28 MutexFactory.cpp
29
30 This factory produces OS specific mutex objects
31 *****************************************************************************/
32
33 #include "config.h"
34 #include "MutexFactory.h"
35 #include "osmutex.h"
36 #include <memory>
37 #include <stddef.h>
38
39 /*****************************************************************************
40 Mutex implementation
41 *****************************************************************************/
42
43 // Constructor
Mutex()44 Mutex::Mutex()
45 {
46 isValid = (MutexFactory::i()->CreateMutex(&handle) == CKR_OK);
47 }
48
49 // Destructor
~Mutex()50 Mutex::~Mutex()
51 {
52 if (isValid)
53 {
54 MutexFactory::i()->DestroyMutex(handle);
55 }
56 }
57
58 // Lock the mutex
lock()59 bool Mutex::lock()
60 {
61 return (isValid && (MutexFactory::i()->LockMutex(handle) == CKR_OK));
62 }
63
64 // Unlock the mutex
unlock()65 void Mutex::unlock()
66 {
67 if (isValid)
68 {
69 MutexFactory::i()->UnlockMutex(handle);
70 }
71 }
72
73 /*****************************************************************************
74 MutexLocker implementation
75 *****************************************************************************/
76
77 // Constructor
MutexLocker(Mutex * inMutex)78 MutexLocker::MutexLocker(Mutex* inMutex)
79 {
80 mutex = inMutex;
81
82 if (mutex != NULL) mutex->lock();
83 }
84
85 // Destructor
~MutexLocker()86 MutexLocker::~MutexLocker()
87 {
88 if (mutex != NULL) mutex->unlock();
89 }
90
91 /*****************************************************************************
92 MutexFactory implementation
93 *****************************************************************************/
94
95 // Constructor
MutexFactory()96 MutexFactory::MutexFactory()
97 {
98 createMutex = OSCreateMutex;
99 destroyMutex = OSDestroyMutex;
100 lockMutex = OSLockMutex;
101 unlockMutex = OSUnlockMutex;
102
103 enabled = true;
104 }
105
106 // Destructor
~MutexFactory()107 MutexFactory::~MutexFactory()
108 {
109 }
110
111 // Return the one-and-only instance
i()112 MutexFactory* MutexFactory::i()
113 {
114 if (!instance.get())
115 {
116 instance.reset(new MutexFactory());
117 }
118
119 return instance.get();
120 }
121
122 // Get a mutex instance
getMutex()123 Mutex* MutexFactory::getMutex()
124 {
125 return new Mutex();
126 }
127
128 // Recycle a mutex instance
recycleMutex(Mutex * mutex)129 void MutexFactory::recycleMutex(Mutex* mutex)
130 {
131 if (mutex != NULL) delete mutex;
132 }
133
134 // Set the function pointers
setCreateMutex(CK_CREATEMUTEX inCreateMutex)135 void MutexFactory::setCreateMutex(CK_CREATEMUTEX inCreateMutex)
136 {
137 createMutex = inCreateMutex;
138 }
139
setDestroyMutex(CK_DESTROYMUTEX inDestroyMutex)140 void MutexFactory::setDestroyMutex(CK_DESTROYMUTEX inDestroyMutex)
141 {
142 destroyMutex = inDestroyMutex;
143 }
144
setLockMutex(CK_LOCKMUTEX inLockMutex)145 void MutexFactory::setLockMutex(CK_LOCKMUTEX inLockMutex)
146 {
147 lockMutex = inLockMutex;
148 }
149
setUnlockMutex(CK_UNLOCKMUTEX inUnlockMutex)150 void MutexFactory::setUnlockMutex(CK_UNLOCKMUTEX inUnlockMutex)
151 {
152 unlockMutex = inUnlockMutex;
153 }
154
enable()155 void MutexFactory::enable()
156 {
157 enabled = true;
158 }
159
disable()160 void MutexFactory::disable()
161 {
162 enabled = false;
163 }
164
CreateMutex(CK_VOID_PTR_PTR newMutex)165 CK_RV MutexFactory::CreateMutex(CK_VOID_PTR_PTR newMutex)
166 {
167 if (!enabled) return CKR_OK;
168
169 return (this->createMutex)(newMutex);
170 }
171
DestroyMutex(CK_VOID_PTR mutex)172 CK_RV MutexFactory::DestroyMutex(CK_VOID_PTR mutex)
173 {
174 if (!enabled) return CKR_OK;
175
176 return (this->destroyMutex)(mutex);
177 }
178
LockMutex(CK_VOID_PTR mutex)179 CK_RV MutexFactory::LockMutex(CK_VOID_PTR mutex)
180 {
181 if (!enabled) return CKR_OK;
182
183 return (this->lockMutex)(mutex);
184 }
185
UnlockMutex(CK_VOID_PTR mutex)186 CK_RV MutexFactory::UnlockMutex(CK_VOID_PTR mutex)
187 {
188 if (!enabled) return CKR_OK;
189
190 return (this->unlockMutex)(mutex);
191 }
192
193