MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_manager.cc
1 /* Copyright (c) 2000, 2010, 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  * sql_manager.cc
18  * This thread manages various maintenance tasks.
19  *
20  * o Flushing the tables every flush_time seconds.
21  * o Berkeley DB: removing unneeded log files.
22  */
23 
24 #include "sql_priv.h"
25 #include "sql_manager.h"
26 #include "unireg.h" // REQUIRED: for other includes
27 #include "sql_base.h" // flush_tables
28 
29 static bool volatile manager_thread_in_use;
30 static bool abort_manager;
31 
32 pthread_t manager_thread;
33 mysql_mutex_t LOCK_manager;
34 mysql_cond_t COND_manager;
35 
36 struct handler_cb {
37  struct handler_cb *next;
38  void (*action)(void);
39 };
40 
41 static struct handler_cb * volatile cb_list;
42 
43 bool mysql_manager_submit(void (*action)())
44 {
45  bool result= FALSE;
46  struct handler_cb * volatile *cb;
47  mysql_mutex_lock(&LOCK_manager);
48  cb= &cb_list;
49  while (*cb && (*cb)->action != action)
50  cb= &(*cb)->next;
51  if (!*cb)
52  {
53  *cb= (struct handler_cb *)my_malloc(sizeof(struct handler_cb), MYF(MY_WME));
54  if (!*cb)
55  result= TRUE;
56  else
57  {
58  (*cb)->next= NULL;
59  (*cb)->action= action;
60  }
61  }
62  mysql_mutex_unlock(&LOCK_manager);
63  return result;
64 }
65 
66 pthread_handler_t handle_manager(void *arg __attribute__((unused)))
67 {
68  int error = 0;
69  struct timespec abstime;
70  bool reset_flush_time = TRUE;
71  struct handler_cb *cb= NULL;
72  my_thread_init();
73  DBUG_ENTER("handle_manager");
74 
75  pthread_detach_this_thread();
76  manager_thread = pthread_self();
77  manager_thread_in_use = 1;
78 
79  for (;;)
80  {
81  mysql_mutex_lock(&LOCK_manager);
82  /* XXX: This will need to be made more general to handle different
83  * polling needs. */
84  if (flush_time)
85  {
86  if (reset_flush_time)
87  {
88  set_timespec(abstime, flush_time);
89  reset_flush_time = FALSE;
90  }
91  while ((!error || error == EINTR) && !abort_manager)
92  error= mysql_cond_timedwait(&COND_manager, &LOCK_manager, &abstime);
93  }
94  else
95  {
96  while ((!error || error == EINTR) && !abort_manager)
97  error= mysql_cond_wait(&COND_manager, &LOCK_manager);
98  }
99  if (cb == NULL)
100  {
101  cb= cb_list;
102  cb_list= NULL;
103  }
104  mysql_mutex_unlock(&LOCK_manager);
105 
106  if (abort_manager)
107  break;
108 
109  if (error == ETIMEDOUT || error == ETIME)
110  {
111  tdc_flush_unused_tables();
112  error = 0;
113  reset_flush_time = TRUE;
114  }
115 
116  while (cb)
117  {
118  struct handler_cb *next= cb->next;
119  cb->action();
120  my_free(cb);
121  cb= next;
122  }
123  }
124  manager_thread_in_use = 0;
125  DBUG_LEAVE; // Can't use DBUG_RETURN after my_thread_end
126  my_thread_end();
127  return (NULL);
128 }
129 
130 
131 /* Start handle manager thread */
132 void start_handle_manager()
133 {
134  DBUG_ENTER("start_handle_manager");
135  abort_manager = false;
136  if (flush_time && flush_time != ~(ulong) 0L)
137  {
138  pthread_t hThread;
139  int error;
140  if ((error= mysql_thread_create(key_thread_handle_manager,
141  &hThread, &connection_attrib,
142  handle_manager, 0)))
143  sql_print_warning("Can't create handle_manager thread (errno= %d)",
144  error);
145  }
146  DBUG_VOID_RETURN;
147 }
148 
149 
150 /* Initiate shutdown of handle manager thread */
151 void stop_handle_manager()
152 {
153  DBUG_ENTER("stop_handle_manager");
154  abort_manager = true;
155  mysql_mutex_lock(&LOCK_manager);
156  if (manager_thread_in_use)
157  {
158  DBUG_PRINT("quit", ("initiate shutdown of handle manager thread: 0x%lx",
159  (ulong)manager_thread));
160  mysql_cond_signal(&COND_manager);
161  }
162  mysql_mutex_unlock(&LOCK_manager);
163  DBUG_VOID_RETURN;
164 }
165