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