~drizzle-developers/ubuntu/karmic/drizzle/ppa

« back to all changes in this revision

Viewing changes to plugin/multi_thread/multi_thread.cc

  • Committer: Monty Taylor
  • Date: 2010-11-24 18:44:57 UTC
  • mfrom: (1308.1.31 trunk)
  • Revision ID: mordred@inaugust.com-20101124184457-qd6jvoe2wgnvl3yq
Tags: 2010.11.04-0ubuntu1~karmic1
* New upstream release.
* Turn off -Werror for packaging builds. (Closes: #602662)

Show diffs side-by-side

added added

removed removed

Lines of Context:
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"
22
24
 
23
25
#include <boost/thread.hpp>
24
26
#include <boost/bind.hpp>
28
30
using namespace drizzled;
29
31
 
30
32
/* Configuration variables. */
31
 
static uint32_t max_threads;
32
 
 
33
 
/* Global's (TBR) */
34
 
static MultiThreadScheduler *scheduler= NULL;
 
33
typedef constrained_check<uint32_t, 4096, 1> max_threads_constraint;
 
34
static max_threads_constraint max_threads;
35
35
 
36
36
namespace drizzled
37
37
{
38
38
  extern size_t my_thread_stack_size;
39
39
}
40
40
 
41
 
void MultiThreadScheduler::runSession(drizzled::Session *session)
 
41
namespace multi_thread {
 
42
 
 
43
void MultiThreadScheduler::runSession(drizzled::session_id_t id)
42
44
{
 
45
  char stack_dummy;
 
46
  boost::this_thread::disable_interruption disable_by_default;
 
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
  }
 
54
  session->pushInterrupt(&disable_by_default);
 
55
 
43
56
  if (drizzled::internal::my_thread_init())
44
57
  {
45
58
    session->disconnect(drizzled::ER_OUT_OF_RESOURCES, true);
48
61
  }
49
62
  boost::this_thread::at_thread_exit(&internal::my_thread_end);
50
63
 
51
 
  session->thread_stack= (char*) &session;
 
64
  session->thread_stack= (char*) &stack_dummy;
52
65
  session->run();
53
66
  killSessionNow(session);
 
67
  // @todo remove hard spin by disconnection the session first from the
 
68
  // thread.
 
69
  while (not session.unique()) {}
54
70
}
55
71
 
56
72
void MultiThreadScheduler::setStackSize()
91
107
#endif
92
108
}
93
109
 
94
 
bool MultiThreadScheduler::addSession(Session *session)
 
110
bool MultiThreadScheduler::addSession(Session::shared_ptr &session)
95
111
{
96
112
  if (thread_count >= max_threads)
97
113
    return true;
98
114
 
99
115
  thread_count.increment();
100
116
 
101
 
  boost::thread new_thread(boost::bind(&MultiThreadScheduler::runSession, this, session));
102
 
 
103
 
  if (not new_thread.joinable())
 
117
  session->getThread().reset(new boost::thread((boost::bind(&MultiThreadScheduler::runSession, this, session->getSessionId()))));
 
118
 
 
119
  if (not session->getThread())
 
120
  {
 
121
    thread_count.decrement();
 
122
    return true;
 
123
  }
 
124
 
 
125
  if (not session->getThread()->joinable())
104
126
  {
105
127
    thread_count.decrement();
106
128
    return true;
110
132
}
111
133
 
112
134
 
113
 
void MultiThreadScheduler::killSessionNow(Session *session)
 
135
void MultiThreadScheduler::killSessionNow(Session::shared_ptr &session)
114
136
{
115
137
  /* Locks LOCK_thread_count and deletes session */
116
138
  Session::unlink(session);
119
141
 
120
142
MultiThreadScheduler::~MultiThreadScheduler()
121
143
{
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)
124
146
  {
125
147
    COND_thread_count.wait(scopedLock);
126
148
  }
127
149
}
128
150
 
 
151
} // multi_thread namespace
 
152
 
129
153
  
130
154
static int init(drizzled::module::Context &context)
131
155
{
132
156
  
133
 
  const module::option_map &vm= context.getOptions();
134
 
  if (vm.count("max-threads"))
135
 
  {
136
 
    if (max_threads > 4096 || max_threads < 1)
137
 
    {
138
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for max-threads\n"));
139
 
      return 1;
140
 
    }
141
 
  }
142
 
 
143
 
  scheduler= new MultiThreadScheduler("multi_thread");
144
 
  context.add(scheduler);
 
157
  context.add(new multi_thread::MultiThreadScheduler("multi_thread"));
145
158
 
146
159
  return 0;
147
160
}
148
161
 
149
 
static DRIZZLE_SYSVAR_UINT(max_threads, max_threads,
150
 
                           PLUGIN_VAR_RQCMDARG,
151
 
                           N_("Maximum number of user threads available."),
152
 
                           NULL, NULL, 2048, 1, 4096, 0);
153
 
 
154
162
static void init_options(drizzled::module::option_context &context)
155
163
{
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."));
159
167
}
160
168
 
161
 
static drizzle_sys_var* sys_variables[]= {
162
 
  DRIZZLE_SYSVAR(max_threads),
163
 
  NULL
164
 
};
165
 
 
166
169
DRIZZLE_DECLARE_PLUGIN
167
170
{
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 */
177
180
}
178
181
DRIZZLE_DECLARE_PLUGIN_END;