~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/multi_thread/multi_thread.cc

  • Committer: Brian Aker
  • Date: 2010-04-05 23:46:43 UTC
  • Revision ID: brian@gaz-20100405234643-0he3xnj902rc70r8
Fixing tests to work with PBXT.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 */
15
15
 
16
 
#include <drizzled/server_includes.h>
17
 
#include <drizzled/atomics.h>
18
 
#include <drizzled/gettext.h>
19
 
#include <drizzled/error.h>
20
 
#include <drizzled/plugin/scheduler.h>
21
 
#include <drizzled/connect.h>
22
 
#include <drizzled/sql_parse.h>
23
 
#include <drizzled/session.h>
24
 
#include <drizzled/connect.h>
25
 
#include <string>
 
16
#include "config.h"
 
17
#include <plugin/multi_thread/multi_thread.h>
 
18
#include "drizzled/pthread_globals.h"
26
19
 
27
20
using namespace std;
 
21
using namespace drizzled;
28
22
 
 
23
/* Configuration variables. */
29
24
static uint32_t max_threads;
30
25
 
31
 
class Multi_thread_scheduler: public Scheduler
32
 
{
33
 
  drizzled::atomic<uint32_t> thread_count;
34
 
  pthread_attr_t multi_thread_attrib;
35
 
 
36
 
public:
37
 
  Multi_thread_scheduler(uint32_t threads): Scheduler(threads)
38
 
  {
39
 
    thread_count= 0;
40
 
    /* Parameter for threads created for connections */
41
 
    (void) pthread_attr_init(&multi_thread_attrib);
42
 
    (void) pthread_attr_setdetachstate(&multi_thread_attrib,
43
 
                                       PTHREAD_CREATE_DETACHED);
44
 
    pthread_attr_setscope(&multi_thread_attrib, PTHREAD_SCOPE_SYSTEM);
45
 
    {
46
 
      struct sched_param tmp_sched_param;
47
 
  
48
 
      memset(&tmp_sched_param, 0, sizeof(tmp_sched_param));
49
 
      tmp_sched_param.sched_priority= WAIT_PRIOR;
50
 
      (void)pthread_attr_setschedparam(&multi_thread_attrib, &tmp_sched_param);
51
 
    }
52
 
  }
53
 
 
54
 
  ~Multi_thread_scheduler()
55
 
  {
56
 
    (void) pthread_mutex_lock(&LOCK_thread_count);
57
 
    while (thread_count)
58
 
    {
59
 
      pthread_cond_wait(&COND_thread_count, &LOCK_thread_count);
60
 
    }
61
 
    (void) pthread_mutex_unlock(&LOCK_thread_count);
62
 
    
63
 
    pthread_attr_destroy(&multi_thread_attrib);
64
 
  }
65
 
 
66
 
  virtual bool add_connection(Session *session)
67
 
  {
68
 
    int error;
69
 
  
70
 
    thread_count++;
71
 
  
72
 
    if ((error= pthread_create(&session->real_id, &multi_thread_attrib, handle_one_connection, static_cast<void*>(session))))
73
 
      return true;
74
 
  
75
 
    return false;
76
 
  }
77
 
  
78
 
  
79
 
  /*
80
 
    End connection, in case when we are using 'no-threads'
81
 
  */
82
 
  
83
 
  virtual bool end_thread(Session *session, bool)
84
 
  {
85
 
    unlink_session(session);   /* locks LOCK_thread_count and deletes session */
86
 
    thread_count--;
87
 
  
88
 
    my_thread_end();
89
 
    pthread_exit(0);
90
 
  
91
 
    return true; // We should never reach this point
92
 
  }
93
 
  
94
 
  virtual uint32_t count(void)
95
 
  {
96
 
    return thread_count;
97
 
  }
98
 
};
99
 
 
100
 
class MultiThreadFactory : public SchedulerFactory
101
 
{
102
 
public:
103
 
  MultiThreadFactory() : SchedulerFactory("multi_thread") {}
104
 
  ~MultiThreadFactory() { if (scheduler != NULL) delete scheduler; }
105
 
  Scheduler *operator() ()
106
 
  {
107
 
    if (scheduler == NULL)
108
 
      scheduler= new Multi_thread_scheduler(max_threads);
109
 
    return scheduler;
110
 
  }
111
 
};
112
 
