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