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#pragma once
18
19/* C++ standard header files */
20#include <string>
21
22/* MySQL includes */
23#include "./my_global.h"
24#ifdef _WIN32
25#include <my_pthread.h>
26/*
27 Rocksdb implements their own pthread_key functions
28 undefine some my_pthread.h macros
29*/
30#undef pthread_key_create
31#undef pthread_key_delete
32#undef pthread_setspecific
33#undef pthread_getspecific
34#endif
35#include <mysql/psi/mysql_table.h>
36#ifdef MARIAROCKS_NOT_YET
37#include <mysql/thread_pool_priv.h>
38#endif
39
40/* MyRocks header files */
41#include "./rdb_utils.h"
42
43namespace myrocks {
44
45class Rdb_thread {
46private:
47 // Disable Copying
48 Rdb_thread(const Rdb_thread &);
49 Rdb_thread &operator=(const Rdb_thread &);
50
51 // Make sure we run only once
52 std::atomic_bool m_run_once;
53
54 pthread_t m_handle;
55
56 std::string m_name;
57
58protected:
59 mysql_mutex_t m_signal_mutex;
60 mysql_cond_t m_signal_cond;
61 bool m_stop = false;
62
63public:
64 Rdb_thread() : m_run_once(false) {}
65
66#ifdef HAVE_PSI_INTERFACE
67 void init(my_core::PSI_mutex_key stop_bg_psi_mutex_key,
68 my_core::PSI_cond_key stop_bg_psi_cond_key);
69 int create_thread(const std::string &thread_name,
70 my_core::PSI_thread_key background_psi_thread_key);
71#else
72 void init();
73 int create_thread(const std::string &thread_name);
74#endif
75
76 virtual void run(void) = 0;
77
78 void signal(const bool &stop_thread = false);
79
80 int join()
81 {
82#ifndef _WIN32
83 return pthread_join(m_handle, nullptr);
84#else
85 /*
86 mysys on Windows creates "detached" threads in pthread_create().
87
88 m_handle here is the thread id I(it is not reused by the OS
89 thus it is safe to state there can't be other thread with
90 the same id at this point).
91
92 If thread is already finished before pthread_join(),
93 we get EINVAL, and it is safe to ignore and handle this as success.
94 */
95 pthread_join(m_handle, nullptr);
96 return 0;
97#endif
98 }
99
100 void setname() {
101 /*
102 mysql_thread_create() ends up doing some work underneath and setting the
103 thread name as "my-func". This isn't what we want. Our intent is to name
104 the threads according to their purpose so that when displayed under the
105 debugger then they'll be more easily identifiable. Therefore we'll reset
106 the name if thread was successfully created.
107 */
108
109 /*
110 We originally had the creator also set the thread name, but that seems to
111 not work correctly in all situations. Having the created thread do the
112 pthread_setname_np resolves the issue.
113 */
114 DBUG_ASSERT(!m_name.empty());
115#ifdef __linux__
116 int err = pthread_setname_np(m_handle, m_name.c_str());
117 if (err)
118 {
119 // NO_LINT_DEBUG
120 sql_print_warning(
121 "MyRocks: Failed to set name (%s) for current thread, errno=%d",
122 m_name.c_str(), errno);
123 }
124#endif
125 }
126
127 void uninit();
128
129 virtual ~Rdb_thread() {}
130
131private:
132 static void *thread_func(void *const thread_ptr);
133};
134
135/**
136 MyRocks background thread control
137 N.B. This is on top of RocksDB's own background threads
138 (@see rocksdb::CancelAllBackgroundWork())
139*/
140
141class Rdb_background_thread : public Rdb_thread {
142private:
143 bool m_save_stats = false;
144
145 void reset() {
146 mysql_mutex_assert_owner(&m_signal_mutex);
147 m_stop = false;
148 m_save_stats = false;
149 }
150
151public:
152 virtual void run() override;
153
154 void request_save_stats() {
155 RDB_MUTEX_LOCK_CHECK(m_signal_mutex);
156
157 m_save_stats = true;
158
159 RDB_MUTEX_UNLOCK_CHECK(m_signal_mutex);
160 }
161};
162
163/*
164 Drop index thread control
165*/
166
167struct Rdb_drop_index_thread : public Rdb_thread {
168 virtual void run() override;
169};
170
171} // namespace myrocks
172