~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/main.cc

  • Committer: Brian Aker
  • Date: 2010-06-04 04:33:21 UTC
  • mto: This revision was merged to the branch mainline in revision 1600.
  • Revision ID: brian@gir-2.local-20100604043321-orl86xv459hmu225
No NULL currently used in printing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <signal.h>
24
24
#include <sys/resource.h>
25
25
#include <unistd.h>
26
 
#include <sys/stat.h>
27
 
#include <sys/types.h>
28
 
 
29
26
 
30
27
#if TIME_WITH_SYS_TIME
31
28
# include <sys/time.h>
42
39
# include <locale.h>
43
40
#endif
44
41
 
45
 
#include <boost/filesystem.hpp>
46
42
 
47
43
#include "drizzled/plugin.h"
48
44
#include "drizzled/gettext.h"
49
45
#include "drizzled/configmake.h"
50
46
#include "drizzled/session.h"
51
 
#include "drizzled/session/cache.h"
52
47
#include "drizzled/internal/my_sys.h"
53
48
#include "drizzled/unireg.h"
 
49
#include "drizzled/stacktrace.h"
54
50
#include "drizzled/drizzled.h"
55
51
#include "drizzled/errmsg_print.h"
56
52
#include "drizzled/data_home.h"
60
56
#include "drizzled/tztime.h"
61
57
#include "drizzled/signal_handler.h"
62
58
#include "drizzled/replication_services.h"
63
 
#include "drizzled/transaction_services.h"
64
 
 
65
 
#include "drizzled/util/backtrace.h"
66
59
 
67
60
using namespace drizzled;
68
61
using namespace std;
69
 
namespace fs=boost::filesystem;
70
62
 
71
63
static pthread_t select_thread;
72
64
static uint32_t thr_kill_signal;
73
65
 
74
 
 
75
66
/**
76
67
  All global error messages are sent here where the first one is stored
77
68
  for the client.
140
131
    sigemptyset(&sa.sa_mask);
141
132
    sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
142
133
 
 
134
    init_stacktrace();
143
135
    sa.sa_handler= drizzled_handle_segfault;
144
136
    sigaction(SIGSEGV, &sa, NULL);
145
137
    sigaction(SIGABRT, &sa, NULL);
191
183
    sigdelset(&set, thr_kill_signal);
192
184
  }
193
185
  else
194
 
  {
195
186
    sigaddset(&set,SIGINT);
196
 
  }
197
187
  sigprocmask(SIG_SETMASK,&set,NULL);
198
188
  pthread_sigmask(SIG_SETMASK,&set,NULL);
199
189
  return;
200
190
}
201
191
 
202
 
static void GoogleProtoErrorThrower(google::protobuf::LogLevel level, const char* filename,
203
 
                       int line, const string& message) throw(const char *)
204
 
{
205
 
  (void)filename;
206
 
  (void)line;
207
 
  (void)message;
208
 
  std::cerr << "\n";
209
 
  drizzled::util::custom_backtrace();
210
 
  std::cerr << "\n";
211
 
  switch(level)
212
 
  {
213
 
  case google::protobuf::LOGLEVEL_INFO:
214
 
    break;
215
 
  case google::protobuf::LOGLEVEL_WARNING:
216
 
  case google::protobuf::LOGLEVEL_ERROR:
217
 
  case google::protobuf::LOGLEVEL_FATAL:
218
 
  default:
219
 
    std::cerr << "GoogleProtoErrorThrower(" << filename << ", " << line << ", " << message << ")";
220
 
    throw("error in google protocol buffer parsing");
221
 
  }
222
 
}
223
192
 
224
193
int main(int argc, char **argv)
225
194
{
233
202
 
234
203
  module::Registry &modules= module::Registry::singleton();
235
204
  plugin::Client *client;
 
205
  Session *session;
236
206
 
237
207
  MY_INIT(argv[0]);             // init my_sys library & pthreads
238
208
  /* nothing should come before this line ^^^ */
239
209
 
240
210
  /* Set signal used to kill Drizzle */
 
211
#if defined(SIGUSR2)
 
212
  thr_kill_signal= internal::thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
 
213
#else
241
214
  thr_kill_signal= SIGINT;
242
 
 
243
 
  google::protobuf::SetLogHandler(&GoogleProtoErrorThrower);
244
 
 
245
 
  /* Function generates error messages before abort */
246
 
  error_handler_hook= my_message_sql;
247
 
  /* init_common_variables must get basic settings such as data_home_dir
248
 
     and plugin_load_list. */
249
 
  if (init_common_variables(argc, argv, modules))
 
215
#endif
 
216
 
 
217
  if (init_common_variables(DRIZZLE_CONFIG_NAME,
 
218
                            argc, argv, load_default_groups))
250
219
    unireg_abort(1);                            // Will do exit
251
220
 
252
 
  /*
253
 
    init signals & alarm
254
 
    After this we can't quit by a simple unireg_abort
255
 
  */
256
221
  init_signals();
257
222
 
258
223
 
259
224
  select_thread=pthread_self();
260
225
  select_thread_in_use=1;
261
226
 
262
 
  if (not opt_help)
