Imported Upstream version 3.13.6
[platform/upstream/nss.git] / mozilla / security / nss / lib / libpkix / pkix_pl_nss / system / pkix_pl_mutex.c
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is the PKIX-C library.
15  *
16  * The Initial Developer of the Original Code is
17  * Sun Microsystems, Inc.
18  * Portions created by the Initial Developer are
19  * Copyright 2004-2007 Sun Microsystems, Inc.  All Rights Reserved.
20  *
21  * Contributor(s):
22  *   Sun Microsystems, Inc.
23  *
24  * Alternatively, the contents of this file may be used under the terms of
25  * either the GNU General Public License Version 2 or later (the "GPL"), or
26  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27  * in which case the provisions of the GPL or the LGPL are applicable instead
28  * of those above. If you wish to allow use of your version of this file only
29  * under the terms of either the GPL or the LGPL, and not to allow others to
30  * use your version of this file under the terms of the MPL, indicate your
31  * decision by deleting the provisions above and replace them with the notice
32  * and other provisions required by the GPL or the LGPL. If you do not delete
33  * the provisions above, a recipient may use your version of this file under
34  * the terms of any one of the MPL, the GPL or the LGPL.
35  *
36  * ***** END LICENSE BLOCK ***** */
37 /*
38  * pkix_pl_mutex.c
39  *
40  * Mutual Exclusion (Lock) Object Functions
41  *
42  */
43
44 #include "pkix_pl_mutex.h"
45
46 /* --Private-Functions-------------------------------------------- */
47
48 /*
49  * FUNCTION: pkix_pl_Mutex_Destroy
50  * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
51  */
52 static PKIX_Error *
53 pkix_pl_Mutex_Destroy(
54         PKIX_PL_Object *object,
55         void *plContext)
56 {
57         PKIX_PL_Mutex *mutex = NULL;
58
59         PKIX_ENTER(MUTEX, "pkix_pl_Mutex_Destroy");
60         PKIX_NULLCHECK_ONE(object);
61
62         /* Sanity check: Test that "object" is a mutex */
63         PKIX_CHECK(pkix_CheckType(object, PKIX_MUTEX_TYPE, plContext),
64                     PKIX_OBJECTNOTMUTEX);
65
66         mutex = (PKIX_PL_Mutex*) object;
67
68         PKIX_MUTEX_DEBUG("\tCalling PR_DestroyLock).\n");
69         PR_DestroyLock(mutex->lock);
70         mutex->lock = NULL;
71
72 cleanup:
73
74         PKIX_RETURN(MUTEX);
75 }
76
77 /*
78  * FUNCTION: pkix_pl_Mutex_RegisterSelf
79  * DESCRIPTION:
80  *  Registers PKIX_MUTEX_TYPE and its related functions with systemClasses[]
81  * THREAD SAFETY:
82  *  Not Thread Safe - for performance and complexity reasons
83  *
84  *  Since this function is only called by PKIX_PL_Initialize, which should
85  *  only be called once, it is acceptable that this function is not
86  *  thread-safe.
87  */
88 PKIX_Error *
89 pkix_pl_Mutex_RegisterSelf(
90         /* ARGSUSED */ void *plContext)
91 {
92
93         extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
94         pkix_ClassTable_Entry entry;
95
96         PKIX_ENTER(MUTEX, "pkix_pl_Mutex_RegisterSelf");
97
98         entry.description = "Mutex";
99         entry.objCounter = 0;
100         entry.typeObjectSize = sizeof(PKIX_PL_Mutex);
101         entry.destructor = pkix_pl_Mutex_Destroy;
102         entry.equalsFunction = NULL;
103         entry.hashcodeFunction = NULL;
104         entry.toStringFunction = NULL;
105         entry.comparator = NULL;
106         entry.duplicateFunction = NULL;
107
108         systemClasses[PKIX_MUTEX_TYPE] = entry;
109
110         PKIX_RETURN(MUTEX);
111 }
112
113 /* --Public-Functions--------------------------------------------- */
114
115 /*
116  * FUNCTION: PKIX_PL_Mutex_Create (see comments in pkix_pl_system.h)
117  */
118 PKIX_Error *
119 PKIX_PL_Mutex_Create(
120         PKIX_PL_Mutex **pNewLock,
121         void *plContext)
122 {
123         PKIX_PL_Mutex *mutex = NULL;
124
125         PKIX_ENTER(MUTEX, "PKIX_PL_Mutex_Create");
126         PKIX_NULLCHECK_ONE(pNewLock);
127
128         PKIX_CHECK(PKIX_PL_Object_Alloc
129                     (PKIX_MUTEX_TYPE,
130                     sizeof (PKIX_PL_Mutex),
131                     (PKIX_PL_Object **)&mutex,
132                     plContext),
133                     PKIX_COULDNOTCREATELOCKOBJECT);
134
135         PKIX_MUTEX_DEBUG("\tCalling PR_NewLock).\n");
136         mutex->lock = PR_NewLock();
137
138         /* If an error occurred in NSPR, report it here */
139         if (mutex->lock == NULL) {
140                 PKIX_DECREF(mutex);
141                 PKIX_ERROR_ALLOC_ERROR();
142         }
143
144         *pNewLock = mutex;
145
146 cleanup:
147
148         PKIX_RETURN(MUTEX);
149 }
150
151 /*
152  * FUNCTION: PKIX_PL_Mutex_Lock (see comments in pkix_pl_system.h)
153  */
154 PKIX_Error *
155 PKIX_PL_Mutex_Lock(
156         PKIX_PL_Mutex *mutex,
157         void *plContext)
158 {
159         PKIX_ENTER(MUTEX, "PKIX_PL_Mutex_Lock");
160         PKIX_NULLCHECK_ONE(mutex);
161
162         PKIX_MUTEX_DEBUG("\tCalling PR_Lock).\n");
163         PR_Lock(mutex->lock);
164
165         PKIX_MUTEX_DEBUG_ARG("(Thread %u just acquired the lock)\n",
166                         (PKIX_UInt32)PR_GetCurrentThread());
167
168         PKIX_RETURN(MUTEX);
169 }
170
171 /*
172  * FUNCTION: PKIX_PL_Mutex_Unlock (see comments in pkix_pl_system.h)
173  */
174 PKIX_Error *
175 PKIX_PL_Mutex_Unlock(
176         PKIX_PL_Mutex *mutex,
177         void *plContext)
178 {
179         PRStatus result;
180
181         PKIX_ENTER(MUTEX, "PKIX_PL_Mutex_Unlock");
182         PKIX_NULLCHECK_ONE(mutex);
183
184         PKIX_MUTEX_DEBUG("\tCalling PR_Unlock).\n");
185         result = PR_Unlock(mutex->lock);
186
187         PKIX_MUTEX_DEBUG_ARG("(Thread %u just released the lock)\n",
188                         (PKIX_UInt32)PR_GetCurrentThread());
189
190         if (result == PR_FAILURE) {
191                 PKIX_ERROR_FATAL(PKIX_ERRORUNLOCKINGMUTEX);
192         }
193
194 cleanup:
195         PKIX_RETURN(MUTEX);
196 }