/src/krb5/src/include/k5-thread.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
2 | | /* include/k5-thread.h - Preliminary portable thread support */ |
3 | | /* |
4 | | * Copyright 2004,2005,2006,2007,2008 by the Massachusetts Institute of Technology. |
5 | | * All Rights Reserved. |
6 | | * |
7 | | * Export of this software from the United States of America may |
8 | | * require a specific license from the United States Government. |
9 | | * It is the responsibility of any person or organization contemplating |
10 | | * export to obtain such a license before exporting. |
11 | | * |
12 | | * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and |
13 | | * distribute this software and its documentation for any purpose and |
14 | | * without fee is hereby granted, provided that the above copyright |
15 | | * notice appear in all copies and that both that copyright notice and |
16 | | * this permission notice appear in supporting documentation, and that |
17 | | * the name of M.I.T. not be used in advertising or publicity pertaining |
18 | | * to distribution of the software without specific, written prior |
19 | | * permission. Furthermore if you modify this software you must label |
20 | | * your software as modified software and not distribute it in such a |
21 | | * fashion that it might be confused with the original M.I.T. software. |
22 | | * M.I.T. makes no representations about the suitability of |
23 | | * this software for any purpose. It is provided "as is" without express |
24 | | * or implied warranty. |
25 | | */ |
26 | | |
27 | | #ifndef K5_THREAD_H |
28 | | #define K5_THREAD_H |
29 | | |
30 | | #include "autoconf.h" |
31 | | #ifndef KRB5_CALLCONV |
32 | | # define KRB5_CALLCONV |
33 | | #endif |
34 | | #ifndef KRB5_CALLCONV_C |
35 | | # define KRB5_CALLCONV_C |
36 | | #endif |
37 | | |
38 | | /* Interface (tentative): |
39 | | |
40 | | Mutex support: |
41 | | |
42 | | // Between these two, we should be able to do pure compile-time |
43 | | // and pure run-time initialization. |
44 | | // POSIX: partial initializer is PTHREAD_MUTEX_INITIALIZER, |
45 | | // finish does nothing |
46 | | // Windows: partial initializer is an invalid handle, |
47 | | // finish does the real initialization work |
48 | | k5_mutex_t foo_mutex = K5_MUTEX_PARTIAL_INITIALIZER; |
49 | | int k5_mutex_finish_init(k5_mutex_t *); |
50 | | // for dynamic allocation |
51 | | int k5_mutex_init(k5_mutex_t *); |
52 | | // Must work for both kinds of alloc, even if it means adding flags. |
53 | | int k5_mutex_destroy(k5_mutex_t *); |
54 | | |
55 | | // As before. |
56 | | int k5_mutex_lock(k5_mutex_t *); |
57 | | int k5_mutex_unlock(k5_mutex_t *); |
58 | | |
59 | | In each library, one new function to finish the static mutex init, |
60 | | and any other library-wide initialization that might be desired. |
61 | | On POSIX, this function would be called via the second support |
62 | | function (see below). On Windows, it would be called at library |
63 | | load time. These functions, or functions they calls, should be the |
64 | | only places that k5_mutex_finish_init gets called. |
65 | | |
66 | | A second function or macro called at various possible "first" entry |
67 | | points which either calls pthread_once on the first function |
68 | | (POSIX), or checks some flag set by the first function (Windows), |
69 | | and possibly returns an error. (In the non-threaded case, a simple |
70 | | flag can be used to avoid multiple invocations, and the mutexes |
71 | | don't need run-time initialization anyways.) |
72 | | |
73 | | A third function for library termination calls mutex_destroy on |
74 | | each mutex for the library. This function would be called |
75 | | automatically at library unload time. If it turns out to be needed |
76 | | at exit time for libraries that don't get unloaded, perhaps we |
77 | | should also use atexit(). Any static mutexes should be cleaned up |
78 | | with k5_mutex_destroy here. |
79 | | |
80 | | How does that second support function invoke the first support |
81 | | function only once? Through something modelled on pthread_once |
82 | | that I haven't written up yet. Probably: |
83 | | |
84 | | k5_once_t foo_once = K5_ONCE_INIT; |
85 | | k5_once(k5_once_t *, void (*)(void)); |
86 | | |
87 | | For POSIX: Map onto pthread_once facility. |
88 | | For non-threaded case: A simple flag. |
89 | | For Windows: Not needed; library init code takes care of it. |
90 | | |
91 | | XXX: A general k5_once mechanism isn't possible for Windows, |
92 | | without faking it through named mutexes or mutexes initialized at |
93 | | startup. I was only using it in one place outside these headers, |
94 | | so I'm dropping the general scheme. Eventually the existing uses |
95 | | in k5-thread.h and k5-platform.h will be converted to pthread_once |
96 | | or static variables. |
97 | | |
98 | | |
99 | | Thread-specific data: |
100 | | |
101 | | // TSD keys are limited in number in gssapi/krb5/com_err; enumerate |
102 | | // them all. This allows support code init to allocate the |
103 | | // necessary storage for pointers all at once, and avoids any |
104 | | // possible error in key creation. |
105 | | enum { ... } k5_key_t; |
106 | | // Register destructor function. Called in library init code. |
107 | | int k5_key_register(k5_key_t, void (*destructor)(void *)); |
108 | | // Returns NULL or data. |
109 | | void *k5_getspecific(k5_key_t); |
110 | | // Returns error if key out of bounds, or the pointer table can't |
111 | | // be allocated. A call to k5_key_register must have happened first. |
112 | | // This may trigger the calling of pthread_setspecific on POSIX. |
113 | | int k5_setspecific(k5_key_t, void *); |
114 | | // Called in library termination code. |
115 | | // Trashes data in all threads, calling the registered destructor |
116 | | // (but calling it from the current thread). |
117 | | int k5_key_delete(k5_key_t); |
118 | | |
119 | | For the non-threaded version, the support code will have a static |
120 | | array indexed by k5_key_t values, and get/setspecific simply access |
121 | | the array elements. |
122 | | |
123 | | The TSD destructor table is global state, protected by a mutex if |
124 | | threads are enabled. |
125 | | |
126 | | |
127 | | Any actual external symbols will use the krb5int_ prefix. The k5_ |
128 | | names will be simple macros or inline functions to rename the |
129 | | external symbols, or slightly more complex ones to expand the |
130 | | implementation inline (e.g., map to POSIX versions and/or debug |
131 | | code using __FILE__ and the like). |
132 | | |
133 | | |
134 | | More to be added, perhaps. */ |
135 | | |
136 | | #include <assert.h> |
137 | | #ifndef NDEBUG |
138 | | #include <stdio.h> |
139 | | #include <string.h> |
140 | | #endif |
141 | | |
142 | | /* The mutex structure we use, k5_mutex_t, is defined to some |
143 | | OS-specific bits. The use of multiple layers of typedefs are an |
144 | | artifact resulting from debugging code we once used, implemented as |
145 | | wrappers around the OS mutex scheme. |
146 | | |
147 | | The OS specific bits, in k5_os_mutex, break down into three primary |
148 | | implementations, POSIX threads, Windows threads, and no thread |
149 | | support. However, the POSIX thread version is further subdivided: |
150 | | In one case, we can determine at run time whether the thread |
151 | | library is linked into the application, and use it only if it is |
152 | | present; in the other case, we cannot, and the thread library must |
153 | | be linked in always, but can be used unconditionally. In the |
154 | | former case, the k5_os_mutex structure needs to hold both the POSIX |
155 | | and the non-threaded versions. |
156 | | |
157 | | The various k5_os_mutex_* operations are the OS-specific versions, |
158 | | applied to the OS-specific data, and k5_mutex_* uses k5_os_mutex_* |
159 | | to do the OS-specific parts of the work. */ |
160 | | |
161 | | /* Define the OS mutex bit. */ |
162 | | |
163 | | typedef char k5_os_nothread_mutex; |
164 | | # define K5_OS_NOTHREAD_MUTEX_PARTIAL_INITIALIZER 0 |
165 | | /* Empty inline functions avoid the "statement with no effect" |
166 | | warnings, and do better type-checking than functions that don't use |
167 | | their arguments. */ |
168 | 0 | static inline int k5_os_nothread_mutex_finish_init(k5_os_nothread_mutex *m) { |
169 | 0 | return 0; |
170 | 0 | } Unexecuted instantiation: threads.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: init-addrinfo.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: plugins.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: errors.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: k5buf.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: fake-addrinfo.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: utf8.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: utf8_conv.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: path.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: json.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: hashtab.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: bcmp.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: strerror_r.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: dir_filenames.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: strlcpy.c:k5_os_nothread_mutex_finish_init Unexecuted instantiation: base64.c:k5_os_nothread_mutex_finish_init |
171 | 0 | static inline int k5_os_nothread_mutex_init(k5_os_nothread_mutex *m) { |
172 | 0 | return 0; |
173 | 0 | } Unexecuted instantiation: threads.c:k5_os_nothread_mutex_init Unexecuted instantiation: init-addrinfo.c:k5_os_nothread_mutex_init Unexecuted instantiation: plugins.c:k5_os_nothread_mutex_init Unexecuted instantiation: errors.c:k5_os_nothread_mutex_init Unexecuted instantiation: k5buf.c:k5_os_nothread_mutex_init Unexecuted instantiation: fake-addrinfo.c:k5_os_nothread_mutex_init Unexecuted instantiation: utf8.c:k5_os_nothread_mutex_init Unexecuted instantiation: utf8_conv.c:k5_os_nothread_mutex_init Unexecuted instantiation: path.c:k5_os_nothread_mutex_init Unexecuted instantiation: json.c:k5_os_nothread_mutex_init Unexecuted instantiation: hashtab.c:k5_os_nothread_mutex_init Unexecuted instantiation: bcmp.c:k5_os_nothread_mutex_init Unexecuted instantiation: strerror_r.c:k5_os_nothread_mutex_init Unexecuted instantiation: dir_filenames.c:k5_os_nothread_mutex_init Unexecuted instantiation: strlcpy.c:k5_os_nothread_mutex_init Unexecuted instantiation: base64.c:k5_os_nothread_mutex_init |
174 | 0 | static inline int k5_os_nothread_mutex_destroy(k5_os_nothread_mutex *m) { |
175 | 0 | return 0; |
176 | 0 | } Unexecuted instantiation: threads.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: init-addrinfo.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: plugins.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: errors.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: k5buf.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: fake-addrinfo.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: utf8.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: utf8_conv.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: path.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: json.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: hashtab.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: bcmp.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: strerror_r.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: dir_filenames.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: strlcpy.c:k5_os_nothread_mutex_destroy Unexecuted instantiation: base64.c:k5_os_nothread_mutex_destroy |
177 | 0 | static inline int k5_os_nothread_mutex_lock(k5_os_nothread_mutex *m) { |
178 | 0 | return 0; |
179 | 0 | } Unexecuted instantiation: threads.c:k5_os_nothread_mutex_lock Unexecuted instantiation: init-addrinfo.c:k5_os_nothread_mutex_lock Unexecuted instantiation: plugins.c:k5_os_nothread_mutex_lock Unexecuted instantiation: errors.c:k5_os_nothread_mutex_lock Unexecuted instantiation: k5buf.c:k5_os_nothread_mutex_lock Unexecuted instantiation: fake-addrinfo.c:k5_os_nothread_mutex_lock Unexecuted instantiation: utf8.c:k5_os_nothread_mutex_lock Unexecuted instantiation: utf8_conv.c:k5_os_nothread_mutex_lock Unexecuted instantiation: path.c:k5_os_nothread_mutex_lock Unexecuted instantiation: json.c:k5_os_nothread_mutex_lock Unexecuted instantiation: hashtab.c:k5_os_nothread_mutex_lock Unexecuted instantiation: bcmp.c:k5_os_nothread_mutex_lock Unexecuted instantiation: strerror_r.c:k5_os_nothread_mutex_lock Unexecuted instantiation: dir_filenames.c:k5_os_nothread_mutex_lock Unexecuted instantiation: strlcpy.c:k5_os_nothread_mutex_lock Unexecuted instantiation: base64.c:k5_os_nothread_mutex_lock |
180 | 0 | static inline int k5_os_nothread_mutex_unlock(k5_os_nothread_mutex *m) { |
181 | 0 | return 0; |
182 | 0 | } Unexecuted instantiation: threads.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: init-addrinfo.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: plugins.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: errors.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: k5buf.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: fake-addrinfo.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: utf8.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: utf8_conv.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: path.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: json.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: hashtab.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: bcmp.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: strerror_r.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: dir_filenames.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: strlcpy.c:k5_os_nothread_mutex_unlock Unexecuted instantiation: base64.c:k5_os_nothread_mutex_unlock |
183 | | |
184 | | /* Values: |
185 | | 2 - function has not been run |
186 | | 3 - function has been run |
187 | | 4 - function is being run -- deadlock detected */ |
188 | | typedef unsigned char k5_os_nothread_once_t; |
189 | | # define K5_OS_NOTHREAD_ONCE_INIT 2 |
190 | | # define k5_os_nothread_once(O,F) \ |
191 | 0 | (*(O) == 3 ? 0 \ |
192 | 0 | : *(O) == 2 ? (*(O) = 4, (F)(), *(O) = 3, 0) \ |
193 | 0 | : (assert(*(O) != 4), assert(*(O) == 2 || *(O) == 3), 0)) |
194 | | |
195 | | |
196 | | |
197 | | #ifndef ENABLE_THREADS |
198 | | |
199 | | typedef k5_os_nothread_mutex k5_os_mutex; |
200 | | # define K5_OS_MUTEX_PARTIAL_INITIALIZER \ |
201 | | K5_OS_NOTHREAD_MUTEX_PARTIAL_INITIALIZER |
202 | | # define k5_os_mutex_finish_init k5_os_nothread_mutex_finish_init |
203 | | # define k5_os_mutex_init k5_os_nothread_mutex_init |
204 | | # define k5_os_mutex_destroy k5_os_nothread_mutex_destroy |
205 | | # define k5_os_mutex_lock k5_os_nothread_mutex_lock |
206 | | # define k5_os_mutex_unlock k5_os_nothread_mutex_unlock |
207 | | |
208 | | # define k5_once_t k5_os_nothread_once_t |
209 | | # define K5_ONCE_INIT K5_OS_NOTHREAD_ONCE_INIT |
210 | | # define k5_once k5_os_nothread_once |
211 | | |
212 | | #elif HAVE_PTHREAD |
213 | | |
214 | | # include <pthread.h> |
215 | | |
216 | | /* Weak reference support, etc. |
217 | | |
218 | | Linux: Stub mutex routines exist, but pthread_once does not. |
219 | | |
220 | | Solaris <10: In libc there's a pthread_once that doesn't seem to do |
221 | | anything. Bleah. But pthread_mutexattr_setrobust_np is defined |
222 | | only in libpthread. However, some version of GNU libc (Red Hat's |
223 | | Fedora Core 5, reportedly) seems to have that function, but no |
224 | | declaration, so we'd have to declare it in order to test for its |
225 | | address. We now have tests to see if pthread_once actually works, |
226 | | so stick with that for now. |
227 | | |
228 | | Solaris 10: The real thread support now lives in libc, and |
229 | | libpthread is just a filter object. So we might as well use the |
230 | | real functions unconditionally. Since we haven't got a test for |
231 | | this property yet, we use NO_WEAK_PTHREADS defined in aclocal.m4 |
232 | | depending on the OS type. |
233 | | |
234 | | IRIX 6.5 stub pthread support in libc is really annoying. The |
235 | | pthread_mutex_lock function returns ENOSYS for a program not linked |
236 | | against -lpthread. No link-time failure, no weak symbols, etc. |
237 | | The C library doesn't provide pthread_once; we can use weak |
238 | | reference support for that. |
239 | | |
240 | | If weak references are not available, then for now, we assume that |
241 | | the pthread support routines will always be available -- either the |
242 | | real thing, or functional stubs that merely prohibit creating |
243 | | threads. |
244 | | |
245 | | If we find a platform with non-functional stubs and no weak |
246 | | references, we may have to resort to some hack like dlsym on the |
247 | | symbol tables of the current process. */ |
248 | | |
249 | | #if defined(HAVE_PRAGMA_WEAK_REF) && !defined(NO_WEAK_PTHREADS) |
250 | | # define USE_CONDITIONAL_PTHREADS |
251 | | #endif |
252 | | |
253 | | #ifdef USE_CONDITIONAL_PTHREADS |
254 | | |
255 | | /* Can't rely on useful stubs -- see above regarding Solaris. */ |
256 | | typedef struct { |
257 | | pthread_once_t o; |
258 | | k5_os_nothread_once_t n; |
259 | | } k5_once_t; |
260 | | # define K5_ONCE_INIT { PTHREAD_ONCE_INIT, K5_OS_NOTHREAD_ONCE_INIT } |
261 | | |
262 | | int k5_once(k5_once_t *once, void (*fn)(void)); |
263 | | #else |
264 | | |
265 | | /* no pragma weak support */ |
266 | | |
267 | | typedef pthread_once_t k5_once_t; |
268 | | # define K5_ONCE_INIT PTHREAD_ONCE_INIT |
269 | | # define k5_once pthread_once |
270 | | |
271 | | #endif |
272 | | |
273 | | #if defined(__mips) && defined(__sgi) && (defined(_SYSTYPE_SVR4) || defined(__SYSTYPE_SVR4__)) |
274 | | # ifndef HAVE_PRAGMA_WEAK_REF |
275 | | # if defined(__GNUC__) && __GNUC__ < 3 |
276 | | # error "Please update to a newer gcc with weak symbol support, or switch to native cc, reconfigure and recompile." |
277 | | # else |
278 | | # error "Weak reference support is required" |
279 | | # endif |
280 | | # endif |
281 | | #endif |
282 | | |
283 | | typedef pthread_mutex_t k5_os_mutex; |
284 | | # define K5_OS_MUTEX_PARTIAL_INITIALIZER \ |
285 | | PTHREAD_MUTEX_INITIALIZER |
286 | | |
287 | | #ifdef USE_CONDITIONAL_PTHREADS |
288 | | |
289 | 3 | # define k5_os_mutex_finish_init(M) (0) |
290 | | int k5_os_mutex_init(k5_os_mutex *m); |
291 | | int k5_os_mutex_destroy(k5_os_mutex *m); |
292 | | int k5_os_mutex_lock(k5_os_mutex *m); |
293 | | int k5_os_mutex_unlock(k5_os_mutex *m); |
294 | | |
295 | | #else |
296 | | |
297 | | static inline int k5_os_mutex_finish_init(k5_os_mutex *m) { return 0; } |
298 | | # define k5_os_mutex_init(M) pthread_mutex_init((M), 0) |
299 | | # define k5_os_mutex_destroy(M) pthread_mutex_destroy((M)) |
300 | | # define k5_os_mutex_lock(M) pthread_mutex_lock(M) |
301 | | # define k5_os_mutex_unlock(M) pthread_mutex_unlock(M) |
302 | | |
303 | | #endif /* is pthreads always available? */ |
304 | | |
305 | | #elif defined _WIN32 |
306 | | |
307 | | # define k5_once_t k5_os_nothread_once_t |
308 | | |
309 | | typedef struct { |
310 | | HANDLE h; |
311 | | int is_locked; |
312 | | } k5_os_mutex; |
313 | | |
314 | | # define K5_OS_MUTEX_PARTIAL_INITIALIZER { INVALID_HANDLE_VALUE, 0 } |
315 | | |
316 | | # define k5_os_mutex_finish_init(M) \ |
317 | | (assert((M)->h == INVALID_HANDLE_VALUE), \ |
318 | | ((M)->h = CreateMutex(NULL, FALSE, NULL)) ? 0 : GetLastError()) |
319 | | # define k5_os_mutex_init(M) \ |
320 | | ((M)->is_locked = 0, \ |
321 | | ((M)->h = CreateMutex(NULL, FALSE, NULL)) ? 0 : GetLastError()) |
322 | | # define k5_os_mutex_destroy(M) \ |
323 | | (CloseHandle((M)->h) ? ((M)->h = 0, 0) : GetLastError()) |
324 | | # define k5_os_mutex_lock k5_win_mutex_lock |
325 | | |
326 | | static inline int k5_win_mutex_lock(k5_os_mutex *m) |
327 | | { |
328 | | DWORD res; |
329 | | res = WaitForSingleObject(m->h, INFINITE); |
330 | | if (res == WAIT_FAILED) |
331 | | return GetLastError(); |
332 | | /* Eventually these should be turned into some reasonable error |
333 | | code. */ |
334 | | assert(res != WAIT_TIMEOUT); |
335 | | assert(res != WAIT_ABANDONED); |
336 | | assert(res == WAIT_OBJECT_0); |
337 | | /* Avoid locking twice. */ |
338 | | assert(m->is_locked == 0); |
339 | | m->is_locked = 1; |
340 | | return 0; |
341 | | } |
342 | | |
343 | | # define k5_os_mutex_unlock(M) \ |
344 | | (assert((M)->is_locked == 1), \ |
345 | | (M)->is_locked = 0, \ |
346 | | ReleaseMutex((M)->h) ? 0 : GetLastError()) |
347 | | |
348 | | #else |
349 | | |
350 | | # error "Thread support enabled, but thread system unknown" |
351 | | |
352 | | #endif |
353 | | |
354 | | typedef k5_os_mutex k5_mutex_t; |
355 | | #define K5_MUTEX_PARTIAL_INITIALIZER K5_OS_MUTEX_PARTIAL_INITIALIZER |
356 | | static inline int k5_mutex_init(k5_mutex_t *m) |
357 | 0 | { |
358 | 0 | return k5_os_mutex_init(m); |
359 | 0 | } Unexecuted instantiation: threads.c:k5_mutex_init Unexecuted instantiation: init-addrinfo.c:k5_mutex_init Unexecuted instantiation: plugins.c:k5_mutex_init Unexecuted instantiation: errors.c:k5_mutex_init Unexecuted instantiation: k5buf.c:k5_mutex_init Unexecuted instantiation: fake-addrinfo.c:k5_mutex_init Unexecuted instantiation: utf8.c:k5_mutex_init Unexecuted instantiation: utf8_conv.c:k5_mutex_init Unexecuted instantiation: path.c:k5_mutex_init Unexecuted instantiation: json.c:k5_mutex_init Unexecuted instantiation: hashtab.c:k5_mutex_init Unexecuted instantiation: bcmp.c:k5_mutex_init Unexecuted instantiation: strerror_r.c:k5_mutex_init Unexecuted instantiation: dir_filenames.c:k5_mutex_init Unexecuted instantiation: strlcpy.c:k5_mutex_init Unexecuted instantiation: base64.c:k5_mutex_init |
360 | | static inline int k5_mutex_finish_init(k5_mutex_t *m) |
361 | 3 | { |
362 | 3 | return k5_os_mutex_finish_init(m); |
363 | 3 | } threads.c:k5_mutex_finish_init Line | Count | Source | 361 | 1 | { | 362 | 1 | return k5_os_mutex_finish_init(m); | 363 | 1 | } |
init-addrinfo.c:k5_mutex_finish_init Line | Count | Source | 361 | 1 | { | 362 | 1 | return k5_os_mutex_finish_init(m); | 363 | 1 | } |
Unexecuted instantiation: plugins.c:k5_mutex_finish_init errors.c:k5_mutex_finish_init Line | Count | Source | 361 | 1 | { | 362 | 1 | return k5_os_mutex_finish_init(m); | 363 | 1 | } |
Unexecuted instantiation: k5buf.c:k5_mutex_finish_init Unexecuted instantiation: fake-addrinfo.c:k5_mutex_finish_init Unexecuted instantiation: utf8.c:k5_mutex_finish_init Unexecuted instantiation: utf8_conv.c:k5_mutex_finish_init Unexecuted instantiation: path.c:k5_mutex_finish_init Unexecuted instantiation: json.c:k5_mutex_finish_init Unexecuted instantiation: hashtab.c:k5_mutex_finish_init Unexecuted instantiation: bcmp.c:k5_mutex_finish_init Unexecuted instantiation: strerror_r.c:k5_mutex_finish_init Unexecuted instantiation: dir_filenames.c:k5_mutex_finish_init Unexecuted instantiation: strlcpy.c:k5_mutex_finish_init Unexecuted instantiation: base64.c:k5_mutex_finish_init |
364 | | #define k5_mutex_destroy(M) \ |
365 | 0 | (k5_os_mutex_destroy(M)) |
366 | | |
367 | | static inline void k5_mutex_lock(k5_mutex_t *m) |
368 | 2 | { |
369 | 2 | int r = k5_os_mutex_lock(m); |
370 | 2 | #ifndef NDEBUG |
371 | 2 | if (r != 0) { |
372 | 0 | fprintf(stderr, "k5_mutex_lock: Received error %d (%s)\n", |
373 | 0 | r, strerror(r)); |
374 | 0 | } |
375 | 2 | #endif |
376 | 2 | assert(r == 0); |
377 | 2 | } Line | Count | Source | 368 | 1 | { | 369 | 1 | int r = k5_os_mutex_lock(m); | 370 | 1 | #ifndef NDEBUG | 371 | 1 | if (r != 0) { | 372 | 0 | fprintf(stderr, "k5_mutex_lock: Received error %d (%s)\n", | 373 | 0 | r, strerror(r)); | 374 | 0 | } | 375 | 1 | #endif | 376 | 1 | assert(r == 0); | 377 | 1 | } |
Unexecuted instantiation: init-addrinfo.c:k5_mutex_lock Unexecuted instantiation: plugins.c:k5_mutex_lock Line | Count | Source | 368 | 1 | { | 369 | 1 | int r = k5_os_mutex_lock(m); | 370 | 1 | #ifndef NDEBUG | 371 | 1 | if (r != 0) { | 372 | 0 | fprintf(stderr, "k5_mutex_lock: Received error %d (%s)\n", | 373 | 0 | r, strerror(r)); | 374 | 0 | } | 375 | 1 | #endif | 376 | 1 | assert(r == 0); | 377 | 1 | } |
Unexecuted instantiation: k5buf.c:k5_mutex_lock Unexecuted instantiation: fake-addrinfo.c:k5_mutex_lock Unexecuted instantiation: utf8.c:k5_mutex_lock Unexecuted instantiation: utf8_conv.c:k5_mutex_lock Unexecuted instantiation: path.c:k5_mutex_lock Unexecuted instantiation: json.c:k5_mutex_lock Unexecuted instantiation: hashtab.c:k5_mutex_lock Unexecuted instantiation: bcmp.c:k5_mutex_lock Unexecuted instantiation: strerror_r.c:k5_mutex_lock Unexecuted instantiation: dir_filenames.c:k5_mutex_lock Unexecuted instantiation: strlcpy.c:k5_mutex_lock Unexecuted instantiation: base64.c:k5_mutex_lock |
378 | | |
379 | | static inline void k5_mutex_unlock(k5_mutex_t *m) |
380 | 2 | { |
381 | 2 | int r = k5_os_mutex_unlock(m); |
382 | 2 | #ifndef NDEBUG |
383 | 2 | if (r != 0) { |
384 | 0 | fprintf(stderr, "k5_mutex_unlock: Received error %d (%s)\n", |
385 | 0 | r, strerror(r)); |
386 | 0 | } |
387 | 2 | #endif |
388 | 2 | assert(r == 0); |
389 | 2 | } threads.c:k5_mutex_unlock Line | Count | Source | 380 | 1 | { | 381 | 1 | int r = k5_os_mutex_unlock(m); | 382 | 1 | #ifndef NDEBUG | 383 | 1 | if (r != 0) { | 384 | 0 | fprintf(stderr, "k5_mutex_unlock: Received error %d (%s)\n", | 385 | 0 | r, strerror(r)); | 386 | 0 | } | 387 | 1 | #endif | 388 | 1 | assert(r == 0); | 389 | 1 | } |
Unexecuted instantiation: init-addrinfo.c:k5_mutex_unlock Unexecuted instantiation: plugins.c:k5_mutex_unlock Line | Count | Source | 380 | 1 | { | 381 | 1 | int r = k5_os_mutex_unlock(m); | 382 | 1 | #ifndef NDEBUG | 383 | 1 | if (r != 0) { | 384 | 0 | fprintf(stderr, "k5_mutex_unlock: Received error %d (%s)\n", | 385 | 0 | r, strerror(r)); | 386 | 0 | } | 387 | 1 | #endif | 388 | 1 | assert(r == 0); | 389 | 1 | } |
Unexecuted instantiation: k5buf.c:k5_mutex_unlock Unexecuted instantiation: fake-addrinfo.c:k5_mutex_unlock Unexecuted instantiation: utf8.c:k5_mutex_unlock Unexecuted instantiation: utf8_conv.c:k5_mutex_unlock Unexecuted instantiation: path.c:k5_mutex_unlock Unexecuted instantiation: json.c:k5_mutex_unlock Unexecuted instantiation: hashtab.c:k5_mutex_unlock Unexecuted instantiation: bcmp.c:k5_mutex_unlock Unexecuted instantiation: strerror_r.c:k5_mutex_unlock Unexecuted instantiation: dir_filenames.c:k5_mutex_unlock Unexecuted instantiation: strlcpy.c:k5_mutex_unlock Unexecuted instantiation: base64.c:k5_mutex_unlock |
390 | | |
391 | | #define k5_mutex_assert_locked(M) ((void)(M)) |
392 | | #define k5_mutex_assert_unlocked(M) ((void)(M)) |
393 | | #define k5_assert_locked k5_mutex_assert_locked |
394 | | #define k5_assert_unlocked k5_mutex_assert_unlocked |
395 | | |
396 | | /* Thread-specific data; implemented in a support file, because we'll |
397 | | need to keep track of some global data for cleanup purposes. |
398 | | |
399 | | Note that the callback function type is such that the C library |
400 | | routine free() is a valid callback. */ |
401 | | typedef enum { |
402 | | K5_KEY_COM_ERR, |
403 | | K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME, |
404 | | K5_KEY_GSS_KRB5_CCACHE_NAME, |
405 | | K5_KEY_GSS_KRB5_ERROR_MESSAGE, |
406 | | K5_KEY_GSS_SPNEGO_STATUS, |
407 | | #if defined(__MACH__) && defined(__APPLE__) |
408 | | K5_KEY_IPC_CONNECTION_INFO, |
409 | | #endif |
410 | | K5_KEY_MAX |
411 | | } k5_key_t; |
412 | | /* rename shorthand symbols for export */ |
413 | | #define k5_key_register krb5int_key_register |
414 | | #define k5_getspecific krb5int_getspecific |
415 | | #define k5_setspecific krb5int_setspecific |
416 | | #define k5_key_delete krb5int_key_delete |
417 | | extern int k5_key_register(k5_key_t, void (*)(void *)); |
418 | | extern void *k5_getspecific(k5_key_t); |
419 | | extern int k5_setspecific(k5_key_t, void *); |
420 | | extern int k5_key_delete(k5_key_t); |
421 | | |
422 | | extern int KRB5_CALLCONV krb5int_mutex_alloc (k5_mutex_t **); |
423 | | extern void KRB5_CALLCONV krb5int_mutex_free (k5_mutex_t *); |
424 | | extern void KRB5_CALLCONV krb5int_mutex_lock (k5_mutex_t *); |
425 | | extern void KRB5_CALLCONV krb5int_mutex_unlock (k5_mutex_t *); |
426 | | |
427 | | /* In time, many of the definitions above should move into the support |
428 | | library, and this file should be greatly simplified. For type |
429 | | definitions, that'll take some work, since other data structures |
430 | | incorporate mutexes directly, and our mutex type is dependent on |
431 | | configuration options and system attributes. For most functions, |
432 | | though, it should be relatively easy. |
433 | | |
434 | | For now, plugins should use the exported functions, and not the |
435 | | above macros, and use krb5int_mutex_alloc for allocations. */ |
436 | | #if defined(PLUGIN) || (defined(CONFIG_SMALL) && !defined(THREAD_SUPPORT_IMPL)) |
437 | | #undef k5_mutex_lock |
438 | | #define k5_mutex_lock krb5int_mutex_lock |
439 | | #undef k5_mutex_unlock |
440 | | #define k5_mutex_unlock krb5int_mutex_unlock |
441 | | #endif |
442 | | |
443 | | #endif /* multiple inclusion? */ |