13
13
along with this program; if not, write to the Free Software
14
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
20
#include <drizzled/pthread_globals.h>
17
#include <plugin/multi_thread/multi_thread.h>
18
#include "drizzled/pthread_globals.h"
19
#include <boost/program_options.hpp>
21
20
#include <drizzled/module/option_map.h>
22
21
#include <drizzled/errmsg_print.h>
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>
29
23
#include <boost/thread.hpp>
30
24
#include <boost/bind.hpp>
31
#include <boost/program_options.hpp>
33
#include "multi_thread.h"
35
26
namespace po= boost::program_options;
36
27
using namespace std;
45
36
extern size_t my_thread_stack_size;
48
namespace multi_thread {
50
void MultiThreadScheduler::runSession(drizzled::session_id_t id)
39
void MultiThreadScheduler::runSession(drizzled::Session *session)
53
boost::this_thread::disable_interruption disable_by_default;
55
Session::shared_ptr session(session::Cache::singleton().find(id));
41
if (drizzled::internal::my_thread_init())
62
std::cerr << _("Session killed before thread could execute") << endl;
65
session->pushInterrupt(&disable_by_default);
67
if (drizzled::internal::my_thread_init())
69
session->disconnect(drizzled::ER_OUT_OF_RESOURCES);
70
session->status_var.aborted_connects++;
74
boost::this_thread::at_thread_exit(&internal::my_thread_end);
76
session->thread_stack= (char*) &stack_dummy;
43
session->disconnect(drizzled::ER_OUT_OF_RESOURCES, true);
44
session->status_var.aborted_connects++;
80
45
killSessionNow(session);
82
catch (abort_exception& ex)
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;
47
boost::this_thread::at_thread_exit(&internal::my_thread_end);
89
TransactionServices::singleton().sendShutdownEvent(*session.get());
91
// @todo remove hard spin by disconnection the session first from the
93
while (not session.unique()) {}
49
session->thread_stack= (char*) &session;
51
killSessionNow(session);
96
54
void MultiThreadScheduler::setStackSize()
109
errmsg_printf(error::ERROR, _("Unable to get thread stack size"));
67
errmsg_printf(ERRMSG_LVL_ERROR, _("Unable to get thread stack size\n"));
110
68
my_thread_stack_size= 524288; // At the time of the writing of this code, this was OSX's
134
bool MultiThreadScheduler::addSession(Session::shared_ptr &session)
92
bool MultiThreadScheduler::addSession(Session *session)
136
94
if (thread_count >= max_threads)
139
97
thread_count.increment();
142
session->getThread().reset(new boost::thread((boost::bind(&MultiThreadScheduler::runSession, this, session->getSessionId()))));
144
catch (std::exception&)
146
thread_count.decrement();
150
if (not session->getThread())
152
thread_count.decrement();
156
if (not session->getThread()->joinable())
99
boost::thread new_thread(boost::bind(&MultiThreadScheduler::runSession, this, session));
101
if (not new_thread.joinable())
158
103
thread_count.decrement();
166
void MultiThreadScheduler::killSession(Session *session)
168
boost_thread_shared_ptr thread(session->getThread());
176
void MultiThreadScheduler::killSessionNow(Session::shared_ptr &session)
178
killSession(session.get());
180
session->disconnect();
111
void MultiThreadScheduler::killSessionNow(Session *session)
182
113
/* Locks LOCK_thread_count and deletes session */
183
114
Session::unlink(session);
184
115
thread_count.decrement();
187
118
MultiThreadScheduler::~MultiThreadScheduler()
189
boost::mutex::scoped_lock scopedLock(drizzled::session::Cache::singleton().mutex());
120
boost::mutex::scoped_lock scopedLock(LOCK_thread_count);
190
121
while (thread_count)
192
123
COND_thread_count.wait(scopedLock);
196
} // multi_thread namespace
199
128
static int init(drizzled::module::Context &context)
202
context.add(new multi_thread::MultiThreadScheduler("multi_thread"));
131
context.add(new MultiThreadScheduler("multi_thread"));
220
149
"One Thread Per Session Scheduler",
221
150
PLUGIN_LICENSE_GPL,
222
151
init, /* Plugin Init */
152
NULL, /* system variables */
224
153
init_options /* config options */
226
155
DRIZZLE_DECLARE_PLUGIN_END;