1 /*
2 * mt_support.c - multi-thread resource locking support
3 */
4 /*
5 * Author: Markku Laukkanen
6 * Created: 6-Sep-1999
7 * History:
8 * 8-Sep-1999 M. Slifcak method names changed;
9 * use array of resource locking structures.
10 */
11
12 #include <net-snmp/net-snmp-config.h>
13 #include <errno.h>
14 #include <net-snmp/library/mt_support.h>
15
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19
20 #ifdef NETSNMP_REENTRANT
21
22 static mutex_type s_res[MT_MAX_IDS][MT_LIB_MAXIMUM]; /* locking structures */
23
24 static mutex_type *
_mt_res(int groupID,int resourceID)25 _mt_res(int groupID, int resourceID)
26 {
27 if (groupID < 0) {
28 return 0;
29 }
30 if (groupID >= MT_MAX_IDS) {
31 return 0;
32 }
33 if (resourceID < 0) {
34 return 0;
35 }
36 if (resourceID >= MT_LIB_MAXIMUM) {
37 return 0;
38 }
39 return (&s_res[groupID][resourceID]);
40 }
41
42 static int
snmp_res_init_mutex(mutex_type * mutex)43 snmp_res_init_mutex(mutex_type *mutex)
44 {
45 int rc = 0;
46 #if HAVE_PTHREAD_H
47 pthread_mutexattr_t attr;
48 pthread_mutexattr_init(&attr);
49 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
50 rc = pthread_mutex_init(mutex, &attr);
51 pthread_mutexattr_destroy(&attr);
52 #elif defined(WIN32)
53 InitializeCriticalSection(mutex);
54 #endif
55
56 return rc;
57 }
58
59 int
snmp_res_init(void)60 snmp_res_init(void)
61 {
62 int ii, jj, rc = 0;
63 mutex_type *mutex;
64
65 for (jj = 0; (0 == rc) && (jj < MT_MAX_IDS); jj++) {
66 for (ii = 0; (0 == rc) && (ii < MT_LIB_MAXIMUM); ii++) {
67 mutex = _mt_res(jj, ii);
68 if (!mutex) {
69 continue;
70 }
71 rc = snmp_res_init_mutex(mutex);
72 }
73 }
74
75 return rc;
76 }
77
78 int
snmp_res_destroy_mutex(int groupID,int resourceID)79 snmp_res_destroy_mutex(int groupID, int resourceID)
80 {
81 int rc = 0;
82 mutex_type *mutex = _mt_res(groupID, resourceID);
83 if (!mutex) {
84 return EFAULT;
85 }
86
87 #if HAVE_PTHREAD_H
88 rc = pthread_mutex_destroy(mutex);
89 #elif defined(WIN32)
90 DeleteCriticalSection(mutex);
91 #endif
92
93 return rc;
94 }
95
96 int
snmp_res_lock(int groupID,int resourceID)97 snmp_res_lock(int groupID, int resourceID)
98 {
99 int rc = 0;
100 mutex_type *mutex = _mt_res(groupID, resourceID);
101
102 if (!mutex) {
103 return EFAULT;
104 }
105
106 #if HAVE_PTHREAD_H
107 rc = pthread_mutex_lock(mutex);
108 #elif defined(WIN32)
109 EnterCriticalSection(mutex);
110 #endif
111
112 return rc;
113 }
114
115 int
snmp_res_unlock(int groupID,int resourceID)116 snmp_res_unlock(int groupID, int resourceID)
117 {
118 int rc = 0;
119 mutex_type *mutex = _mt_res(groupID, resourceID);
120
121 if (!mutex) {
122 return EFAULT;
123 }
124
125 #if HAVE_PTHREAD_H
126 rc = pthread_mutex_unlock(mutex);
127 #elif defined(WIN32)
128 LeaveCriticalSection(mutex);
129 #endif
130
131 return rc;
132 }
133
134 #else /* NETSNMP_REENTRANT */
135 #ifdef WIN32
136
137 /*
138 * Provide "do nothing" targets for Release (.DLL) builds.
139 */
140
141 int
142 snmp_res_init(void)
143 {
144 return 0;
145 }
146
147 int
148 snmp_res_lock(int groupID, int resourceID)
149 {
150 return 0;
151 }
152
153 int
154 snmp_res_unlock(int groupID, int resourceID)
155 {
156 return 0;
157 }
158
159 int
160 snmp_res_destroy_mutex(int groupID, int resourceID)
161 {
162 return 0;
163 }
164 #endif /* WIN32 */
165 #endif /* NETSNMP_REENTRANT */
166
167 #ifdef __cplusplus
168 }
169 #endif
170