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