~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/main.cc

  • Committer: Brian Aker
  • Date: 2011-02-22 06:12:02 UTC
  • mfrom: (2190.1.6 drizzle-build)
  • Revision ID: brian@tangent.org-20110222061202-k03czxykqy4x9hjs
List update, header fixes, multiple symbols, and David deletes some code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include "config.h"
 
20
#include <config.h>
21
21
 
22
22
#include <pthread.h>
23
23
#include <signal.h>
44
44
 
45
45
#include <boost/filesystem.hpp>
46
46
 
47
 
#include "drizzled/plugin.h"
48
 
#include "drizzled/gettext.h"
49
 
#include "drizzled/configmake.h"
50
 
#include "drizzled/session.h"
51
 
#include "drizzled/internal/my_sys.h"
52
 
#include "drizzled/unireg.h"
53
 
#include "drizzled/drizzled.h"
54
 
#include "drizzled/errmsg_print.h"
55
 
#include "drizzled/data_home.h"
56
 
#include "drizzled/plugin/listen.h"
57
 
#include "drizzled/plugin/client.h"
58
 
#include "drizzled/pthread_globals.h"
59
 
#include "drizzled/tztime.h"
60
 
#include "drizzled/signal_handler.h"
61
 
#include "drizzled/replication_services.h"
62
 
#include "drizzled/transaction_services.h"
 
47
#include <drizzled/abort_exception.h>
 
48
#include <drizzled/catalog/local.h>
 
49
#include <drizzled/configmake.h>
 
50
#include <drizzled/data_home.h>
 
51
#include <drizzled/debug.h>
 
52
#include <drizzled/drizzled.h>
 
53
#include <drizzled/errmsg_print.h>
 
54
#include <drizzled/gettext.h>
 
55
#include <drizzled/internal/my_sys.h>
 
56
#include <drizzled/plugin.h>
 
57
#include <drizzled/plugin/client.h>
 
58
#include <drizzled/plugin/listen.h>
 
59
#include <drizzled/plugin/monitored_in_transaction.h>
 
60
#include <drizzled/pthread_globals.h>
 
61
#include <drizzled/replication_services.h>
 
62
#include <drizzled/session.h>
 
63
#include <drizzled/session/cache.h>
 
64
#include <drizzled/signal_handler.h>
 
65
#include <drizzled/transaction_services.h>
 
66
#include <drizzled/tztime.h>
 
67
#include <drizzled/unireg.h>
 
68
#include <drizzled/util/backtrace.h>
 
69
#include <drizzled/current_session.h>
 
70
#include <drizzled/daemon.h>
63
71
 
64
72
using namespace drizzled;
65
73
using namespace std;
66
 
namespace fs=boost::filesystem;
67
74
 
68
75
static pthread_t select_thread;
69
76
static uint32_t thr_kill_signal;
70
77
 
 
78
extern bool opt_daemon;
 
79
 
71
80
 
72
81
/**
73
82
  All global error messages are sent here where the first one is stored
74
83
  for the client.
75
84
*/
76
 
static void my_message_sql(uint32_t error, const char *str, myf MyFlags)
 
