~drizzle-trunk/drizzle/development

868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
1
/* Copyright (C) 2006 MySQL AB
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
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
16
#include <config.h>
2040.7.1 by Monty Taylor
Added an abort macro and an abort_exception.
17
18
#include <iostream>
19
20
#include <drizzled/pthread_globals.h>
1660.9.1 by Vijay Samuel
Merge refactored commandline for multi_thread using boost::program_options
21
#include <drizzled/module/option_map.h>
1685.5.1 by David Shrewsbury
Fix for bug 532481: fixes OS X crash by support thread_stack option
22
#include <drizzled/errmsg_print.h>
2040.7.1 by Monty Taylor
Added an abort macro and an abort_exception.
23
#include <drizzled/session.h>
24
#include <drizzled/session/cache.h>
25
#include <drizzled/abort_exception.h>
26
#include <drizzled/transaction_services.h>
27
#include <drizzled/gettext.h>
2239.1.6 by Olaf van der Spek
Refactor includes
28
#include <drizzled/plugin.h>
2241.3.1 by Olaf van der Spek
Refactor Session::status_var
29
#include <drizzled/statistics_variables.h>
960.1.2 by Monty Taylor
Moved pthread_attrib into multi_thread class.
30
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
31
#include <boost/thread.hpp>
32
#include <boost/bind.hpp>
2040.7.1 by Monty Taylor
Added an abort macro and an abort_exception.
33
#include <boost/program_options.hpp>
34
35
#include "multi_thread.h"
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
36
1660.9.1 by Vijay Samuel
Merge refactored commandline for multi_thread using boost::program_options
37
namespace po= boost::program_options;
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
38
using namespace std;
971.3.64 by Eric Day
Cleaned up Scheduler plugin, moved more code to the schedular plugins, reworked some functions to be methods in Session, removed some dead code.
39
using namespace drizzled;
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
40
971.3.64 by Eric Day
Cleaned up Scheduler plugin, moved more code to the schedular plugins, reworked some functions to be methods in Session, removed some dead code.
41
/* Configuration variables. */
1897.4.11 by Monty Taylor
Multi-thread
42
typedef constrained_check<uint32_t, 4096, 1> max_threads_constraint;
43
static max_threads_constraint max_threads;
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
44
1703.2.4 by David Shrewsbury
Fix namespace issue on thread stack global var
45
namespace drizzled
46
{
47
  extern size_t my_thread_stack_size;
48
}
1703.2.1 by David Shrewsbury
Make 0 thread_stack mean use the OS default
49
1933.2.3 by Brian Aker
Have session store a copy of its current thread.
50
namespace multi_thread {
51
1932.3.13 by Brian Aker
Cleanup session ownership rules such that we know exactly when session has
52
void MultiThreadScheduler::runSession(drizzled::session_id_t id)
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
53
{
1932.3.13 by Brian Aker
Cleanup session ownership rules such that we know exactly when session has
54
  char stack_dummy;
1933.2.4 by Brian Aker
Update user locks to allow for interruption based on boost.
55
  boost::this_thread::disable_interruption disable_by_default;
2040.7.1 by Monty Taylor
Added an abort macro and an abort_exception.
56
2282.1.2 by Olaf van der Spek
Session Cache
57
  Session::shared_ptr session(session::Cache::find(id));
1932.3.13 by Brian Aker
Cleanup session ownership rules such that we know exactly when session has
58
2040.7.1 by Monty Taylor
Added an abort macro and an abort_exception.
59
  try
60
  {
61
62
    if (not session)
63
    {
64
      std::cerr << _("Session killed before thread could execute") << endl;
65
      return;
66
    }
67
    session->pushInterrupt(&disable_by_default);
2281.4.5 by Olaf van der Spek
Prune & refactor
68
    drizzled::internal::my_thread_init();
69
    session->thread_stack= (char*) &stack_dummy;
70
    session->run();
2040.7.1 by Monty Taylor
Added an abort macro and an abort_exception.
71
72
    killSessionNow(session);
73
  }
74
  catch (abort_exception& ex)
75
  {
76
    cout << _("Drizzle has receieved an abort event.") << endl;
77
    cout << _("In Function: ") << *::boost::get_error_info<boost::throw_function>(ex) << endl;
78
    cout << _("In File: ") << *::boost::get_error_info<boost::throw_file>(ex) << endl;
79
    cout << _("On Line: ") << *::boost::get_error_info<boost::throw_line>(ex) << endl;
80
2318.6.62 by Olaf van der Spek
Refactor
81
    TransactionServices::sendShutdownEvent(*session.get());
2040.7.1 by Monty Taylor
Added an abort macro and an abort_exception.
82
  }
1932.3.13 by Brian Aker
Cleanup session ownership rules such that we know exactly when session has
83
  // @todo remove hard spin by disconnection the session first from the
84
  // thread.
85
  while (not session.unique()) {}
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
86
}
87
88
void MultiThreadScheduler::setStackSize()
89
{
90
  pthread_attr_t attr;
91
92
  (void) pthread_attr_init(&attr);
93
94
  /* Get the thread stack size that the OS will use and make sure
95
    that we update our global variable. */
96
  int err= pthread_attr_getstacksize(&attr, &my_thread_stack_size);
97
  pthread_attr_destroy(&attr);
98
99
  if (err != 0)
100
  {
2126.3.3 by Brian Aker
Merge in error message rework. Many error messages are fixed in this patch.
101
    errmsg_printf(error::ERROR, _("Unable to get thread stack size"));
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
102
    my_thread_stack_size= 524288; // At the time of the writing of this code, this was OSX's
103
  }
104
105
  if (my_thread_stack_size == 0)
106
  {
107
    my_thread_stack_size= 524288; // At the time of the writing of this code, this was OSX's
108
  }
1703.2.6 by David Shrewsbury
Fix for Solaris thread stack size issue.
109
#ifdef __sun
110
  /*
111
   * Solaris will return zero for the stack size in a call to
112
   * pthread_attr_getstacksize() to indicate that the OS default stack
113
   * size is used. We need an actual value in my_thread_stack_size so that
114
   * check_stack_overrun() will work. The Solaris man page for the
115
   * pthread_attr_getstacksize() function says that 2M is used for 64-bit
116
   * processes. We'll explicitly set it here to make sure that is what
117
   * will be used.
118
   */
119
  if (my_thread_stack_size == 0)
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
120
  {
1703.2.6 by David Shrewsbury
Fix for Solaris thread stack size issue.
121
    my_thread_stack_size= 2 * 1024 * 1024;
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
122
  }
1703.2.6 by David Shrewsbury
Fix for Solaris thread stack size issue.
123
#endif
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
124
}
125
2318.6.43 by Olaf van der Spek
Refactor
126
bool MultiThreadScheduler::addSession(const Session::shared_ptr& session)
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
127
{
128
  if (thread_count >= max_threads)
129
    return true;
1685.5.1 by David Shrewsbury
Fix for bug 532481: fixes OS X crash by support thread_stack option
130
1260.1.2 by Monty Taylor
Replaced operator overloads with methods since we can't actually usefully follow the proper semantics for the operators.
131
  thread_count.increment();
2039.2.1 by Andrew Hutchings
When spawning many sessions it is possible to hit "ulimit -u" (I didn't even realise this affected thread counts).
132
  try
133
  {
134
    session->getThread().reset(new boost::thread((boost::bind(&MultiThreadScheduler::runSession, this, session->getSessionId()))));
135
  }
136
  catch (std::exception&)
137
  {
138
    thread_count.decrement();
139
    return true;
140
  }
1933.2.3 by Brian Aker
Have session store a copy of its current thread.
141
142
  if (not session->getThread())
143
  {
144
    thread_count.decrement();
145
    return true;
146
  }
147
148
  if (not session->getThread()->joinable())
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
149
  {
1260.1.2 by Monty Taylor
Replaced operator overloads with methods since we can't actually usefully follow the proper semantics for the operators.
150
    thread_count.decrement();
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
151
    return true;
152
  }
153
154
  return false;
155
}
156
157
1961 by Brian Aker
This extends our coverage of interrupting active threads. With no crash
158
void MultiThreadScheduler::killSession(Session *session)
159
{
2275.3.3 by Olaf van der Spek
Thread
160
  thread_ptr thread(session->getThread());
1961 by Brian Aker
This extends our coverage of interrupting active threads. With no crash
161
162
  if (thread)
163
  {
164
    thread->interrupt();
165
  }
166
}
167
2318.6.43 by Olaf van der Spek
Refactor
168
void MultiThreadScheduler::killSessionNow(const Session::shared_ptr& session)
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
169
{
1961 by Brian Aker
This extends our coverage of interrupting active threads. With no crash
170
  killSession(session.get());
2062.2.1 by Brian Aker
Begin process to disconnect before moving the connection out of the session
171
172
  session->disconnect();
173
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
174
  /* Locks LOCK_thread_count and deletes session */
1241.9.12 by Monty Taylor
Trims more out of server_includes.h.
175
  Session::unlink(session);
1260.1.2 by Monty Taylor
Replaced operator overloads with methods since we can't actually usefully follow the proper semantics for the operators.
176
  thread_count.decrement();
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
177
}
178
179
MultiThreadScheduler::~MultiThreadScheduler()
180
{
2275.3.2 by Olaf van der Spek
Session Cache
181
  boost::mutex::scoped_lock scopedLock(drizzled::session::Cache::mutex());
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
182
  while (thread_count)
183
  {
1755.2.7 by Brian Aker
Refactor, boost direct use.
184
    COND_thread_count.wait(scopedLock);
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
185
  }
186
}
187
1933.2.3 by Brian Aker
Have session store a copy of its current thread.
188
} // multi_thread namespace
189
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
190
  
1530.2.6 by Monty Taylor
Moved plugin::Context to module::Context.
191
static int init(drizzled::module::Context &context)
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
192
{
1660.9.1 by Vijay Samuel
Merge refactored commandline for multi_thread using boost::program_options
193
  
1933.2.3 by Brian Aker
Have session store a copy of its current thread.
194
  context.add(new multi_thread::MultiThreadScheduler("multi_thread"));
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
195
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
196
  return 0;
197
}
198
1660.9.1 by Vijay Samuel
Merge refactored commandline for multi_thread using boost::program_options
199
static void init_options(drizzled::module::option_context &context)
200
{
201
  context("max-threads",
1897.4.11 by Monty Taylor
Multi-thread
202
          po::value<max_threads_constraint>(&max_threads)->default_value(2048),
2068.4.1 by Andrew Hutchings
Fix intl domain
203
          _("Maximum number of user threads available."));
1660.9.1 by Vijay Samuel
Merge refactored commandline for multi_thread using boost::program_options
204
}
205
1228.1.5 by Monty Taylor
Merged in some naming things.
206
DRIZZLE_DECLARE_PLUGIN
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
207
{
1241.10.2 by Monty Taylor
Added support for embedding the drizzle version number in the plugin file.
208
  DRIZZLE_VERSION_ID,
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
209
  "multi_thread",
210
  "0.1",
211
  "Brian Aker",
960.1.1 by Monty Taylor
First pass at scheduler plugin.
212
  "One Thread Per Session Scheduler",
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
213
  PLUGIN_LICENSE_GPL,
214
  init, /* Plugin Init */
2095.3.1 by Monty Taylor
Re-purpose the old plugin sysvar slot in the struct to be a depends list.
215
  NULL,   /* depends */
1660.9.1 by Vijay Samuel
Merge refactored commandline for multi_thread using boost::program_options
216
  init_options    /* config options */
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
217
}
1228.1.5 by Monty Taylor
Merged in some naming things.
218
DRIZZLE_DECLARE_PLUGIN_END;