/src/mysql-server/include/thr_rwlock.h
Line | Count | Source |
1 | | #ifndef THR_RWLOCK_INCLUDED |
2 | | #define THR_RWLOCK_INCLUDED |
3 | | |
4 | | /* Copyright (c) 2014, 2025, Oracle and/or its affiliates. |
5 | | |
6 | | This program is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License, version 2.0, |
8 | | as published by the Free Software Foundation. |
9 | | |
10 | | This program is designed to work with certain software (including |
11 | | but not limited to OpenSSL) that is licensed under separate terms, |
12 | | as designated in a particular file or component or in included license |
13 | | documentation. The authors of MySQL hereby grant you an additional |
14 | | permission to link the program and your derivative works with the |
15 | | separately licensed software that they have either included with |
16 | | the program or referenced in the documentation. |
17 | | |
18 | | This program is distributed in the hope that it will be useful, |
19 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 | | GNU General Public License, version 2.0, for more details. |
22 | | |
23 | | You should have received a copy of the GNU General Public License |
24 | | along with this program; if not, write to the Free Software |
25 | | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
26 | | |
27 | | /** |
28 | | @file include/thr_rwlock.h |
29 | | MySQL rwlock implementation. |
30 | | |
31 | | There are two "layers": |
32 | | 1) native_rw_*() |
33 | | Functions that map directly down to OS primitives. |
34 | | Windows - SRWLock |
35 | | Other OSes - pthread |
36 | | 2) mysql_rw*() |
37 | | Functions that include Performance Schema instrumentation. |
38 | | See include/mysql/psi/mysql_thread.h |
39 | | |
40 | | This file also includes rw_pr_*(), which implements a special |
41 | | version of rwlocks that prefer readers. The P_S version of these |
42 | | are mysql_prlock_*() - see include/mysql/psi/mysql_thread.h |
43 | | */ |
44 | | |
45 | | #ifdef SAFE_MUTEX |
46 | | #include <assert.h> |
47 | | #endif |
48 | | #ifdef _WIN32 |
49 | | #include <windows.h> |
50 | | #else |
51 | | #include <pthread.h> // IWYU pragma: export |
52 | | #endif |
53 | | |
54 | | #ifdef SAFE_MUTEX |
55 | | #include "my_thread.h" |
56 | | #endif |
57 | | #include "mysql/components/services/bits/thr_rwlock_bits.h" // IWYU pragma: export |
58 | | |
59 | 0 | static inline int native_rw_init(native_rw_lock_t *rwp) { |
60 | 0 | #ifdef _WIN32 |
61 | 0 | InitializeSRWLock(&rwp->srwlock); |
62 | 0 | rwp->have_exclusive_srwlock = false; |
63 | 0 | return 0; |
64 | 0 | #else |
65 | 0 | /* pthread_rwlockattr_t is not used in MySQL */ |
66 | 0 | return pthread_rwlock_init(rwp, nullptr); |
67 | 0 | #endif |
68 | 0 | } Unexecuted instantiation: sql_lexer.cc:native_rw_init(pthread_rwlock_t*) Unexecuted instantiation: my_init.cc:native_rw_init(pthread_rwlock_t*) |
69 | | |
70 | 0 | static inline int native_rw_destroy(native_rw_lock_t *rwp [[maybe_unused]]) { |
71 | 0 | #ifdef _WIN32 |
72 | 0 | return 0; /* no destroy function */ |
73 | 0 | #else |
74 | 0 | return pthread_rwlock_destroy(rwp); |
75 | 0 | #endif |
76 | 0 | } Unexecuted instantiation: sql_lexer.cc:native_rw_destroy(pthread_rwlock_t*) Unexecuted instantiation: my_init.cc:native_rw_destroy(pthread_rwlock_t*) |
77 | | |
78 | 0 | static inline int native_rw_rdlock(native_rw_lock_t *rwp) { |
79 | 0 | #ifdef _WIN32 |
80 | 0 | AcquireSRWLockShared(&rwp->srwlock); |
81 | 0 | return 0; |
82 | 0 | #else |
83 | 0 | return pthread_rwlock_rdlock(rwp); |
84 | 0 | #endif |
85 | 0 | } Unexecuted instantiation: sql_lexer.cc:native_rw_rdlock(pthread_rwlock_t*) Unexecuted instantiation: my_init.cc:native_rw_rdlock(pthread_rwlock_t*) |
86 | | |
87 | 0 | static inline int native_rw_tryrdlock(native_rw_lock_t *rwp) { |
88 | 0 | #ifdef _WIN32 |
89 | 0 | if (!TryAcquireSRWLockShared(&rwp->srwlock)) return EBUSY; |
90 | 0 | return 0; |
91 | 0 | #else |
92 | 0 | return pthread_rwlock_tryrdlock(rwp); |
93 | 0 | #endif |
94 | 0 | } Unexecuted instantiation: sql_lexer.cc:native_rw_tryrdlock(pthread_rwlock_t*) Unexecuted instantiation: my_init.cc:native_rw_tryrdlock(pthread_rwlock_t*) |
95 | | |
96 | 0 | static inline int native_rw_wrlock(native_rw_lock_t *rwp) { |
97 | 0 | #ifdef _WIN32 |
98 | 0 | AcquireSRWLockExclusive(&rwp->srwlock); |
99 | 0 | rwp->have_exclusive_srwlock = true; |
100 | 0 | return 0; |
101 | 0 | #else |
102 | 0 | return pthread_rwlock_wrlock(rwp); |
103 | 0 | #endif |
104 | 0 | } Unexecuted instantiation: sql_lexer.cc:native_rw_wrlock(pthread_rwlock_t*) Unexecuted instantiation: my_init.cc:native_rw_wrlock(pthread_rwlock_t*) |
105 | | |
106 | 0 | static inline int native_rw_trywrlock(native_rw_lock_t *rwp) { |
107 | 0 | #ifdef _WIN32 |
108 | 0 | if (!TryAcquireSRWLockExclusive(&rwp->srwlock)) return EBUSY; |
109 | 0 | rwp->have_exclusive_srwlock = true; |
110 | 0 | return 0; |
111 | 0 | #else |
112 | 0 | return pthread_rwlock_trywrlock(rwp); |
113 | 0 | #endif |
114 | 0 | } Unexecuted instantiation: sql_lexer.cc:native_rw_trywrlock(pthread_rwlock_t*) Unexecuted instantiation: my_init.cc:native_rw_trywrlock(pthread_rwlock_t*) |
115 | | |
116 | 0 | static inline int native_rw_unlock(native_rw_lock_t *rwp) { |
117 | 0 | #ifdef _WIN32 |
118 | 0 | if (rwp->have_exclusive_srwlock) { |
119 | 0 | rwp->have_exclusive_srwlock = false; |
120 | 0 | ReleaseSRWLockExclusive(&rwp->srwlock); |
121 | 0 | } else |
122 | 0 | ReleaseSRWLockShared(&rwp->srwlock); |
123 | 0 | return 0; |
124 | 0 | #else |
125 | 0 | return pthread_rwlock_unlock(rwp); |
126 | 0 | #endif |
127 | 0 | } Unexecuted instantiation: sql_lexer.cc:native_rw_unlock(pthread_rwlock_t*) Unexecuted instantiation: my_init.cc:native_rw_unlock(pthread_rwlock_t*) |
128 | | |
129 | | extern int rw_pr_init(rw_pr_lock_t *); |
130 | | extern int rw_pr_rdlock(rw_pr_lock_t *); |
131 | | extern int rw_pr_wrlock(rw_pr_lock_t *); |
132 | | extern int rw_pr_unlock(rw_pr_lock_t *); |
133 | | extern int rw_pr_destroy(rw_pr_lock_t *); |
134 | | |
135 | | #ifdef SAFE_MUTEX |
136 | | static inline void rw_pr_lock_assert_write_owner(const rw_pr_lock_t *rwlock) { |
137 | | assert(rwlock->active_writer && |
138 | | my_thread_equal(my_thread_self(), rwlock->writer_thread)); |
139 | | } |
140 | | |
141 | | static inline void rw_pr_lock_assert_not_write_owner( |
142 | | const rw_pr_lock_t *rwlock) { |
143 | | assert(!rwlock->active_writer || |
144 | | !my_thread_equal(my_thread_self(), rwlock->writer_thread)); |
145 | | } |
146 | | #endif |
147 | | |
148 | | #endif /* THR_RWLOCK_INCLUDED */ |