~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/multi_thread/multi_thread.cc

  • Committer: Brian Aker
  • Date: 2009-10-02 19:38:12 UTC
  • mfrom: (1152.1.7 merge)
  • Revision ID: brian@gaz-20091002193812-mpd61oecep74t6gd
Merge Monty + Brian for plugins.

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/sql_parse.h>
22
 
#include <drizzled/session.h>
23
 
#include <string>
 
16
#include <plugin/multi_thread/multi_thread.h>
24
17
 
25
18
using namespace std;
26
19
using namespace drizzled;
28
21
/* Configuration variables. */
29
22
static uint32_t max_threads;
30
23
 
 
24
/* Global's (TBR) */
 
25
static MultiThreadScheduler *scheduler= NULL;
 
26
 
31
27
/**
32
28
 * Function to be run as a thread for each session.
33
29
 */
36
32
  extern "C" pthread_handler_t session_thread(void *arg);
37
33
}
38
34
 
39
 
class MultiThreadScheduler: public plugin::Scheduler
40
 
{
41
 
private:
42
 
  drizzled::atomic<uint32_t> thread_count;
43
 
  pthread_attr_t attr;
44
 
 
45
 
public:
46
 
  MultiThreadScheduler(): Scheduler()
47
 
  {
48
 
    struct sched_param tmp_sched_param;
49
 
 
50
 
    memset(&tmp_sched_param, 0, sizeof(struct sched_param));
51
 
 
52
 
    /* Setup attribute parameter for session threads. */
53
 
    (void) pthread_attr_init(&attr);
54
 
    (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
55
 
    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
56
 
 
57
 
    tmp_sched_param.sched_priority= WAIT_PRIOR;
58
 
    (void) pthread_attr_setschedparam(&attr, &tmp_sched_param);
59
 
 
60
 
    thread_count= 0;
61
 
  }
62
 
 
63
 
  ~MultiThreadScheduler()
64
 
  {
65
 
    (void) pthread_mutex_lock(&LOCK_thread_count);
66
 
    while (thread_count)
67
 
    {
68
 
      pthread_cond_wait(&COND_thread_count, &LOCK_thread_count);
69
 
    }
70
 
 
71
 
    (void) pthread_mutex_unlock(&LOCK_thread_count);
72
 
    (void) pthread_attr_destroy(&attr);
73
 
  }
74
 
 
75
 
  virtual bool addSession(Session *session)
76
 
  {
77
 
    if (thread_count >= max_threads)
78
 
      return true;
79
 
 
80
 
    thread_count++;
81
 
  
82
 
    if (pthread_create(&session->real_id, &attr, session_thread,
83
 
                       static_cast<void*>(session)))
84
 
    {
85
 
      thread_count--;
86
 
      return true;
87
 
    }
88
 
  
89
 
    return false;
90
 
  }
91
 
  
92
 
  void runSession(Session *session)
93
 
  {
94
 
    if (my_thread_init())
95
 
    {
96
 
      session->disconnect(ER_OUT_OF_RESOURCES, true);
97
 
      statistic_increment(aborted_connects, &LOCK_status);
98
 
      killSessionNow(session);
99
 
    }
100
 
 
101
 
    session->thread_stack= (char*) &session;
102
 
    session->run();
103
 
    killSessionNow(session);
104
 
  }
105
 
 
106
 
  void killSessionNow(Session *session)
107
 
  {
108
 
    /* Locks LOCK_thread_count and deletes session */
109
 
    unlink_session(session);
110
 
    thread_count--;
111
 
    my_thread_end();
112
 
    pthread_exit(0);
113
 
    /* We should never reach this point. */
114
 
  }
115
 
};
116
 
 
117
35
namespace
118
36
{
119
37
  extern "C" pthread_handler_t session_thread(void *arg)
120
38
  {
121
39
    Session *session= static_cast<Session*>(arg);
122
 
    MultiThreadScheduler *scheduler= static_cast<MultiThreadScheduler*>(session->scheduler);
123
 
    scheduler->runSession(session);
 
40
    MultiThreadScheduler *sched= static_cast<MultiThreadScheduler*>(session->scheduler);
 
41
    sched->runSession(session);
124
42
    return NULL;
125
43
  }
126
44
}
127
45
 
128
 
class MultiThreadFactory : public plugin::SchedulerFactory
129
 
{
130
 
public:
131
 
  MultiThreadFactory() : SchedulerFactory("multi_thread")
132
 
  {
133
 
    addAlias("multi-thread");
134
 
  }
135
 
 
136
 
  ~MultiThreadFactory()
137
 
  {
138
 
    if (scheduler != NULL)
139
 
      delete scheduler;
140
 
  }
141
 
 
142
 
  plugin::Scheduler *operator() ()
143
 
  {
144
 
    if (scheduler == NULL)
145
 
      scheduler= new MultiThreadScheduler();
146
 
    return scheduler;
147
 
  }
148
 
};
149
 
 
150
 
static MultiThreadFactory *factory= NULL;
151
 
 
 
46
 
 
47
bool MultiThreadScheduler::addSession(Session *session)
 
48
{
 
49
  if (thread_count >= max_threads)
 
50
    return true;
 
51
 
 
52
  thread_count++;
 
53
 
 
54
  if (pthread_create(&session->real_id, &attr, session_thread,
 
55
                     static_cast<void*>(session)))
 
56
  {
 
57
    thread_count--;
 
58
    return true;
 
59
  }
 
60
 
 
61
  return false;
 
62
}
 
63
 
 
64
 
 
65
void MultiThreadScheduler::killSessionNow(Session *session)
 
66
{
 
67
  /* Locks LOCK_thread_count and deletes session */
 
68
  unlink_session(session);
 
69
  thread_count--;
 
70
  my_thread_end();
 
71
  pthread_exit(0);
 
72
  /* We should never reach this point. */
 
73
}
 
74
 
 
75
MultiThreadScheduler::~MultiThreadScheduler()
 
76
{
 
77
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
78
  while (thread_count)
 
79
  {
 
80
    pthread_cond_wait(&COND_thread_count, &LOCK_thread_count);
 
81
  }
 
82
 
 
83
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
84
  (void) pthread_attr_destroy(&attr);
 
85
}
 
86
 
 
87
  
152
88
static int init(drizzled::plugin::Registry &registry)
153
89
{
154
 
  factory= new MultiThreadFactory();
155
 
  registry.add(factory);
 
90
  scheduler= new MultiThreadScheduler("multi_thread");
 
91
  registry.add(scheduler);
 
92
 
156
93
  return 0;
157
94
}
158
95
 
159
96
static int deinit(drizzled::plugin::Registry &registry)
160
97
{
161
 
  if (factory)
162
 
  {
163
 
    registry.remove(factory);
164
 
    delete factory;
165
 
  }
 
98
  registry.remove(scheduler);
 
99
  delete scheduler;
 
100
 
166
101
  return 0;
167
102
}
168
103