19
19
#include <boost/program_options.hpp>
20
20
#include <drizzled/module/option_map.h>
21
21
#include <drizzled/errmsg_print.h>
22
#include "drizzled/session.h"
23
#include "drizzled/session_list.h"
23
25
#include <boost/thread.hpp>
24
26
#include <boost/bind.hpp>
28
30
using namespace drizzled;
30
32
/* Configuration variables. */
31
static uint32_t max_threads;
34
static MultiThreadScheduler *scheduler= NULL;
33
typedef constrained_check<uint32_t, 4096, 1> max_threads_constraint;
34
static max_threads_constraint max_threads;
38
38
extern size_t my_thread_stack_size;
41
void MultiThreadScheduler::runSession(drizzled::Session *session)
41
namespace multi_thread {
43
void MultiThreadScheduler::runSession(drizzled::session_id_t id)
46
boost::this_thread::disable_interruption disable_by_default;
47
Session::shared_ptr session(session::Cache::singleton().find(id));
51
std::cerr << "Session killed before thread could execute\n";
54
session->pushInterrupt(&disable_by_default);
43
56
if (drizzled::internal::my_thread_init())
45
58
session->disconnect(drizzled::ER_OUT_OF_RESOURCES, true);
49
62
boost::this_thread::at_thread_exit(&internal::my_thread_end);
51
session->thread_stack= (char*) &session;
64
session->thread_stack= (char*) &stack_dummy;
53
66
killSessionNow(session);
67
// @todo remove hard spin by disconnection the session first from the
69
while (not session.unique()) {}
56
72
void MultiThreadScheduler::setStackSize()
94
bool MultiThreadScheduler::addSession(Session *session)
110
bool MultiThreadScheduler::addSession(Session::shared_ptr &session)
96
112
if (thread_count >= max_threads)
99
115
thread_count.increment();
101
boost::thread new_thread(boost::bind(&MultiThreadScheduler::runSession, this, session));
103
if (not new_thread.joinable())
117
session->getThread().reset(new boost::thread((boost::bind(&MultiThreadScheduler::runSession, this, session->getSessionId()))));
119
if (not session->getThread())
121
thread_count.decrement();
125
if (not session->getThread()->joinable())
105
127
thread_count.decrement();
113
void MultiThreadScheduler::killSessionNow(Session *session)
135
void MultiThreadScheduler::killSessionNow(Session::shared_ptr &session)
115
137
/* Locks LOCK_thread_count and deletes session */
116
138
Session::unlink(session);
120
142
MultiThreadScheduler::~MultiThreadScheduler()
122
boost::mutex::scoped_lock scopedLock(LOCK_thread_count);
144
boost::mutex::scoped_lock scopedLock(drizzled::session::Cache::singleton().mutex());
123
145
while (thread_count)
125
147
COND_thread_count.wait(scopedLock);
151
} // multi_thread namespace
130
154
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);
157
context.add(new multi_thread::MultiThreadScheduler("multi_thread"));
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
162
static void init_options(drizzled::module::option_context &context)
156
164
context("max-threads",
157
po::value<uint32_t>(&max_threads)->default_value(2048),
165
po::value<max_threads_constraint>(&max_threads)->default_value(2048),
158
166
N_("Maximum number of user threads available."));
161
static drizzle_sys_var* sys_variables[]= {
162
DRIZZLE_SYSVAR(max_threads),
166
169
DRIZZLE_DECLARE_PLUGIN
168
171
DRIZZLE_VERSION_ID,
172
175
"One Thread Per Session Scheduler",
173
176
PLUGIN_LICENSE_GPL,
174
177
init, /* Plugin Init */
175
sys_variables, /* system variables */
178
NULL, /* system variables */
176
179
init_options /* config options */
178
181
DRIZZLE_DECLARE_PLUGIN_END;