Bug Summary

File:out/../deps/v8/src/base/platform/mutex.cc
Warning:line 106, column 3
Value stored to 'result' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mutex.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D V8_GYP_BUILD -D V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64 -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D V8_TARGET_ARCH_X64 -D V8_HAVE_TARGET_OS -D V8_TARGET_OS_LINUX -D V8_EMBEDDER_STRING="-node.8" -D ENABLE_DISASSEMBLER -D V8_PROMISE_INTERNAL_FIELD_COUNT=1 -D V8_SHORT_BUILTIN_CALLS -D OBJECT_PRINT -D V8_INTL_SUPPORT -D V8_ATOMIC_OBJECT_FIELD_WRITES -D V8_ENABLE_LAZY_SOURCE_POSITIONS -D V8_USE_SIPHASH -D V8_SHARED_RO_HEAP -D V8_WIN64_UNWINDING_INFO -D V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH -D V8_SNAPSHOT_COMPRESSION -D V8_ENABLE_WEBASSEMBLY -D V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS -D V8_ALLOCATION_FOLDING -D V8_ALLOCATION_SITE_TRACKING -D V8_SCRIPTORMODULE_LEGACY_LIFETIME -D V8_ADVANCED_BIGINT_ALGORITHMS -D BUILDING_V8_BASE_SHARED -I ../deps/v8 -I ../deps/v8/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/backward -internal-isystem /usr/local/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-return-type -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-08-22-142216-507842-1 -x c++ ../deps/v8/src/base/platform/mutex.cc
1// Copyright 2013 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/base/platform/mutex.h"
6
7#include <errno(*__errno_location ()).h>
8
9#if DEBUG
10#include <unordered_set>
11#endif // DEBUG
12
13#if V8_OS_WIN
14#include <windows.h>
15#endif
16
17namespace v8 {
18namespace base {
19
20#if DEBUG
21namespace {
22// Used for asserts to guarantee we are not re-locking a mutex on the same
23// thread. If this thread has only one held shared mutex (common case), we use
24// {single_held_shared_mutex}. If it has more than one we allocate a set for it.
25// Said set has to manually be constructed and destroyed.
26thread_local base::SharedMutex* single_held_shared_mutex = nullptr;
27using TSet = std::unordered_set<base::SharedMutex*>;
28thread_local TSet* held_shared_mutexes = nullptr;
29
30// Returns true iff {shared_mutex} is not a held mutex.
31bool SharedMutexNotHeld(SharedMutex* shared_mutex) {
32 DCHECK_NOT_NULL(shared_mutex)((void) 0);
33 return single_held_shared_mutex != shared_mutex &&
34 (!held_shared_mutexes ||
35 held_shared_mutexes->count(shared_mutex) == 0);
36}
37
38// Tries to hold {shared_mutex}. Returns true iff it hadn't been held prior to
39// this function call.
40bool TryHoldSharedMutex(SharedMutex* shared_mutex) {
41 DCHECK_NOT_NULL(shared_mutex)((void) 0);
42 if (single_held_shared_mutex) {
43 if (shared_mutex == single_held_shared_mutex) {
44 return false;
45 }
46 DCHECK_NULL(held_shared_mutexes)((void) 0);
47 held_shared_mutexes = new TSet({single_held_shared_mutex, shared_mutex});
48 single_held_shared_mutex = nullptr;
49 return true;
50 } else if (held_shared_mutexes) {
51 return held_shared_mutexes->insert(shared_mutex).second;
52 } else {
53 DCHECK_NULL(single_held_shared_mutex)((void) 0);
54 single_held_shared_mutex = shared_mutex;
55 return true;
56 }
57}
58
59// Tries to release {shared_mutex}. Returns true iff it had been held prior to
60// this function call.
61bool TryReleaseSharedMutex(SharedMutex* shared_mutex) {
62 DCHECK_NOT_NULL(shared_mutex)((void) 0);
63 if (single_held_shared_mutex == shared_mutex) {
64 single_held_shared_mutex = nullptr;
65 return true;
66 }
67 if (held_shared_mutexes && held_shared_mutexes->erase(shared_mutex)) {
68 if (held_shared_mutexes->empty()) {
69 delete held_shared_mutexes;
70 held_shared_mutexes = nullptr;
71 }
72 return true;
73 }
74 return false;
75}
76} // namespace
77#endif // DEBUG
78
79#if V8_OS_POSIX1
80
81static V8_INLINEinline __attribute__((always_inline)) void InitializeNativeHandle(pthread_mutex_t* mutex) {
82 int result;
83#if defined(DEBUG)
84 // Use an error checking mutex in debug mode.
85 pthread_mutexattr_t attr;
86 result = pthread_mutexattr_init(&attr);
87 DCHECK_EQ(0, result)((void) 0);
88 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
89 DCHECK_EQ(0, result)((void) 0);
90 result = pthread_mutex_init(mutex, &attr);
91 DCHECK_EQ(0, result)((void) 0);
92 result = pthread_mutexattr_destroy(&attr);
93#else
94 // Use a fast mutex (default attributes).
95 result = pthread_mutex_init(mutex, nullptr);
96#endif // defined(DEBUG)
97 DCHECK_EQ(0, result)((void) 0);
98 USE(result)do { ::v8::base::Use unused_tmp_array_for_use_macro[]{result}
; (void)unused_tmp_array_for_use_macro; } while (false)
;
99}
100
101
102static V8_INLINEinline __attribute__((always_inline)) void InitializeRecursiveNativeHandle(pthread_mutex_t* mutex) {
103 pthread_mutexattr_t attr;
104 int result = pthread_mutexattr_init(&attr);
105 DCHECK_EQ(0, result)((void) 0);
106 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
Value stored to 'result' is never read
107 DCHECK_EQ(0, result)((void) 0);
108 result = pthread_mutex_init(mutex, &attr);
109 DCHECK_EQ(0, result)((void) 0);
110 result = pthread_mutexattr_destroy(&attr);
111 DCHECK_EQ(0, result)((void) 0);
112 USE(result)do { ::v8::base::Use unused_tmp_array_for_use_macro[]{result}
; (void)unused_tmp_array_for_use_macro; } while (false)
;
113}
114
115
116static V8_INLINEinline __attribute__((always_inline)) void DestroyNativeHandle(pthread_mutex_t* mutex) {
117 int result = pthread_mutex_destroy(mutex);
118 DCHECK_EQ(0, result)((void) 0);
119 USE(result)do { ::v8::base::Use unused_tmp_array_for_use_macro[]{result}
; (void)unused_tmp_array_for_use_macro; } while (false)
;
120}
121
122
123static V8_INLINEinline __attribute__((always_inline)) void LockNativeHandle(pthread_mutex_t* mutex) {
124 int result = pthread_mutex_lock(mutex);
125 DCHECK_EQ(0, result)((void) 0);
126 USE(result)do { ::v8::base::Use unused_tmp_array_for_use_macro[]{result}
; (void)unused_tmp_array_for_use_macro; } while (false)
;
127}
128
129
130static V8_INLINEinline __attribute__((always_inline)) void UnlockNativeHandle(pthread_mutex_t* mutex) {
131 int result = pthread_mutex_unlock(mutex);
132 DCHECK_EQ(0, result)((void) 0);
133 USE(result)do { ::v8::base::Use unused_tmp_array_for_use_macro[]{result}
; (void)unused_tmp_array_for_use_macro; } while (false)
;
134}
135
136
137static V8_INLINEinline __attribute__((always_inline)) bool TryLockNativeHandle(pthread_mutex_t* mutex) {
138 int result = pthread_mutex_trylock(mutex);
139 if (result == EBUSY16) {
140 return false;
141 }
142 DCHECK_EQ(0, result)((void) 0);
143 return true;
144}
145
146
147Mutex::Mutex() {
148 InitializeNativeHandle(&native_handle_);
149#ifdef DEBUG
150 level_ = 0;
151#endif
152}
153
154
155Mutex::~Mutex() {
156 DestroyNativeHandle(&native_handle_);
157 DCHECK_EQ(0, level_)((void) 0);
158}
159
160
161void Mutex::Lock() {
162 LockNativeHandle(&native_handle_);
163 AssertUnheldAndMark();
164}
165
166
167void Mutex::Unlock() {
168 AssertHeldAndUnmark();
169 UnlockNativeHandle(&native_handle_);
170}
171
172
173bool Mutex::TryLock() {
174 if (!TryLockNativeHandle(&native_handle_)) {
175 return false;
176 }
177 AssertUnheldAndMark();
178 return true;
179}
180
181
182RecursiveMutex::RecursiveMutex() {
183 InitializeRecursiveNativeHandle(&native_handle_);
184#ifdef DEBUG
185 level_ = 0;
186#endif
187}
188
189
190RecursiveMutex::~RecursiveMutex() {
191 DestroyNativeHandle(&native_handle_);
192 DCHECK_EQ(0, level_)((void) 0);
193}
194
195
196void RecursiveMutex::Lock() {
197 LockNativeHandle(&native_handle_);
198#ifdef DEBUG
199 DCHECK_LE(0, level_)((void) 0);
200 level_++;
201#endif
202}
203
204
205void RecursiveMutex::Unlock() {
206#ifdef DEBUG
207 DCHECK_LT(0, level_)((void) 0);
208 level_--;
209#endif
210 UnlockNativeHandle(&native_handle_);
211}
212
213
214bool RecursiveMutex::TryLock() {
215 if (!TryLockNativeHandle(&native_handle_)) {
216 return false;
217 }
218#ifdef DEBUG
219 DCHECK_LE(0, level_)((void) 0);
220 level_++;
221#endif
222 return true;
223}
224
225#if V8_OS_DARWIN
226
227SharedMutex::SharedMutex() { InitializeNativeHandle(&native_handle_); }
228
229SharedMutex::~SharedMutex() { DestroyNativeHandle(&native_handle_); }
230
231void SharedMutex::LockShared() { LockExclusive(); }
232
233void SharedMutex::LockExclusive() {
234 DCHECK(TryHoldSharedMutex(this))((void) 0);
235 LockNativeHandle(&native_handle_);
236}
237
238void SharedMutex::UnlockShared() { UnlockExclusive(); }
239
240void SharedMutex::UnlockExclusive() {
241 DCHECK(TryReleaseSharedMutex(this))((void) 0);
242 UnlockNativeHandle(&native_handle_);
243}
244
245bool SharedMutex::TryLockShared() { return TryLockExclusive(); }
246
247bool SharedMutex::TryLockExclusive() {
248 DCHECK(SharedMutexNotHeld(this))((void) 0);
249 if (!TryLockNativeHandle(&native_handle_)) return false;
250 DCHECK(TryHoldSharedMutex(this))((void) 0);
251 return true;
252}
253
254#else // !V8_OS_DARWIN
255
256SharedMutex::SharedMutex() { pthread_rwlock_init(&native_handle_, nullptr); }
257
258SharedMutex::~SharedMutex() {
259 int result = pthread_rwlock_destroy(&native_handle_);
260 DCHECK_EQ(0, result)((void) 0);
261 USE(result)do { ::v8::base::Use unused_tmp_array_for_use_macro[]{result}
; (void)unused_tmp_array_for_use_macro; } while (false)
;
262}
263
264void SharedMutex::LockShared() {
265 DCHECK(TryHoldSharedMutex(this))((void) 0);
266 int result = pthread_rwlock_rdlock(&native_handle_);
267 DCHECK_EQ(0, result)((void) 0);
268 USE(result)do { ::v8::base::Use unused_tmp_array_for_use_macro[]{result}
; (void)unused_tmp_array_for_use_macro; } while (false)
;
269}
270
271void SharedMutex::LockExclusive() {
272 DCHECK(TryHoldSharedMutex(this))((void) 0);
273 int result = pthread_rwlock_wrlock(&native_handle_);
274 DCHECK_EQ(0, result)((void) 0);
275 USE(result)do { ::v8::base::Use unused_tmp_array_for_use_macro[]{result}
; (void)unused_tmp_array_for_use_macro; } while (false)
;
276}
277
278void SharedMutex::UnlockShared() {
279 DCHECK(TryReleaseSharedMutex(this))((void) 0);
280 int result = pthread_rwlock_unlock(&native_handle_);
281 DCHECK_EQ(0, result)((void) 0);
282 USE(result)do { ::v8::base::Use unused_tmp_array_for_use_macro[]{result}
; (void)unused_tmp_array_for_use_macro; } while (false)
;
283}
284
285void SharedMutex::UnlockExclusive() {
286 // Same code as {UnlockShared} on POSIX.
287 UnlockShared();
288}
289
290bool SharedMutex::TryLockShared() {
291 DCHECK(SharedMutexNotHeld(this))((void) 0);
292 bool result = pthread_rwlock_tryrdlock(&native_handle_) == 0;
293 if (result) DCHECK(TryHoldSharedMutex(this))((void) 0);
294 return result;
295}
296
297bool SharedMutex::TryLockExclusive() {
298 DCHECK(SharedMutexNotHeld(this))((void) 0);
299 bool result = pthread_rwlock_trywrlock(&native_handle_) == 0;
300 if (result) DCHECK(TryHoldSharedMutex(this))((void) 0);
301 return result;
302}
303
304#endif // !V8_OS_DARWIN
305
306#elif V8_OS_WIN
307
308Mutex::Mutex() : native_handle_(SRWLOCK_INIT) {
309#ifdef DEBUG
310 level_ = 0;
311#endif
312}
313
314
315Mutex::~Mutex() {
316 DCHECK_EQ(0, level_)((void) 0);
317}
318
319
320void Mutex::Lock() {
321 AcquireSRWLockExclusive(V8ToWindowsType(&native_handle_));
322 AssertUnheldAndMark();
323}
324
325
326void Mutex::Unlock() {
327 AssertHeldAndUnmark();
328 ReleaseSRWLockExclusive(V8ToWindowsType(&native_handle_));
329}
330
331
332bool Mutex::TryLock() {
333 if (!TryAcquireSRWLockExclusive(V8ToWindowsType(&native_handle_))) {
334 return false;
335 }
336 AssertUnheldAndMark();
337 return true;
338}
339
340
341RecursiveMutex::RecursiveMutex() {
342 InitializeCriticalSection(V8ToWindowsType(&native_handle_));
343#ifdef DEBUG
344 level_ = 0;
345#endif
346}
347
348
349RecursiveMutex::~RecursiveMutex() {
350 DeleteCriticalSection(V8ToWindowsType(&native_handle_));
351 DCHECK_EQ(0, level_)((void) 0);
352}
353
354
355void RecursiveMutex::Lock() {
356 EnterCriticalSection(V8ToWindowsType(&native_handle_));
357#ifdef DEBUG
358 DCHECK_LE(0, level_)((void) 0);
359 level_++;
360#endif
361}
362
363
364void RecursiveMutex::Unlock() {
365#ifdef DEBUG
366 DCHECK_LT(0, level_)((void) 0);
367 level_--;
368#endif
369 LeaveCriticalSection(V8ToWindowsType(&native_handle_));
370}
371
372
373bool RecursiveMutex::TryLock() {
374 if (!TryEnterCriticalSection(V8ToWindowsType(&native_handle_))) {
375 return false;
376 }
377#ifdef DEBUG
378 DCHECK_LE(0, level_)((void) 0);
379 level_++;
380#endif
381 return true;
382}
383
384SharedMutex::SharedMutex() : native_handle_(SRWLOCK_INIT) {}
385
386SharedMutex::~SharedMutex() {}
387
388void SharedMutex::LockShared() {
389 DCHECK(TryHoldSharedMutex(this))((void) 0);
390 AcquireSRWLockShared(V8ToWindowsType(&native_handle_));
391}
392
393void SharedMutex::LockExclusive() {
394 DCHECK(TryHoldSharedMutex(this))((void) 0);
395 AcquireSRWLockExclusive(V8ToWindowsType(&native_handle_));
396}
397
398void SharedMutex::UnlockShared() {
399 DCHECK(TryReleaseSharedMutex(this))((void) 0);
400 ReleaseSRWLockShared(V8ToWindowsType(&native_handle_));
401}
402
403void SharedMutex::UnlockExclusive() {
404 DCHECK(TryReleaseSharedMutex(this))((void) 0);
405 ReleaseSRWLockExclusive(V8ToWindowsType(&native_handle_));
406}
407
408bool SharedMutex::TryLockShared() {
409 DCHECK(SharedMutexNotHeld(this))((void) 0);
410 bool result = TryAcquireSRWLockShared(V8ToWindowsType(&native_handle_));
411 if (result) DCHECK(TryHoldSharedMutex(this))((void) 0);
412 return result;
413}
414
415bool SharedMutex::TryLockExclusive() {
416 DCHECK(SharedMutexNotHeld(this))((void) 0);
417 bool result = TryAcquireSRWLockExclusive(V8ToWindowsType(&native_handle_));
418 if (result) DCHECK(TryHoldSharedMutex(this))((void) 0);
419 return result;
420}
421
422#elif V8_OS_STARBOARD
423
424Mutex::Mutex() { SbMutexCreate(&native_handle_); }
425
426Mutex::~Mutex() { SbMutexDestroy(&native_handle_); }
427
428void Mutex::Lock() { SbMutexAcquire(&native_handle_); }
429
430void Mutex::Unlock() { SbMutexRelease(&native_handle_); }
431
432RecursiveMutex::RecursiveMutex() {}
433
434RecursiveMutex::~RecursiveMutex() {}
435
436void RecursiveMutex::Lock() { native_handle_.Acquire(); }
437
438void RecursiveMutex::Unlock() { native_handle_.Release(); }
439
440bool RecursiveMutex::TryLock() { return native_handle_.AcquireTry(); }
441
442SharedMutex::SharedMutex() = default;
443
444SharedMutex::~SharedMutex() = default;
445
446void SharedMutex::LockShared() {
447 DCHECK(TryHoldSharedMutex(this))((void) 0);
448 native_handle_.AcquireReadLock();
449}
450
451void SharedMutex::LockExclusive() {
452 DCHECK(TryHoldSharedMutex(this))((void) 0);
453 native_handle_.AcquireWriteLock();
454}
455
456void SharedMutex::UnlockShared() {
457 DCHECK(TryReleaseSharedMutex(this))((void) 0);
458 native_handle_.ReleaseReadLock();
459}
460
461void SharedMutex::UnlockExclusive() {
462 DCHECK(TryReleaseSharedMutex(this))((void) 0);
463 native_handle_.ReleaseWriteLock();
464}
465
466bool SharedMutex::TryLockShared() {
467 DCHECK(SharedMutexNotHeld(this))((void) 0);
468 return false;
469}
470
471bool SharedMutex::TryLockExclusive() {
472 DCHECK(SharedMutexNotHeld(this))((void) 0);
473 return false;
474}
475#endif // V8_OS_STARBOARD
476
477} // namespace base
478} // namespace v8