static MultiThreadFactory *factory= NULL;
113
 
 
114
 
static int init(PluginRegistry &registry)
115
 
{
116
 
  factory= new MultiThreadFactory();
117
 
  registry.add(factory);
118
 
  return 0;
119
 
}
120
 
 
121
 
static int deinit(PluginRegistry &registry)
122
 
{
123
 
  if (factory)
124
 
  {
125
 
    registry.remove(factory);
126
 
    delete factory;
127
 
  }
 
26
/* Global's (TBR) */
 
27
static MultiThreadScheduler *scheduler= NULL;
 
28
 
 
29
/**
 
30
 * Function to be run as a thread for each session.
 
31
 */
 
32
namespace
 
33
{
 
34
  extern "C" pthread_handler_t session_thread(void *arg);
 
35
}
 
36
 
 
37
namespace
 
38
{
 
39
  extern "C" pthread_handler_t session_thread(void *arg)
 
40
  {
 
41
    Session *session= static_cast<Session*>(arg);
 
42
    MultiThreadScheduler *sched= static_cast<MultiThreadScheduler*>(session->scheduler);
 
43
    sched->runSession(session);
 
44
    return NULL;
 
45
  }
 
46
}
 
47
 
 
48
 
 
49
bool MultiThreadScheduler::addSession(Session *session)
 
50
{
 
51
  if (thread_count >= max_threads)
 
52
    return true;
 
53
 
 
54
  thread_count.increment();
 
55
 
 
56
  if (pthread_create(&session->real_id, &attr, session_thread,
 
57
                     static_cast<void*>(session)))
 
58
  {
 
59
    thread_count.decrement();
 
60
    return true;
 
61
  }
 
62
 
 
63
  return false;
 
64
}
 
65
 
 
66
 
 
67
void MultiThreadScheduler::killSessionNow(Session *session)
 
68
{
 
69
  /* Locks LOCK_thread_count and deletes session */
 
70
  Session::unlink(session);
 
71
  thread_count.decrement();
 
72
  internal::my_thread_end();
 
73
  pthread_exit(0);
 
74
  /* We should never reach this point. */
 
75
}
 
76
 
 
77
MultiThreadScheduler::~MultiThreadScheduler()
 
78
{
 
79
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
80
  while (thread_count)
 
81
  {
 
82
    pthread_cond_wait(&COND_thread_count, &LOCK_thread_count);
 
83
  }
 
84
 
 
85
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
86
  (void) pthread_attr_destroy(&attr);
 
87
}
 
88
 
 
89
  
 
90
static int init(drizzled::plugin::Context &context)
 
91
{
 
92
  scheduler= new MultiThreadScheduler("multi_thread");
 
93
  context.add(scheduler);
 
94
 
128
95
  return 0;
129
96
}
130
97
 
131
98
static DRIZZLE_SYSVAR_UINT(max_threads, max_threads,
132
99
                           PLUGIN_VAR_RQCMDARG,
133
100
                           N_("Maximum number of user threads available."),
134
 
                           NULL, NULL, 2048, 1, 4048, 0);
 
101
                           NULL, NULL, 2048, 1, 4096, 0);
135
102
 
136
 
static struct st_mysql_sys_var* system_variables[]= {
 
103
static drizzle_sys_var* sys_variables[]= {
137
104
  DRIZZLE_SYSVAR(max_threads),
138
105
  NULL
139
106
};
140
107
 
141
 
drizzle_declare_plugin(multi_thread)
 
108
DRIZZLE_DECLARE_PLUGIN
142
109
{
 
110
  DRIZZLE_VERSION_ID,
143
111
  "multi_thread",
144
112
  "0.1",
145
113
  "Brian Aker",
146
114
  "One Thread Per Session Scheduler",
147
115
  PLUGIN_LICENSE_GPL,
148
116
  init, /* Plugin Init */
149
 
  deinit, /* Plugin Deinit */
150
 
  NULL,   /* status variables */
151
 
  system_variables,   /* system variables */
 
117
  sys_variables,   /* system variables */
152
118
  NULL    /* config options */
153
119
}
154
 
drizzle_declare_plugin_end;
 
120
DRIZZLE_DECLARE_PLUGIN_END;