Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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 <unistd.h>
  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 */
  190.