Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8774 | rgimad | 1 | /* |
2 | * Threading abstraction layer |
||
3 | * |
||
4 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
||
5 | * SPDX-License-Identifier: GPL-2.0 |
||
6 | * |
||
7 | * This program is free software; you can redistribute it and/or modify |
||
8 | * it under the terms of the GNU General Public License as published by |
||
9 | * the Free Software Foundation; either version 2 of the License, or |
||
10 | * (at your option) any later version. |
||
11 | * |
||
12 | * This program is distributed in the hope that it will be useful, |
||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
15 | * GNU General Public License for more details. |
||
16 | * |
||
17 | * You should have received a copy of the GNU General Public License along |
||
18 | * with this program; if not, write to the Free Software Foundation, Inc., |
||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
||
20 | * |
||
21 | * This file is part of mbed TLS (https://tls.mbed.org) |
||
22 | */ |
||
23 | |||
24 | /* |
||
25 | * Ensure gmtime_r is available even with -std=c99; must be defined before |
||
26 | * config.h, which pulls in glibc's features.h. Harmless on other platforms. |
||
27 | */ |
||
28 | #if !defined(_POSIX_C_SOURCE) |
||
29 | #define _POSIX_C_SOURCE 200112L |
||
30 | #endif |
||
31 | |||
32 | #if !defined(MBEDTLS_CONFIG_FILE) |
||
33 | #include "mbedtls/config.h" |
||
34 | #else |
||
35 | #include MBEDTLS_CONFIG_FILE |
||
36 | #endif |
||
37 | |||
38 | #if defined(MBEDTLS_THREADING_C) |
||
39 | |||
40 | #include "mbedtls/threading.h" |
||
41 | |||
42 | #if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) |
||
43 | |||
44 | #if !defined(_WIN32) && (defined(unix) || \ |
||
45 | defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ |
||
46 | defined(__MACH__))) |
||
47 | #include |
||
48 | #endif /* !_WIN32 && (unix || __unix || __unix__ || |
||
49 | * (__APPLE__ && __MACH__)) */ |
||
50 | |||
51 | #if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ |
||
52 | ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ |
||
53 | _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) |
||
54 | /* |
||
55 | * This is a convenience shorthand macro to avoid checking the long |
||
56 | * preprocessor conditions above. Ideally, we could expose this macro in |
||
57 | * platform_util.h and simply use it in platform_util.c, threading.c and |
||
58 | * threading.h. However, this macro is not part of the Mbed TLS public API, so |
||
59 | * we keep it private by only defining it in this file |
||
60 | */ |
||
61 | |||
62 | #if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) |
||
63 | #define THREADING_USE_GMTIME |
||
64 | #endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */ |
||
65 | |||
66 | #endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ |
||
67 | ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ |
||
68 | _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */ |
||
69 | |||
70 | #endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ |
||
71 | |||
72 | #if defined(MBEDTLS_THREADING_PTHREAD) |
||
73 | static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex ) |
||
74 | { |
||
75 | if( mutex == NULL ) |
||
76 | return; |
||
77 | |||
78 | mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0; |
||
79 | } |
||
80 | |||
81 | static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex ) |
||
82 | { |
||
83 | if( mutex == NULL || !mutex->is_valid ) |
||
84 | return; |
||
85 | |||
86 | (void) pthread_mutex_destroy( &mutex->mutex ); |
||
87 | mutex->is_valid = 0; |
||
88 | } |
||
89 | |||
90 | static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex ) |
||
91 | { |
||
92 | if( mutex == NULL || ! mutex->is_valid ) |
||
93 | return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); |
||
94 | |||
95 | if( pthread_mutex_lock( &mutex->mutex ) != 0 ) |
||
96 | return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
||
97 | |||
98 | return( 0 ); |
||
99 | } |
||
100 | |||
101 | static int threading_mutex_unlock_pthread( mbedtls_threading_mutex_t *mutex ) |
||
102 | { |
||
103 | if( mutex == NULL || ! mutex->is_valid ) |
||
104 | return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); |
||
105 | |||
106 | if( pthread_mutex_unlock( &mutex->mutex ) != 0 ) |
||
107 | return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); |
||
108 | |||
109 | return( 0 ); |
||
110 | } |
||
111 | |||
112 | void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_init_pthread; |
||
113 | void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_free_pthread; |
||
114 | int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_pthread; |
||
115 | int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread; |
||
116 | |||
117 | /* |
||
118 | * With phtreads we can statically initialize mutexes |
||
119 | */ |
||
120 | #define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 } |
||
121 | |||
122 | #endif /* MBEDTLS_THREADING_PTHREAD */ |
||
123 | |||
124 | #if defined(MBEDTLS_THREADING_ALT) |
||
125 | static int threading_mutex_fail( mbedtls_threading_mutex_t *mutex ) |
||
126 | { |
||
127 | ((void) mutex ); |
||
128 | return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); |
||
129 | } |
||
130 | static void threading_mutex_dummy( mbedtls_threading_mutex_t *mutex ) |
||
131 | { |
||
132 | ((void) mutex ); |
||
133 | return; |
||
134 | } |
||
135 | |||
136 | void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; |
||
137 | void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; |
||
138 | int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; |
||
139 | int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; |
||
140 | |||
141 | /* |
||
142 | * Set functions pointers and initialize global mutexes |
||
143 | */ |
||
144 | void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ), |
||
145 | void (*mutex_free)( mbedtls_threading_mutex_t * ), |
||
146 | int (*mutex_lock)( mbedtls_threading_mutex_t * ), |
||
147 | int (*mutex_unlock)( mbedtls_threading_mutex_t * ) ) |
||
148 | { |
||
149 | mbedtls_mutex_init = mutex_init; |
||
150 | mbedtls_mutex_free = mutex_free; |
||
151 | mbedtls_mutex_lock = mutex_lock; |
||
152 | mbedtls_mutex_unlock = mutex_unlock; |
||
153 | |||
154 | #if defined(MBEDTLS_FS_IO) |
||
155 | mbedtls_mutex_init( &mbedtls_threading_readdir_mutex ); |
||
156 | #endif |
||
157 | #if defined(THREADING_USE_GMTIME) |
||
158 | mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex ); |
||
159 | #endif |
||
160 | } |
||
161 | |||
162 | /* |
||
163 | * Free global mutexes |
||
164 | */ |
||
165 | void mbedtls_threading_free_alt( void ) |
||
166 | { |
||
167 | #if defined(MBEDTLS_FS_IO) |
||
168 | mbedtls_mutex_free( &mbedtls_threading_readdir_mutex ); |
||
169 | #endif |
||
170 | #if defined(THREADING_USE_GMTIME) |
||
171 | mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex ); |
||
172 | #endif |
||
173 | } |
||
174 | #endif /* MBEDTLS_THREADING_ALT */ |
||
175 | |||
176 | /* |
||
177 | * Define global mutexes |
||
178 | */ |
||
179 | #ifndef MUTEX_INIT |
||
180 | #define MUTEX_INIT |
||
181 | #endif |
||
182 | #if defined(MBEDTLS_FS_IO) |
||
183 | mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT; |
||
184 | #endif |
||
185 | #if defined(THREADING_USE_GMTIME) |
||
186 | mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; |
||
187 | #endif |
||
188 | |||
189 | #endif /* MBEDTLS_THREADING_C */ |