85
static void my_message_sql(drizzled::error_t error, const char *str, myf MyFlags)
77
86
{
78
87
  Session *session;
79
88
  /*
86
95
      session->is_fatal_error= 1;
87
96
 
88
97
    /*
89
 
      TODO: There are two exceptions mechanism (Session and sp_rcontext),
 
98
      @TODO There are two exceptions mechanism (Session and sp_rcontext),
90
99
      this could be improved by having a common stack of handlers.
91
100
    */
92
 
    if (session->handle_error(error, str,
93
 
                          DRIZZLE_ERROR::WARN_LEVEL_ERROR))
94
 
      return;;
 
101
    if (session->handle_error(error, str, DRIZZLE_ERROR::WARN_LEVEL_ERROR))
 
102
      return;
95
103
 
96
104
    /*
97
 
      session->lex->current_select == 0 if lex structure is not inited
 
105
      session->getLex()->current_select == 0 if lex structure is not inited
98
106
      (not query command (COM_QUERY))
99
107
    */
100
 
    if (! (session->lex->current_select &&
101
 
        session->lex->current_select->no_error && !session->is_fatal_error))
 
108
    if (! (session->getLex()->current_select &&
 
109
           session->getLex()->current_select->no_error && !session->is_fatal_error))
102
110
    {
103
111
      if (! session->main_da.is_error())            // Return only first message
104
112
      {
105
 
        if (error == 0)
 
113
        if (error == EE_OK)
106
114
          error= ER_UNKNOWN_ERROR;
 
115
 
107
116
        if (str == NULL)
108
117
          str= ER(error);
 
118
 
109
119
        session->main_da.set_error_status(error, str);
110
120
      }
111
121
    }
119
129
      session->no_warnings_for_error= true;
120
130
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
121
131
      session->no_warnings_for_error= false;
122
 
      }
123
132
    }
124
 
    if (!session || MyFlags & ME_NOREFRESH)
125
 
        errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
 
133
  }
 
134
 
 
135
  if (not session || MyFlags & ME_NOREFRESH)
 
136
  {
 
137
    errmsg_printf(error::ERROR, "%s: %s",internal::my_progname,str);
 
138
  }
126
139
}
127
140
 
128
141
static void init_signals(void)
130
143
  sigset_t set;
131
144
  struct sigaction sa;
132
145
 
133
 
  if (!(test_flags.test(TEST_NO_STACKTRACE) || 
134
 
        test_flags.test(TEST_CORE_ON_SIGNAL)))
 
146
  if (not (getDebug().test(debug::NO_STACKTRACE) || 
 
147
        getDebug().test(debug::CORE_ON_SIGNAL)))
135
148
  {
136
149
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
137
150
    sigemptyset(&sa.sa_mask);
147
160
    sigaction(SIGFPE, &sa, NULL);
148
161
  }
149
162
 
150
 
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
 
163
  if (getDebug().test(debug::CORE_ON_SIGNAL))
