550608230bb8910e0d954584e91dc52fdef7cf07
[openafs.git] / src / util / pthread_glock.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 RCSID
14     ("$Header$");
15
16 #if defined(AFS_NT40_ENV) && defined(AFS_PTHREAD_ENV)
17 #define AFS_GRMUTEX_DECLSPEC __declspec(dllexport)
18 #endif
19 #include <afs/pthread_glock.h>
20 #include <string.h>
21
22 /*
23  * Implement a pthread based recursive global lock for use in porting
24  * old lwp style code to pthreads.
25  */
26
27 pthread_recursive_mutex_t grmutex;
28
29 static int glock_init = 0;
30 static pthread_once_t glock_init_once = PTHREAD_ONCE_INIT;
31
32 static void
33 glock_init_func(void)
34 {
35     pthread_mutex_init(&grmutex.mut, (const pthread_mutexattr_t *)0);
36     grmutex.times_inside = 0;
37     grmutex.owner = (pthread_t) 0;
38     grmutex.locked = 0;
39     glock_init = 1;
40 }
41
42 int
43 pthread_recursive_mutex_lock(pthread_recursive_mutex_t * mut)
44 {
45     int rc = 0;
46
47 /*
48  *    FSLog("Entered pthread_recursive_mutex_lock, thread id is %d\n",
49  *              pthread_self());
50  */
51
52     (glock_init || pthread_once(&glock_init_once, glock_init_func));
53
54     if (mut->locked) {
55         if (pthread_equal(mut->owner, pthread_self())) {
56             mut->times_inside++;
57             return rc;
58         }
59     }
60     rc = pthread_mutex_lock(&mut->mut);
61     if (rc == 0) {
62         mut->times_inside = 1;
63         mut->owner = pthread_self();
64         mut->locked = 1;
65     }
66
67     return rc;
68 }
69
70 int
71 pthread_recursive_mutex_unlock(pthread_recursive_mutex_t * mut)
72 {
73     int rc = 0;
74
75 /*
76  *    FSLog("Entered pthread_recursive_mutex_unlock, thread id is %d\n",
77  *              pthread_self());
78  *
79  */
80
81     (glock_init || pthread_once(&glock_init_once, glock_init_func));
82
83     if ((mut->locked) && (pthread_equal(mut->owner, pthread_self()))) {
84         mut->times_inside--;
85         if (mut->times_inside == 0) {
86             mut->locked = 0;
87             rc = pthread_mutex_unlock(&mut->mut);
88         }
89     } else {
90         /*
91          * Note that you might want to try to differentiate between
92          * the two possible reasons you're here, but since we don't
93          * hold the mutex, it's useless to try.
94          */
95         rc = -1;
96     }
97     return rc;
98 }