~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
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
16
#include "config.h"
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
17
#include <plugin/multi_thread/multi_thread.h>
1241.9.31 by Monty Taylor
Moved global pthread variables into their own header.
18
#include "drizzled/pthread_globals.h"
1660.9.1 by Vijay Samuel
Merge refactored commandline for multi_thread using boost::program_options
19
#include <boost/program_options.hpp>
20
#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
21
#include <drizzled/errmsg_print.h>
1932.3.3 by Brian Aker
Pull in code to abstract out the session list a bit.
22
#include "drizzled/session.h"
1966.2.5 by Brian Aker
Style change around session list.
23
#include "drizzled/session/cache.h"
960.1.2 by Monty Taylor
Moved pthread_attrib into multi_thread class.
24
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
25
#include <boost/thread.hpp>
26
#include <boost/bind.hpp>
27
1660.9.1 by Vijay Samuel
Merge refactored commandline for multi_thread using boost::program_options
28
namespace po= boost::program_options;
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
29
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.
30
using namespace drizzled;
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
31
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.
32
/* Configuration variables. */
1897.4.11 by Monty Taylor
Multi-thread
33
typedef constrained_check<uint32_t, 4096, 1> max_threads_constraint;
34
static max_threads_constraint max_threads;
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
35
1703.2.4 by David Shrewsbury
Fix namespace issue on thread stack global var
36
namespace drizzled
37
{
38
  extern size_t my_thread_stack_size;
39
}
1703.2.1 by David Shrewsbury
Make 0 thread_stack mean use the OS default
40
1933.2.3 by Brian Aker
Have session store a copy of its current thread.
41
namespace multi_thread {
42
1932.3.13 by Brian Aker
Cleanup session ownership rules such that we know exactly when session has
43
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
44
{
1932.3.13 by Brian Aker
Cleanup session ownership rules such that we know exactly when session has
45
  char stack_dummy;
1933.2.4 by Brian Aker
Update user locks to allow for interruption based on boost.
46
  boost::this_thread::disable_interruption disable_by_default;
1932.3.13 by Brian Aker
Cleanup session ownership rules such that we know exactly when session has
47
  Session::shared_ptr session(session::Cache::singleton().find(id));
48
49
  if (not session)
50
  {
51
    std::cerr << "Session killed before thread could execute\n";
52
    return;
53
  }
1933.2.4 by Brian Aker
Update user locks to allow for interruption based on boost.
54
  session->pushInterrupt(&disable_by_default);
1932.3.13 by Brian Aker
Cleanup session ownership rules such that we know exactly when session has
55
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
56
  if (drizzled::internal::my_thread_init())
57
  {
2015.3.3 by Brian Aker
Update disconnect code.
58
    session->disconnect(drizzled::ER_OUT_OF_RESOURCES);
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
59
    session->status_var.aborted_connects++;
2015.3.3 by Brian Aker
Update disconnect code.
60
  }
61
  else
62
  {
63
    boost::this_thread::at_thread_exit(&internal::my_thread_end);
64
65
    session->thread_stack= (char*) &stack_dummy;
66
    session->run();
67
  }
68
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
69
  killSessionNow(session);
1932.3.13 by Brian Aker
Cleanup session ownership rules such that we know exactly when session has
70
  // @todo remove hard spin by disconnection the session first from the
71
  // thread.
72
  while (not session.unique()) {}
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
73
}
74
75
void MultiThreadScheduler::setStackSize()
76
{
77
  pthread_attr_t attr;
78
79
  (void) pthread_attr_init(&attr);
80
81
  /* Get the thread stack size that the OS will use and make sure
82
    that we update our global variable. */
83
  int err= pthread_attr_getstacksize(&attr, &my_thread_stack_size);
84
  pthread_attr_destroy(&attr);
85
86
  if (err != 0)
87
  {
88
    errmsg_printf(ERRMSG_LVL_ERROR, _("Unable to get thread stack size\n"));
89
    my_thread_stack_size= 524288; // At the time of the writing of this code, this was OSX's
90
  }
91
92
  if (my_thread_stack_size == 0)
93
  {
94
    my_thread_stack_size= 524288; // At the time of the writing of this code, this was OSX's
95
  }
1703.2.6 by David Shrewsbury
Fix for Solaris thread stack size issue.
96
#ifdef __sun
97
  /*
98
   * Solaris will return zero for the stack size in a call to
99
   * pthread_attr_getstacksize() to indicate that the OS default stack
100
   * size is used. We need an actual value in my_thread_stack_size so that
101
   * check_stack_overrun() will work. The Solaris man page for the
102
   * pthread_attr_getstacksize() function says that 2M is used for 64-bit
103
   * processes. We'll explicitly set it here to make sure that is what
104
   * will be used.
105
   */
106
  if (my_thread_stack_size == 0)
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
107
  {
1703.2.6 by David Shrewsbury
Fix for Solaris thread stack size issue.
108
    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
109
  }
1703.2.6 by David Shrewsbury
Fix for Solaris thread stack size issue.
110
#endif
1782 by Brian Aker
This modifies our thread system to be based on boost, and it fixes a
111
}
112
1932.3.13 by Brian Aker
Cleanup session ownership rules such that we know exactly when session has
113
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
114
{
115
  if (thread_count >= max_threads)
116
    return true;
1685.5.1 by David Shrewsbury
Fix for bug 532481: fixes OS X crash by support thread_stack option
117
1260.1.2 by Monty Taylor
Replaced operator overloads with methods since we can't actually usefully follow the proper semantics for the operators.
118
  thread_count.increment();
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
119
1933.2.3 by Brian Aker
Have session store a copy of its current thread.
120
  session->getThread().reset(new boost::thread((boost::bind(&MultiThreadScheduler::runSession, this, session->getSessionId()))));
121
122
  if (not session->getThread())
123
  {
124
    thread_count.decrement();
125
    return true;
126
  }
127
128
  if (not session->getThread()->joinable())
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
129
  {
1260.1.2 by Monty Taylor
Replaced operator overloads with methods since we can't actually usefully follow the proper semantics for the operators.
130
    thread_count.decrement();
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
131
    return true;
132
  }
133
134
  return false;
135
}
136
137
1961 by Brian Aker
This extends our coverage of interrupting active threads. With no crash
138
void MultiThreadScheduler::killSession(Session *session)
139
{
140
  boost_thread_shared_ptr thread(session->getThread());
141
142
  if (thread)
143
  {
144
    thread->interrupt();
145
  }
146
}
147
1932.3.13 by Brian Aker
Cleanup session ownership rules such that we know exactly when session has
148
void MultiThreadScheduler::killSessionNow(Session::shared_ptr &session)
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
149
{
1961 by Brian Aker
This extends our coverage of interrupting active threads. With no crash
150
  killSession(session.get());
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
151
  /* Locks LOCK_thread_count and deletes session */
1241.9.12 by Monty Taylor
Trims more out of server_includes.h.
152
  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.
153
  thread_count.decrement();
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
154
}
155
156
MultiThreadScheduler::~MultiThreadScheduler()
157
{
1932.3.4 by Brian Aker
Move counter lock so that ownership is held by session_list.
158
  boost::mutex::scoped_lock scopedLock(drizzled::session::Cache::singleton().mutex());
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
159
  while (thread_count)
160
  {
1755.2.7 by Brian Aker
Refactor, boost direct use.
161
    COND_thread_count.wait(scopedLock);
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
162
  }
163
}
164
1933.2.3 by Brian Aker
Have session store a copy of its current thread.
165
} // multi_thread namespace
166
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
167
  
