A local copy of OpenSSL from GitHub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
3.0 KiB

  1. /*
  2. * Copyright 2016 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. #include <openssl/crypto.h>
  10. #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && defined(OPENSSL_SYS_WINDOWS)
  11. CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
  12. {
  13. CRYPTO_RWLOCK *lock = OPENSSL_zalloc(sizeof(CRITICAL_SECTION));
  14. if (lock == NULL)
  15. return NULL;
  16. /* 0x400 is the spin count value suggested in the documentation */
  17. if (!InitializeCriticalSectionAndSpinCount(lock, 0x400)) {
  18. OPENSSL_free(lock);
  19. return NULL;
  20. }
  21. return lock;
  22. }
  23. int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
  24. {
  25. EnterCriticalSection(lock);
  26. return 1;
  27. }
  28. int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
  29. {
  30. EnterCriticalSection(lock);
  31. return 1;
  32. }
  33. int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
  34. {
  35. LeaveCriticalSection(lock);
  36. return 1;
  37. }
  38. void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
  39. {
  40. if (lock == NULL)
  41. return;
  42. DeleteCriticalSection(lock);
  43. OPENSSL_free(lock);
  44. return;
  45. }
  46. # if _WIN32_WINNT < 0x0600
  47. # define ONCE_UNINITED 0
  48. # define ONCE_ININIT 1
  49. # define ONCE_DONE 2
  50. int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
  51. {
  52. LONG volatile *lock = (LONG *)once;
  53. LONG result;
  54. if (*lock == ONCE_DONE)
  55. return 1;
  56. do {
  57. result = InterlockedCompareExchange(lock, ONCE_ININIT, ONCE_UNINITED);
  58. if (result == ONCE_UNINITED) {
  59. init();
  60. *lock = ONCE_DONE;
  61. return 1;
  62. }
  63. } while (result == ONCE_ININIT);
  64. return (*lock == ONCE_DONE);
  65. }
  66. # else
  67. BOOL CALLBACK once_cb(PINIT_ONCE once, PVOID p, PVOID *pp)
  68. {
  69. void (*init)(void) = p;
  70. init();
  71. return TRUE;
  72. }
  73. int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
  74. {
  75. if (InitOnceExecuteOnce(once, once_cb, init, NULL))
  76. return 1;
  77. return 0;
  78. }
  79. # endif
  80. int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
  81. {
  82. *key = TlsAlloc();
  83. if (*key == TLS_OUT_OF_INDEXES)
  84. return 0;
  85. return 1;
  86. }
  87. void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
  88. {
  89. return TlsGetValue(*key);
  90. }
  91. int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
  92. {
  93. if (TlsSetValue(*key, val) == 0)
  94. return 0;
  95. return 1;
  96. }
  97. int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
  98. {
  99. if (TlsFree(*key) == 0)
  100. return 0;
  101. return 1;
  102. }
  103. CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void)
  104. {
  105. return GetCurrentThreadId();
  106. }
  107. int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b)
  108. {
  109. return (a == b);
  110. }
  111. int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
  112. {
  113. *ret = InterlockedExchangeAdd(val, amount) + amount;
  114. return 1;
  115. }
  116. #endif