MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
scheduler.cc
1 /* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 /*
17  Implementation for the thread scheduler
18 */
19 
20 #include <sql_priv.h>
21 #include "unireg.h" // REQUIRED: for other includes
22 #include "scheduler.h"
23 #include "sql_connect.h" // init_new_connection_handler_thread
24 #include "scheduler.h"
25 #include "sql_callback.h"
26 #include "global_threads.h"
27 #include "mysql/thread_pool_priv.h"
28 
29 /*
30  End connection, in case when we are using 'no-threads'
31 */
32 
33 static bool no_threads_end(THD *thd, bool put_in_cache)
34 {
35  thd_release_resources(thd);
36  dec_connection_count();
37 
38  // THD is an incomplete type here, so use destroy_thd() to delete it.
39  mysql_mutex_lock(&LOCK_thread_count);
40  remove_global_thread(thd);
41  mysql_mutex_unlock(&LOCK_thread_count);
42  destroy_thd(thd);
43 
44  return 1; // Abort handle_one_connection
45 }
46 
47 static scheduler_functions one_thread_scheduler_functions=
48 {
49  1, // max_threads
50  NULL, // init
51  init_new_connection_handler_thread, // init_new_connection_thread
52 #ifndef EMBEDDED_LIBRARY
53  handle_connection_in_main_thread, // add_connection
54 #else
55  NULL, // add_connection
56 #endif // EMBEDDED_LIBRARY
57  NULL, // thd_wait_begin
58  NULL, // thd_wait_end
59  NULL, // post_kill_notification
60  no_threads_end, // end_thread
61  NULL, // end
62 };
63 
64 #ifndef EMBEDDED_LIBRARY
65 static scheduler_functions one_thread_per_connection_scheduler_functions=
66 {
67  0, // max_threads
68  NULL, // init
69  init_new_connection_handler_thread, // init_new_connection_thread
70  create_thread_to_handle_connection, // add_connection
71  NULL, // thd_wait_begin
72  NULL, // thd_wait_end
73  NULL, // post_kill_notification
74  one_thread_per_connection_end, // end_thread
75  NULL, // end
76 };
77 #endif // EMBEDDED_LIBRARY
78 
79 
80 scheduler_functions *thread_scheduler= NULL;
81 
88 extern "C"
89 {
90 static void scheduler_wait_lock_begin(void) {
91  MYSQL_CALLBACK(thread_scheduler,
92  thd_wait_begin, (current_thd, THD_WAIT_TABLE_LOCK));
93 }
94 
95 static void scheduler_wait_lock_end(void) {
96  MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (current_thd));
97 }
98 
99 static void scheduler_wait_sync_begin(void) {
100  MYSQL_CALLBACK(thread_scheduler,
101  thd_wait_begin, (current_thd, THD_WAIT_TABLE_LOCK));
102 }
103 
104 static void scheduler_wait_sync_end(void) {
105  MYSQL_CALLBACK(thread_scheduler, thd_wait_end, (current_thd));
106 }
107 };
117 static void scheduler_init() {
118  thr_set_lock_wait_callback(scheduler_wait_lock_begin,
119  scheduler_wait_lock_end);
120  thr_set_sync_wait_callback(scheduler_wait_sync_begin,
121  scheduler_wait_sync_end);
122 }
123 
124 /*
125  Initialize scheduler for --thread-handling=one-thread-per-connection
126 */
127 
128 #ifndef EMBEDDED_LIBRARY
129 void one_thread_per_connection_scheduler()
130 {
131  scheduler_init();
132  one_thread_per_connection_scheduler_functions.max_threads= max_connections;
133  thread_scheduler= &one_thread_per_connection_scheduler_functions;
134 }
135 #endif
136 
137 /*
138  Initailize scheduler for --thread-handling=no-threads
139 */
140 
141 void one_thread_scheduler()
142 {
143  scheduler_init();
144  thread_scheduler= &one_thread_scheduler_functions;
145 }
146 
147 
148 /*
149  Initialize scheduler for --thread-handling=one-thread-per-connection
150 */
151 
152 /*
153  thd_scheduler keeps the link between THD and events.
154  It's embedded in the THD class.
155 */
156 
157 thd_scheduler::thd_scheduler()
158  : m_psi(NULL), data(NULL)
159 {
160 }
161 
162 
163 thd_scheduler::~thd_scheduler()
164 {
165 }
166 
167 static scheduler_functions *saved_thread_scheduler;
168 static uint saved_thread_handling;
169 
170 extern "C"
171 int my_thread_scheduler_set(scheduler_functions *scheduler)
172 {
173  DBUG_ASSERT(scheduler != 0);
174 
175  if (scheduler == NULL)
176  return 1;
177 
178  saved_thread_scheduler= thread_scheduler;
179  saved_thread_handling= thread_handling;
180  thread_scheduler= scheduler;
181  // Scheduler loaded dynamically
182  thread_handling= SCHEDULER_TYPES_COUNT;
183  return 0;
184 }
185 
186 
187 extern "C"
188 int my_thread_scheduler_reset()
189 {
190  DBUG_ASSERT(saved_thread_scheduler != NULL);
191 
192  if (saved_thread_scheduler == NULL)
193  return 1;
194 
195  thread_scheduler= saved_thread_scheduler;
196  thread_handling= saved_thread_handling;
197  saved_thread_scheduler= 0;
198  return 0;
199 }
200 
201 
202