1
/* Copyright (C) 2006 MySQL AB
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.
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.
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 */
17
#include <plugin/multi_thread/multi_thread.h>
18
#include "drizzled/pthread_globals.h"
19
#include <boost/program_options.hpp>
20
#include <drizzled/module/option_map.h>
21
#include <drizzled/errmsg_print.h>
23
#include <boost/thread.hpp>
24
#include <boost/bind.hpp>
26
namespace po= boost::program_options;
28
using namespace drizzled;
30
/* Configuration variables. */
31
static uint32_t max_threads;
34
static MultiThreadScheduler *scheduler= NULL;
38
extern size_t my_thread_stack_size;
41
void MultiThreadScheduler::runSession(drizzled::Session *session)
43
if (drizzled::internal::my_thread_init())
45
session->disconnect(drizzled::ER_OUT_OF_RESOURCES, true);
46
session->status_var.aborted_connects++;
47
killSessionNow(session);
49
boost::this_thread::at_thread_exit(&internal::my_thread_end);
51
session->thread_stack= (char*) &session;
53
killSessionNow(session);
56
void MultiThreadScheduler::setStackSize()
60
(void) pthread_attr_init(&attr);
62
/* Get the thread stack size that the OS will use and make sure
63
that we update our global variable. */
64
int err= pthread_attr_getstacksize(&attr, &my_thread_stack_size);
65
pthread_attr_destroy(&attr);
69
errmsg_printf(ERRMSG_LVL_ERROR, _("Unable to get thread stack size\n"));
70
my_thread_stack_size= 524288; // At the time of the writing of this code, this was OSX's
73
if (my_thread_stack_size == 0)
75
my_thread_stack_size= 524288; // At the time of the writing of this code, this was OSX's
79
* Solaris will return zero for the stack size in a call to
80
* pthread_attr_getstacksize() to indicate that the OS default stack
81
* size is used. We need an actual value in my_thread_stack_size so that
82
* check_stack_overrun() will work. The Solaris man page for the
83
* pthread_attr_getstacksize() function says that 2M is used for 64-bit
84
* processes. We'll explicitly set it here to make sure that is what
87
if (my_thread_stack_size == 0)
89
my_thread_stack_size= 2 * 1024 * 1024;
94
bool MultiThreadScheduler::addSession(Session *session)
96
if (thread_count >= max_threads)
99
thread_count.increment();
101
boost::thread new_thread(boost::bind(&MultiThreadScheduler::runSession, this, session));
103
if (not new_thread.joinable())
105
thread_count.decrement();
113
void MultiThreadScheduler::killSessionNow(Session *session)
115
/* Locks LOCK_thread_count and deletes session */
116
Session::unlink(session);
117
thread_count.decrement();
120
MultiThreadScheduler::~MultiThreadScheduler()
122
boost::mutex::scoped_lock scopedLock(LOCK_thread_count);
125
COND_thread_count.wait(scopedLock);
130
static int init(drizzled::module::Context &context)
133
const module::option_map &vm= context.getOptions();
134
if (vm.count("max-threads"))
136
if (max_threads > 4096 || max_threads < 1)
138
errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-threads\n"));
143
scheduler= new MultiThreadScheduler("multi_thread");
144
context.add(scheduler);
149
static DRIZZLE_SYSVAR_UINT(max_threads, max_threads,
151
N_("Maximum number of user threads available."),
152
NULL, NULL, 2048, 1, 4096, 0);
154
static void init_options(drizzled::module::option_context &context)
156
context("max-threads",
157
po::value<uint32_t>(&max_threads)->default_value(2048),
158
N_("Maximum number of user threads available."));
161
static drizzle_sys_var* sys_variables[]= {
162
DRIZZLE_SYSVAR(max_threads),
166
DRIZZLE_DECLARE_PLUGIN
172
"One Thread Per Session Scheduler",
174
init, /* Plugin Init */
175
sys_variables, /* system variables */
176
init_options /* config options */
178
DRIZZLE_DECLARE_PLUGIN_END;