1 /*
2 * Copyright (c) 2015, 2021, Oracle and/or its affiliates.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2.0,
6 * as published by the Free Software Foundation.
7 *
8 * This program is also distributed with certain software (including
9 * but not limited to OpenSSL) that is licensed under separate terms,
10 * as designated in a particular file or component or in included license
11 * documentation. The authors of MySQL hereby grant you an additional
12 * permission to link the program and your derivative works with the
13 * separately licensed software that they have included with MySQL.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License, version 2.0, for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26 #include "ngs/thread.h"
27 #include "ngs/memory.h"
28 #include "my_thread.h"
29 #include "my_sys.h" // my_thread_stack_size
30
31
thread_create(PSI_thread_key key,Thread_t * thread,Start_routine_t func,void * arg)32 void ngs::thread_create(PSI_thread_key key, Thread_t *thread,
33 Start_routine_t func, void *arg)
34 {
35 my_thread_attr_t connection_attrib;
36
37 (void)my_thread_attr_init(&connection_attrib);
38 /*
39 check_stack_overrun() assumes that stack size is (at least)
40 my_thread_stack_size. If it is smaller, we may segfault.
41 */
42 my_thread_attr_setstacksize(&connection_attrib, my_thread_stack_size);
43
44 if (mysql_thread_create(key, thread, &connection_attrib, func, arg))
45 throw std::runtime_error("Could not create a thread");
46 }
47
48
thread_join(Thread_t * thread,void ** ret)49 int ngs::thread_join(Thread_t *thread, void **ret)
50 {
51 return my_thread_join(thread, ret);
52 }
53
54
Mutex(PSI_mutex_key key)55 ngs::Mutex::Mutex(PSI_mutex_key key)
56 {
57 mysql_mutex_init(key, &m_mutex, NULL);
58 }
59
60
~Mutex()61 ngs::Mutex::~Mutex()
62 {
63 mysql_mutex_destroy(&m_mutex);
64 }
65
66
operator mysql_mutex_t*()67 ngs::Mutex::operator mysql_mutex_t*()
68 {
69 return &m_mutex;
70 }
71
72
73
RWLock(PSI_rwlock_key key)74 ngs::RWLock::RWLock(PSI_rwlock_key key)
75 {
76 mysql_rwlock_init(key, &m_rwlock);
77 }
78
79
~RWLock()80 ngs::RWLock::~RWLock()
81 {
82 mysql_rwlock_destroy(&m_rwlock);
83 }
84
85
Cond(PSI_cond_key key)86 ngs::Cond::Cond(PSI_cond_key key)
87 {
88 mysql_cond_init(key, &m_cond);
89 }
90
91
~Cond()92 ngs::Cond::~Cond()
93 {
94 mysql_cond_destroy(&m_cond);
95 }
96
97
wait(Mutex & mutex)98 void ngs::Cond::wait(Mutex& mutex)
99 {
100 mysql_cond_wait(&m_cond, &mutex.m_mutex);
101 }
102
103
timed_wait(Mutex & mutex,unsigned long long nanoseconds)104 int ngs::Cond::timed_wait(Mutex& mutex, unsigned long long nanoseconds)
105 {
106 timespec ts;
107
108 set_timespec_nsec(&ts, nanoseconds);
109
110 return mysql_cond_timedwait(&m_cond, &mutex.m_mutex, &ts);
111 }
112
113
signal()114 void ngs::Cond::signal()
115 {
116 mysql_cond_signal(&m_cond);
117 }
118
119
signal(Mutex & mutex)120 void ngs::Cond::signal(Mutex& mutex)
121 {
122 Mutex_lock lock(mutex);
123
124 signal();
125 }
126
127
broadcast()128 void ngs::Cond::broadcast()
129 {
130 mysql_cond_broadcast(&m_cond);
131 }
132
133
broadcast(Mutex & mutex)134 void ngs::Cond::broadcast(Mutex& mutex)
135 {
136 Mutex_lock lock(mutex);
137
138 broadcast();
139 }
140
141 unsigned int ngs::x_psf_objects_key = 0;
142
143