"Fossies" - the Fresh Open Source Software Archive

Member "openssl-1.1.1g/crypto/threads_win.c" (21 Apr 2020, 3944 Bytes) of package /linux/misc/openssl-1.1.1g.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "threads_win.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.1.1f_vs_1.1.1g.

    1 /*
    2  * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
    3  *
    4  * Licensed under the OpenSSL license (the "License").  You may not use
    5  * this file except in compliance with the License.  You can obtain a copy
    6  * in the file LICENSE in the source distribution or at
    7  * https://www.openssl.org/source/license.html
    8  */
    9 
   10 #if defined(_WIN32)
   11 # include <windows.h>
   12 #endif
   13 
   14 #include <openssl/crypto.h>
   15 
   16 #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && defined(OPENSSL_SYS_WINDOWS)
   17 
   18 CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
   19 {
   20     CRYPTO_RWLOCK *lock;
   21 
   22     if ((lock = OPENSSL_zalloc(sizeof(CRITICAL_SECTION))) == NULL) {
   23         /* Don't set error, to avoid recursion blowup. */
   24         return NULL;
   25     }
   26 
   27 # if !defined(_WIN32_WCE)
   28     /* 0x400 is the spin count value suggested in the documentation */
   29     if (!InitializeCriticalSectionAndSpinCount(lock, 0x400)) {
   30         OPENSSL_free(lock);
   31         return NULL;
   32     }
   33 # else
   34     InitializeCriticalSection(lock);
   35 # endif
   36 
   37     return lock;
   38 }
   39 
   40 int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
   41 {
   42     EnterCriticalSection(lock);
   43     return 1;
   44 }
   45 
   46 int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
   47 {
   48     EnterCriticalSection(lock);
   49     return 1;
   50 }
   51 
   52 int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
   53 {
   54     LeaveCriticalSection(lock);
   55     return 1;
   56 }
   57 
   58 void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
   59 {
   60     if (lock == NULL)
   61         return;
   62 
   63     DeleteCriticalSection(lock);
   64     OPENSSL_free(lock);
   65 
   66     return;
   67 }
   68 
   69 #  define ONCE_UNINITED     0
   70 #  define ONCE_ININIT       1
   71 #  define ONCE_DONE         2
   72 
   73 /*
   74  * We don't use InitOnceExecuteOnce because that isn't available in WinXP which
   75  * we still have to support.
   76  */
   77 int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
   78 {
   79     LONG volatile *lock = (LONG *)once;
   80     LONG result;
   81 
   82     if (*lock == ONCE_DONE)
   83         return 1;
   84 
   85     do {
   86         result = InterlockedCompareExchange(lock, ONCE_ININIT, ONCE_UNINITED);
   87         if (result == ONCE_UNINITED) {
   88             init();
   89             *lock = ONCE_DONE;
   90             return 1;
   91         }
   92     } while (result == ONCE_ININIT);
   93 
   94     return (*lock == ONCE_DONE);
   95 }
   96 
   97 int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
   98 {
   99     *key = TlsAlloc();
  100     if (*key == TLS_OUT_OF_INDEXES)
  101         return 0;
  102 
  103     return 1;
  104 }
  105 
  106 void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
  107 {
  108     DWORD last_error;
  109     void *ret;
  110 
  111     /*
  112      * TlsGetValue clears the last error even on success, so that callers may
  113      * distinguish it successfully returning NULL or failing. It is documented
  114      * to never fail if the argument is a valid index from TlsAlloc, so we do
  115      * not need to handle this.
  116      *
  117      * However, this error-mangling behavior interferes with the caller's use of
  118      * GetLastError. In particular SSL_get_error queries the error queue to
  119      * determine whether the caller should look at the OS's errors. To avoid
  120      * destroying state, save and restore the Windows error.
  121      *
  122      * https://msdn.microsoft.com/en-us/library/windows/desktop/ms686812(v=vs.85).aspx
  123      */
  124     last_error = GetLastError();
  125     ret = TlsGetValue(*key);
  126     SetLastError(last_error);
  127     return ret;
  128 }
  129 
  130 int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
  131 {
  132     if (TlsSetValue(*key, val) == 0)
  133         return 0;
  134 
  135     return 1;
  136 }
  137 
  138 int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
  139 {
  140     if (TlsFree(*key) == 0)
  141         return 0;
  142 
  143     return 1;
  144 }
  145 
  146 CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void)
  147 {
  148     return GetCurrentThreadId();
  149 }
  150 
  151 int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b)
  152 {
  153     return (a == b);
  154 }
  155 
  156 int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
  157 {
  158     *ret = (int)InterlockedExchangeAdd((long volatile *)val, (long)amount) + amount;
  159     return 1;
  160 }
  161 
  162 int openssl_init_fork_handlers(void)
  163 {
  164     return 0;
  165 }
  166 
  167 int openssl_get_fork_id(void)
  168 {
  169     return 0;
  170 }
  171 #endif