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