1 /*
2    Portions Copyright (c) 2015-Present, Facebook, Inc.
3    Portions Copyright (c) 2012, Monty Program Ab
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; version 2 of the License.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
17 
18 #ifdef USE_PRAGMA_IMPLEMENTATION
19 #pragma implementation // gcc: Class implementation
20 #endif
21 
22 /* The C++ file's header */
23 #include "./rdb_threads.h"
24 
25 namespace myrocks {
26 
thread_func(void * const thread_ptr)27 void *Rdb_thread::thread_func(void *const thread_ptr) {
28   DBUG_ASSERT(thread_ptr != nullptr);
29   Rdb_thread *const thread = static_cast<Rdb_thread *const>(thread_ptr);
30   if (!thread->m_run_once.exchange(true)) {
31     thread->run();
32     thread->uninit();
33   }
34   return nullptr;
35 }
36 
init(my_core::PSI_mutex_key stop_bg_psi_mutex_key,my_core::PSI_cond_key stop_bg_psi_cond_key)37 void Rdb_thread::init(
38 #ifdef HAVE_PSI_INTERFACE
39     my_core::PSI_mutex_key stop_bg_psi_mutex_key,
40     my_core::PSI_cond_key stop_bg_psi_cond_key
41 #endif
42     ) {
43   DBUG_ASSERT(!m_run_once);
44   mysql_mutex_init(stop_bg_psi_mutex_key, &m_signal_mutex, MY_MUTEX_INIT_FAST);
45   mysql_cond_init(stop_bg_psi_cond_key, &m_signal_cond, nullptr);
46 }
47 
uninit()48 void Rdb_thread::uninit() {
49   mysql_mutex_destroy(&m_signal_mutex);
50   mysql_cond_destroy(&m_signal_cond);
51 }
52 
create_thread(const std::string & thread_name,PSI_thread_key background_psi_thread_key)53 int Rdb_thread::create_thread(const std::string &thread_name
54 #ifdef HAVE_PSI_INTERFACE
55                               ,
56                               PSI_thread_key background_psi_thread_key
57 #endif
58                               ) {
59   DBUG_ASSERT(!thread_name.empty());
60 
61   int err = mysql_thread_create(background_psi_thread_key, &m_handle, nullptr,
62                                 thread_func, this);
63 
64   if (!err) {
65     /*
66       mysql_thread_create() ends up doing some work underneath and setting the
67       thread name as "my-func". This isn't what we want. Our intent is to name
68       the threads according to their purpose so that when displayed under the
69       debugger then they'll be more easily identifiable. Therefore we'll reset
70       the name if thread was successfully created.
71     */
72     err = pthread_setname_np(m_handle, thread_name.c_str());
73   }
74 
75   return err;
76 }
77 
signal(const bool & stop_thread)78 void Rdb_thread::signal(const bool &stop_thread) {
79   mysql_mutex_lock(&m_signal_mutex);
80   if (stop_thread) {
81     m_stop = true;
82   }
83   mysql_cond_signal(&m_signal_cond);
84   mysql_mutex_unlock(&m_signal_mutex);
85 }
86 
87 } // namespace myrocks
88