Ensure a tls key is only generated once - wrap create & destroy in a mutex.
[Samba/gebeck_regimport.git] / lib / util / smb_threads.c
blobfa2d8da18650088eb3f6079b839583f3db4330eb
1 /*
2 Unix SMB/CIFS implementation.
3 SMB client library implementation (thread interface functions).
4 Copyright (C) Jeremy Allison, 2009.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * This code is based in the ideas in openssl
22 * but somewhat simpler and expended to include
23 * thread local storage.
26 #include "includes.h"
28 /*********************************************************
29 Functions to vector the locking primitives used internally
30 by libsmbclient.
31 *********************************************************/
33 const struct smb_thread_functions *global_tfp;
35 /*********************************************************
36 Dynamic lock array.
37 *********************************************************/
39 void **global_lock_array;
41 /*********************************************************
42 Function to set the locking primitives used by libsmbclient.
43 *********************************************************/
45 int smb_thread_set_functions(const struct smb_thread_functions *tf)
47 int i;
49 global_tfp = tf;
51 #if defined(PARANOID_MALLOC_CHECKER)
52 #ifdef malloc
53 #undef malloc
54 #endif
55 #endif
57 /* Here we initialize any static locks we're using. */
58 global_lock_array = (void **)malloc(sizeof(void *) *NUM_GLOBAL_LOCKS);
60 #if defined(PARANOID_MALLOC_CHECKER)
61 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
62 #endif
64 if (global_lock_array == NULL) {
65 return ENOMEM;
68 for (i = 0; i < NUM_GLOBAL_LOCKS; i++) {
69 char *name = NULL;
70 if (asprintf(&name, "global_lock_%d", i) == -1) {
71 SAFE_FREE(global_lock_array);
72 return ENOMEM;
74 if (global_tfp->create_mutex(name,
75 &global_lock_array[i],
76 __location__)) {
77 smb_panic("smb_thread_set_functions: create mutexes failed");
79 SAFE_FREE(name);
82 return 0;
85 #if 0
86 /* Test. - pthread implementations. */
87 #include <pthread.h>
89 #ifdef malloc
90 #undef malloc
91 #endif
93 SMB_THREADS_DEF_PTHREAD_IMPLEMENTATION(tf);
95 void *pkey = NULL;
97 /* Test function. */
98 int test_threads(void)
100 int ret;
101 void *plock = NULL;
102 smb_thread_set_functions(&tf);
104 if ((ret = SMB_THREAD_CREATE_TLS_ONCE("test_tls", pkey)) != 0) {
105 printf("Create tls once error: %d\n", ret);
107 if ((ret = SMB_THREAD_CREATE_MUTEX("test", plock)) != 0) {
108 printf("Create lock error: %d\n", ret);
110 if ((ret = SMB_THREAD_LOCK(plock, SMB_THREAD_LOCK)) != 0) {
111 printf("lock error: %d\n", ret);
113 if ((SMB_THREAD_LOCK(plock, SMB_THREAD_UNLOCK)) != 0) {
114 printf("unlock error: %d\n", ret);
116 SMB_THREAD_DESTROY_MUTEX(plock);
117 SMB_THREAD_DESTROY_TLS_ONCE(pkey);
119 return 0;
121 #endif