]>
Commit | Line | Data |
---|---|---|
aa6bb135 RS |
1 | /* |
2 | * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. | |
71a04cfc | 3 | * |
aa6bb135 RS |
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 | |
71a04cfc AG |
8 | */ |
9 | ||
10 | #include <openssl/crypto.h> | |
71a04cfc AG |
11 | |
12 | #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && defined(OPENSSL_SYS_WINDOWS) | |
13 | ||
14 | CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) | |
15 | { | |
16 | CRYPTO_RWLOCK *lock = OPENSSL_zalloc(sizeof(CRITICAL_SECTION)); | |
17 | if (lock == NULL) | |
18 | return NULL; | |
19 | ||
20 | /* 0x400 is the spin count value suggested in the documentation */ | |
0b2fc928 F |
21 | if (!InitializeCriticalSectionAndSpinCount(lock, 0x400)) { |
22 | OPENSSL_free(lock); | |
71a04cfc | 23 | return NULL; |
0b2fc928 | 24 | } |
71a04cfc AG |
25 | |
26 | return lock; | |
27 | } | |
28 | ||
29 | int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock) | |
30 | { | |
31 | EnterCriticalSection(lock); | |
32 | return 1; | |
33 | } | |
34 | ||
35 | int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock) | |
36 | { | |
37 | EnterCriticalSection(lock); | |
38 | return 1; | |
39 | } | |
40 | ||
41 | int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock) | |
42 | { | |
43 | LeaveCriticalSection(lock); | |
44 | return 1; | |
45 | } | |
46 | ||
47 | void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock) | |
48 | { | |
49 | if (lock == NULL) | |
50 | return; | |
51 | ||
52 | DeleteCriticalSection(lock); | |
53 | OPENSSL_free(lock); | |
54 | ||
55 | return; | |
56 | } | |
57 | ||
58 | # if _WIN32_WINNT < 0x0600 | |
59 | ||
60 | # define ONCE_UNINITED 0 | |
61 | # define ONCE_ININIT 1 | |
62 | # define ONCE_DONE 2 | |
63 | ||
64 | int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void)) | |
65 | { | |
66 | LONG volatile *lock = (LONG *)once; | |
67 | LONG result; | |
68 | ||
69 | if (*lock == ONCE_DONE) | |
70 | return 1; | |
71 | ||
72 | do { | |
73 | result = InterlockedCompareExchange(lock, ONCE_ININIT, ONCE_UNINITED); | |
74 | if (result == ONCE_UNINITED) { | |
75 | init(); | |
76 | *lock = ONCE_DONE; | |
77 | return 1; | |
78 | } | |
79 | } while (result == ONCE_ININIT); | |
80 | ||
81 | return (*lock == ONCE_DONE); | |
82 | } | |
83 | ||
84 | # else | |
85 | ||
86 | BOOL CALLBACK once_cb(PINIT_ONCE once, PVOID p, PVOID *pp) | |
87 | { | |
88 | void (*init)(void) = p; | |
89 | ||
90 | init(); | |
91 | ||
92 | return TRUE; | |
93 | } | |
94 | ||
64256510 | 95 | int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void)) |
71a04cfc AG |
96 | { |
97 | if (InitOnceExecuteOnce(once, once_cb, init, NULL)) | |
6b888643 | 98 | return 1; |
71a04cfc | 99 | |
6b888643 | 100 | return 0; |
71a04cfc AG |
101 | } |
102 | ||
103 | # endif | |
104 | ||
105 | int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *)) | |
106 | { | |
107 | *key = TlsAlloc(); | |
108 | if (*key == TLS_OUT_OF_INDEXES) | |
109 | return 0; | |
110 | ||
111 | return 1; | |
112 | } | |
113 | ||
114 | void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key) | |
115 | { | |
116 | return TlsGetValue(*key); | |
117 | } | |
118 | ||
119 | int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val) | |
120 | { | |
121 | if (TlsSetValue(*key, val) == 0) | |
122 | return 0; | |
123 | ||
124 | return 1; | |
125 | } | |
126 | ||
127 | int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key) | |
128 | { | |
129 | if (TlsFree(*key) == 0) | |
130 | return 0; | |
131 | ||
132 | return 1; | |
133 | } | |
134 | ||
135 | CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void) | |
136 | { | |
137 | return GetCurrentThreadId(); | |
138 | } | |
139 | ||
140 | int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b) | |
141 | { | |
142 | return (a == b); | |
143 | } | |
144 | ||
145 | int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) | |
146 | { | |
147 | *ret = InterlockedExchangeAdd(val, amount) + amount; | |
148 | return 1; | |
149 | } | |
150 | ||
151 | #endif |