263
 
  {
264
 
    if (chdir(getDataHome().file_string().c_str()))
265
 
    {
266
 
      errmsg_printf(ERRMSG_LVL_ERROR,
267
 
                    _("Data directory %s does not exist\n"),
268
 
                    getDataHome().file_string().c_str());
269
 
      unireg_abort(1);
270
 
    }
271
 
    if (mkdir("local", 0700))
272
 
    {
273
 
      /* We don't actually care */
274
 
    }
275
 
    if (chdir("local"))
276
 
    {
277
 
      errmsg_printf(ERRMSG_LVL_ERROR,
278
 
                    _("Local catalog %s/local does not exist\n"),
279
 
                    getDataHome().file_string().c_str());
280
 
      unireg_abort(1);
281
 
    }
282
 
 
283
 
    full_data_home= fs::system_complete(getDataHome());
284
 
    getDataHomeCatalog()= "./";
285
 
    getDataHome()= "../";
286
 
  }
287
 
 
288
 
 
 
227
  if (chdir(data_home_real) && !opt_help)
 
228
  {
 
229
    errmsg_printf(ERRMSG_LVL_ERROR, _("Data directory %s does not exist\n"), data_home_real);
 
230
    unireg_abort(1);
 
231
  }
 
232
  data_home= data_home_buff;
 
233
  data_home[0]=FN_CURLIB;               // all paths are relative from here
 
234
  data_home[1]=0;
 
235
  data_home_len= 2;
 
236
 
 
237
  if ((user_info= check_user(drizzled_user)))
 
238
  {
 
239
    set_user(drizzled_user, user_info);
 
240
  }
289
241
 
290
242
  if (server_id == 0)
291
243
  {
312
264
  if (plugin::Listen::setup())
313
265
    unireg_abort(1);
314
266
 
 
267
  /*
 
268
    init signals & alarm
 
269
    After this we can't quit by a simple unireg_abort
 
270
  */
 
271
  error_handler_hook= my_message_sql;
315
272
 
316
273
  assert(plugin::num_trx_monitored_objects > 0);
317
274
  if (drizzle_rm_tmp_tables() ||
321
278
    select_thread_in_use=0;
322
279
    (void) pthread_kill(signal_thread, SIGTERM);
323
280
 
324
 
    (void) unlink(pid_file.file_string().c_str());      // Not needed anymore
 
281
    (void) unlink(pidfile_name);        // Not needed anymore
325
282
 
326
283
    exit(1);
327
284
  }
328
285
 
 
286
  init_status_vars();
 
287
 
329
288
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
330
289
                PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
331
290
 
332
291
 
333
 
  TransactionServices &transaction_services= TransactionServices::singleton();
334
 
 
335
 
  /* Send server startup event */
336
 
  {
337
 
    Session *session;
338
 
 
339
 
    if ((session= new Session(plugin::Listen::getNullClient())))
340
 
    {
341
 
      currentSession().release();
342
 
      currentSession().reset(session);
343
 
      transaction_services.sendStartupEvent(session);
344
 
      delete session;
345
 
    }
346
 
  }
347
 
 
348
 
 
349
292
  /* Listen for new connections and start new session for each connection
350
293
     accepted. The listen.getClient() method will return NULL when the server
351
294
     should be shutdown. */
352
295
  while ((client= plugin::Listen::getClient()) != NULL)
353
296
  {
354
 
    Session::shared_ptr session(new Session(client));
355
 
 
356
 
    if (not session)
 
297
    if (!(session= new Session(client)))
357
298
    {
358
299
      delete client;
359
300
      continue;
360
301
    }
361
302
 
362
303
    /* If we error on creation we drop the connection and delete the session. */
363
 
    if (Session::schedule(session))
 
304
    if (session->schedule())
364
305
      Session::unlink(session);
365
306
  }
366
307
 
367
 
  /* Send server shutdown event */
368
 
  {
369
 
    Session *session;
370
 
 
371
 
    if ((session= new Session(plugin::Listen::getNullClient())))
372
 
    {
373
 
      currentSession().release();
374
 
      currentSession().reset(session);
375
 
      transaction_services.sendShutdownEvent(session);
376
 
      delete session;
377
 
    }
378
 
  }
379
 
 
380
 
  {
381
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
382
 
    select_thread_in_use= false;                        // For close_connections
383
 
  }
384
 
  COND_thread_count.notify_all();
 
308
  /* (void) pthread_attr_destroy(&connection_attrib); */
 
309
 
 
310
 
 
311
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
312
  select_thread_in_use=0;                       // For close_connections
 
313
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
314
  (void) pthread_cond_broadcast(&COND_thread_count);
385
315
 
386
316
  /* Wait until cleanup is done */
387
 
  {
388
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
389
 
    while (not ready_to_exit)
390
 
      COND_server_end.wait(scopedLock);
391
 
  }
 
317
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
318
  while (!ready_to_exit)
 
319
    pthread_cond_wait(&COND_server_end,&LOCK_thread_count);
 
320
  (void) pthread_mutex_unlock(&LOCK_thread_count);
392
321
 
393
322
  clean_up(1);
394
323
  module::Registry::shutdown();
 
324
  clean_up_mutexes();
395
325
  internal::my_end();
396
 
 
397
326
  return 0;
398
327
}
399
328