151
164
  {
152
165
    /* Change limits so that we will get a core file */
153
166
    struct rlimit rl;
154
167
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
155
168
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
156
 
        errmsg_printf(ERRMSG_LVL_WARN,
 
169
        errmsg_printf(error::WARN,
157
170
                      _("setrlimit could not change the size of core files "
158
171
                        "to 'infinity';  We may not be able to generate a "
159
172
                        "core file on signals"));
178
191
#ifdef SIGTSTP
179
192
  sigaddset(&set,SIGTSTP);
180
193
#endif
181
 
  if (test_flags.test(TEST_SIGINT))
 
194
  if (getDebug().test(debug::ALLOW_SIGINT))
182
195
  {
183
196
    sa.sa_flags= 0;
184
197
    sa.sa_handler= drizzled_end_thread_signal;
196
209
  return;
197
210
}
198
211
 
199
 
static void GoogleProtoErrorThrower(google::protobuf::LogLevel level, const char* filename,
200
 
                       int line, const string& message) throw(const char *)
 
212
static void GoogleProtoErrorThrower(google::protobuf::LogLevel level,
 
213
                                    const char* ,
 
214
                                    int, const string& ) throw(const char *)
201
215
{
202
 
  (void)filename;
203
 
  (void)line;
204
 
  (void)message;
205
216
  switch(level)
206
217
  {
207
218
  case google::protobuf::LOGLEVEL_INFO:
210
221
  case google::protobuf::LOGLEVEL_ERROR:
211
222
  case google::protobuf::LOGLEVEL_FATAL:
212
223
  default:
213
 
    std::cerr << "GoogleProtoErrorThrower(" << filename << ", " << line << ", " << message << ")";
214
224
    throw("error in google protocol buffer parsing");
215
225
  }
216
226
}
221
231
# if defined(HAVE_LOCALE_H)
222
232
  setlocale(LC_ALL, "");
223
233
# endif
224
 
  bindtextdomain("drizzle", LOCALEDIR);
225
 
  textdomain("drizzle");
 
234
  bindtextdomain("drizzle7", LOCALEDIR);
 
235
  textdomain("drizzle7");
226
236
#endif
227
237
 
228
238
  module::Registry &modules= module::Registry::singleton();
229
 
  plugin::Client *client;
230
 
  Session *session;
231
239
 
232
240
  MY_INIT(argv[0]);             // init my_sys library & pthreads
233
241
  /* nothing should come before this line ^^^ */
239
247
 
240
248
  /* Function generates error messages before abort */
241
249
  error_handler_hook= my_message_sql;
 
250
 
242
251
  /* init_common_variables must get basic settings such as data_home_dir
243
252
     and plugin_load_list. */
244
 
  if (init_common_variables(argc, argv, modules))
 
253
  if (init_basic_variables(argc, argv))
 
254
    unireg_abort(1);                            // Will do exit
 
255
 
 
256
  if (opt_daemon)
 
257
  {
 
258
    if (signal(SIGHUP, SIG_IGN) == SIG_ERR)
 
259
    {
 
260
      perror("Failed to ignore SIGHUP");
 
261
    }
 
262
    if (daemonize())
 
263
    {
 
264
      fprintf(stderr, "failed to daemon() in order to daemonize\n");
 
265
      exit(EXIT_FAILURE);
 
266
    }
 
267
  }
 
268
 
 
269
  if (init_remaining_variables(modules))
245
270
    unireg_abort(1);                            // Will do exit
246
271
 
247
272
  /*
258
283
  {
259
284
    if (chdir(getDataHome().file_string().c_str()))
260
285
    {
261
 
      errmsg_printf(ERRMSG_LVL_ERROR,
 
286
      errmsg_printf(error::ERROR,
262
287
                    _("Data directory %s does not exist\n"),
263
288
                    getDataHome().file_string().c_str());
264
289
      unireg_abort(1);
269
294
    }
270
295
    if (chdir("local"))
271
296
    {
272
 
      errmsg_printf(ERRMSG_LVL_ERROR,
 
297
      errmsg_printf(error::ERROR,
273
298
                    _("Local catalog %s/local does not exist\n"),
274
299
                    getDataHome().file_string().c_str());
275
300
      unireg_abort(1);
276
301
    }
277
302
 
278
 
    full_data_home= fs::system_complete(getDataHome());
279
 
    getDataHomeCatalog()= "./";
280
 
    getDataHome()= "../";
 
303
    boost::filesystem::path &full_data_home= getFullDataHome();
 
304
    full_data_home= boost::filesystem::system_complete(getDataHome());
 
305
    errmsg_printf(error::INFO, "Data Home directory is : %s", full_data_home.native_file_string().c_str());
281
306
  }
282
307
 
283
308
 
287
312
    server_id= 1;
288
313
  }
289
314
 
290
 
  if (init_server_components(modules))
 
315
  try
 
316
  {
 
317
    if (init_server_components(modules))
 
318
      DRIZZLE_ABORT;
 
319
  }
 
320
  catch (abort_exception& ex)
 
321
  {
 
322
#if defined(DEBUG)
 
323
    cout << _("Drizzle has receieved an abort event.") << endl;
 
324
    cout << _("In Function: ") << *::boost::get_error_info<boost::throw_function>(ex) << endl;
 
325
    cout << _("In File: ") << *::boost::get_error_info<boost::throw_file>(ex) << endl;
 
326
    cout << _("On Line: ") << *::boost::get_error_info<boost::throw_line>(ex) << endl;
 
327
#endif
291
328
    unireg_abort(1);
 
329
  }
 
330
 
292
331
 
293
332
  /**
294
333
   * This check must be done after init_server_components for now
307
346
  if (plugin::Listen::setup())
308
347
    unireg_abort(1);
309
348
 
310
 
 
311
349
  assert(plugin::num_trx_monitored_objects > 0);
312
 
  if (drizzle_rm_tmp_tables() ||
313
 
      my_tz_init((Session *)0, default_tz_name))
 
350
  if (drizzle_rm_tmp_tables())
314
351
  {
315
352
    abort_loop= true;
316
353
    select_thread_in_use=0;
318
355
 
319
356
    (void) unlink(pid_file.file_string().c_str());      // Not needed anymore
320
357
 
321
 
    exit(1);
 
358
    unireg_abort(1);
322
359
  }
323
360
 
324
 
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
 
361
  errmsg_printf(error::INFO, _(ER(ER_STARTUP)), internal::my_progname,
325
362
                PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
326
363
 
327
364
 
328
365
  TransactionServices &transaction_services= TransactionServices::singleton();
329
366
 
330
367
  /* Send server startup event */
331
 
  if ((session= new Session(plugin::Listen::getNullClient())))
332
368
  {
333
 
    transaction_services.sendStartupEvent(session);
334
 
    session->lockForDelete();
335
 
    delete session;
 
369
    Session::shared_ptr session;
 
370
 
 
371
    if ((session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local())))
 
372
    {
 
373
      currentSession().release();
 
374
      currentSession().reset(session.get());
 
375
 
 
376
 
 
377
      transaction_services.sendStartupEvent(*session);
 
378
 
 
379
      plugin_startup_window(modules, *(session.get()));
 
380
    }
336
381
  }
337
382
 
 
383
  if (opt_daemon)
 
384
    daemon_is_ready();
338
385
 
339
 
  /* Listen for new connections and start new session for each connection
 
386
  /* 
 
387
    Listen for new connections and start new session for each connection
340
388
     accepted. The listen.getClient() method will return NULL when the server
341
 
     should be shutdown. */
 
389
     should be shutdown.
 
390
   */
 
391
  plugin::Client *client;
342
392
  while ((client= plugin::Listen::getClient()) != NULL)
343
393
  {
344
 
    if (!(session= new Session(client)))
 
394
    Session::shared_ptr session;
 
395
    session= Session::make_shared(client, client->catalog());
 
396
 
 
397
    if (not session)
345
398
    {
346
399
      delete client;
347
400
      continue;
348
401
    }
349
402
 
350
403
    /* If we error on creation we drop the connection and delete the session. */
351
 
    if (session->schedule())
 
404
    if (Session::schedule(session))
352
405
      Session::unlink(session);
353
406
  }
354
407
 
355
408
  /* Send server shutdown event */
356
 
  if ((session= new Session(plugin::Listen::getNullClient())))
357
 
  {
358
 
    transaction_services.sendShutdownEvent(session);
359
 
    session->lockForDelete();
360
 
    delete session;
361
 
  }
362
 
 
363
 
  LOCK_thread_count.lock();
364
 
  select_thread_in_use=0;                       // For close_connections
365
 
  LOCK_thread_count.unlock();
 
409
  {
 
410
    Session::shared_ptr session;
 
411
 
 
412
    if ((session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local())))
 
413
    {
 
414
      currentSession().release();
 
415
      currentSession().reset(session.get());
 
416
      transaction_services.sendShutdownEvent(*session.get());
 
417
    }
 
418
  }
 
419
 
 
420
  {
 
421
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
 
422
    select_thread_in_use= false;                        // For close_connections
 
423
  }
366
424
  COND_thread_count.notify_all();
367
425
 
368
426
  /* Wait until cleanup is done */
369
 
  {
370
 
    boost::mutex::scoped_lock scopedLock(LOCK_thread_count);
371
 
    while (!ready_to_exit)
372
 
      COND_server_end.wait(scopedLock);
373
 
  }
 
427
  session::Cache::singleton().shutdownSecond();
374
428
 
375
429
  clean_up(1);
376
430
  module::Registry::shutdown();