1530.2.6 by Monty Taylor
Moved plugin::Context to module::Context.
168
static int init(drizzled::module::Context &context)
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
169
{
1660.9.1 by Vijay Samuel
Merge refactored commandline for multi_thread using boost::program_options
170
  
1933.2.3 by Brian Aker
Have session store a copy of its current thread.
171
  context.add(new multi_thread::MultiThreadScheduler("multi_thread"));
1152.1.5 by Brian Aker
Remove Factory/make scheduler work like everything else.
172
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
173
  return 0;
174
}
175
1660.9.1 by Vijay Samuel
Merge refactored commandline for multi_thread using boost::program_options
176
static void init_options(drizzled::module::option_context &context)
177
{
178
  context("max-threads",
1897.4.11 by Monty Taylor
Multi-thread
179
          po::value<max_threads_constraint>(&max_threads)->default_value(2048),
1660.9.1 by Vijay Samuel
Merge refactored commandline for multi_thread using boost::program_options
180
          N_("Maximum number of user threads available."));
181
}
182
1228.1.5 by Monty Taylor
Merged in some naming things.
183
DRIZZLE_DECLARE_PLUGIN
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
184
{
1241.10.2 by Monty Taylor
Added support for embedding the drizzle version number in the plugin file.
185
  DRIZZLE_VERSION_ID,
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
186
  "multi_thread",
187
  "0.1",
188
  "Brian Aker",
960.1.1 by Monty Taylor
First pass at scheduler plugin.
189
  "One Thread Per Session Scheduler",
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
190
  PLUGIN_LICENSE_GPL,
191
  init, /* Plugin Init */
1897.4.11 by Monty Taylor
Multi-thread
192
  NULL,   /* system variables */
1660.9.1 by Vijay Samuel
Merge refactored commandline for multi_thread using boost::program_options
193
  init_options    /* config options */
868 by Brian Aker
Adding Multi-threaded Scheduler into the system.
194
}
1228.1.5 by Monty Taylor
Merged in some naming things.
195
DRIZZLE_DECLARE_PLUGIN_END;