summaryrefslogtreecommitdiff
path: root/lib/util/smb_threads.c
blob: fa2d8da18650088eb3f6079b839583f3db4330eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
   Unix SMB/CIFS implementation.
   SMB client library implementation (thread interface functions).
   Copyright (C) Jeremy Allison, 2009.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
 * This code is based in the ideas in openssl
 * but somewhat simpler and expended to include
 * thread local storage.
 */

#include "includes.h"

/*********************************************************
 Functions to vector the locking primitives used internally
 by libsmbclient.
*********************************************************/

const struct smb_thread_functions *global_tfp;

/*********************************************************
 Dynamic lock array.
*********************************************************/

void **global_lock_array;

/*********************************************************
 Function to set the locking primitives used by libsmbclient.
*********************************************************/

int smb_thread_set_functions(const struct smb_thread_functions *tf)
{
	int i;

	global_tfp = tf;

#if defined(PARANOID_MALLOC_CHECKER)
#ifdef malloc
#undef malloc
#endif
#endif

	/* Here we initialize any static locks we're using. */
	global_lock_array = (void **)malloc(sizeof(void *) *NUM_GLOBAL_LOCKS);

#if defined(PARANOID_MALLOC_CHECKER)
#define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
#endif

	if (global_lock_array == NULL) {
		return ENOMEM;
	}

	for (i = 0; i < NUM_GLOBAL_LOCKS; i++) {
		char *name = NULL;
		if (asprintf(&name, "global_lock_%d", i) == -1) {
			SAFE_FREE(global_lock_array);
			return ENOMEM;
		}
		if (global_tfp->create_mutex(name,
				&global_lock_array[i],
				__location__)) {
			smb_panic("smb_thread_set_functions: create mutexes failed");
		}
		SAFE_FREE(name);
	}

	return 0;
}

#if 0
/* Test. - pthread implementations. */
#include <pthread.h>

#ifdef malloc
#undef malloc
#endif

SMB_THREADS_DEF_PTHREAD_IMPLEMENTATION(tf);

void *pkey = NULL;

/* Test function. */
int test_threads(void)
{
	int ret;
	void *plock = NULL;
	smb_thread_set_functions(&tf);

	if ((ret = SMB_THREAD_CREATE_TLS_ONCE("test_tls", pkey)) != 0) {
		printf("Create tls once error: %d\n", ret);
	}
	if ((ret = SMB_THREAD_CREATE_MUTEX("test", plock)) != 0) {
		printf("Create lock error: %d\n", ret);
	}
	if ((ret = SMB_THREAD_LOCK(plock, SMB_THREAD_LOCK)) != 0) {
		printf("lock error: %d\n", ret);
	}
	if ((SMB_THREAD_LOCK(plock, SMB_THREAD_UNLOCK)) != 0) {
		printf("unlock error: %d\n", ret);
	}
	SMB_THREAD_DESTROY_MUTEX(plock);
	SMB_THREAD_DESTROY_TLS_ONCE(pkey);

	return 0;
}
#endif