~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/main.cc

  • Committer: Brian Aker
  • Date: 2011-03-24 23:14:46 UTC
  • mfrom: (2246.4.12 foreach)
  • Revision ID: brian@tangent.org-20110324231446-7q1gydkglys73nft
Merge in XTF

Show diffs side-by-side

added added

removed removed

Lines of Context:
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/session/cache.h"
52
 
#include "drizzled/internal/my_sys.h"
53
 
#include "drizzled/unireg.h"
54
 
#include "drizzled/drizzled.h"
55
 
#include "drizzled/errmsg_print.h"
56
 
#include "drizzled/data_home.h"
57
 
#include "drizzled/plugin/listen.h"
58
 
#include "drizzled/plugin/client.h"
59
 
#include "drizzled/pthread_globals.h"
60
 
#include "drizzled/tztime.h"
61
 
#include "drizzled/signal_handler.h"
62
 
#include "drizzled/replication_services.h"
63
 
#include "drizzled/transaction_services.h"
64
 
#include "drizzled/catalog/local.h"
65
 
 
66
 
#include "drizzled/util/backtrace.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>
 
71
#include <drizzled/diagnostics_area.h>
 
72
#include <drizzled/sql_base.h>
 
73
#include <drizzled/sql_lex.h>
 
74
#include <drizzled/system_variables.h>
67
75
 
68
76
using namespace drizzled;
69
77
using namespace std;
70
 
namespace fs=boost::filesystem;
71
78
 
72
79
static pthread_t select_thread;
73
80
static uint32_t thr_kill_signal;
74
81
 
 
82
extern bool opt_daemon;
 
83
 
75
84
 
76
85
/**
77
86
  All global error messages are sent here where the first one is stored
90
99
      session->is_fatal_error= 1;
91
100
 
92
101
    /*
93
 
      TODO: There are two exceptions mechanism (Session and sp_rcontext),
 
102
      @TODO There are two exceptions mechanism (Session and sp_rcontext),
94
103
      this could be improved by having a common stack of handlers.
95
104
    */
96
 
    if (session->handle_error(error, str,
97
 
                          DRIZZLE_ERROR::WARN_LEVEL_ERROR))
98
 
      return;;
 
105
    if (session->handle_error(error, str, DRIZZLE_ERROR::WARN_LEVEL_ERROR))
 
106
      return;
99
107
 
100
108
    /*
101
 
      session->lex->current_select == 0 if lex structure is not inited
 
109
      session->lex().current_select == 0 if lex structure is not inited
102
110
      (not query command (COM_QUERY))
103
111
    */
104
 
    if (! (session->lex->current_select &&
105
 
        session->lex->current_select->no_error && !session->is_fatal_error))
 
112
    if (! (session->lex().current_select &&
 
113
           session->lex().current_select->no_error && !session->is_fatal_error))
106
114
    {
107
 
      if (! session->main_da.is_error())            // Return only first message
 
115
      if (! session->main_da().is_error())            // Return only first message
108
116
      {
109
117
        if (error == EE_OK)
110
118
          error= ER_UNKNOWN_ERROR;
112
120
        if (str == NULL)
113
121
          str= ER(error);
114
122
 
115
 
        session->main_da.set_error_status(error, str);
 
123
        session->main_da().set_error_status(error, str);
116
124
      }
117
125
    }
118
126
 
125
133
      session->no_warnings_for_error= true;
126
134
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, str);
127
135
      session->no_warnings_for_error= false;
128
 
      }
129
136
    }
130
 
    if (!session || MyFlags & ME_NOREFRESH)
131
 
        errmsg_printf(ERRMSG_LVL_ERROR, "%s: %s",internal::my_progname,str);
 
137
  }
 
138
 
 
139
  if (not session || MyFlags & ME_NOREFRESH)
 
140
  {
 
141
    errmsg_printf(error::ERROR, "%s: %s",internal::my_progname,str);
 
142
  }
132
143
}
133
144
 
134
145
static void init_signals(void)
136
147
  sigset_t set;
137
148
  struct sigaction sa;
138
149
 
139
 
  if (!(test_flags.test(TEST_NO_STACKTRACE) || 
140
 
        test_flags.test(TEST_CORE_ON_SIGNAL)))
 
150
  if (not (getDebug().test(debug::NO_STACKTRACE) ||
 
151
        getDebug().test(debug::CORE_ON_SIGNAL)))
141
152
  {
142
153
    sa.sa_flags = SA_RESETHAND | SA_NODEFER;
143
154
    sigemptyset(&sa.sa_mask);
153
164
    sigaction(SIGFPE, &sa, NULL);
154
165
  }
155
166
 
156
 
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
 
167
  if (getDebug().test(debug::CORE_ON_SIGNAL))
157
168
  {
158
169
    /* Change limits so that we will get a core file */
159
170
    struct rlimit rl;
160
171
    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
161
172
    if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
162
 
        errmsg_printf(ERRMSG_LVL_WARN,
 
173
        errmsg_printf(error::WARN,
163
174
                      _("setrlimit could not change the size of core files "
164
175
                        "to 'infinity';  We may not be able to generate a "
165
176
                        "core file on signals"));
184
195
#ifdef SIGTSTP
185
196
  sigaddset(&set,SIGTSTP);
186
197
#endif
187
 
  if (test_flags.test(TEST_SIGINT))
 
198
  if (getDebug().test(debug::ALLOW_SIGINT))
188
199
  {
189
200
    sa.sa_flags= 0;
190
201
    sa.sa_handler= drizzled_end_thread_signal;
240
251
 
241
252
  /* Function generates error messages before abort */
242
253
  error_handler_hook= my_message_sql;
 
254
 
243
255
  /* init_common_variables must get basic settings such as data_home_dir
244
256
     and plugin_load_list. */
245
 
  if (init_common_variables(argc, argv, modules))
 
257
  if (init_basic_variables(argc, argv))
 
258
    unireg_abort(1);                            // Will do exit
 
259
 
 
260
  if (opt_daemon)
 
261
  {
 
262
    if (signal(SIGHUP, SIG_IGN) == SIG_ERR)
 
263
    {
 
264
      perror("Failed to ignore SIGHUP");
 
265
    }
 
266
    if (daemonize())
 
267
    {
 
268
      fprintf(stderr, "failed to daemon() in order to daemonize\n");
 
269
      exit(EXIT_FAILURE);
 
270
    }
 
271
  }
 
272
 
 
273
  if (init_remaining_variables(modules))
246
274
    unireg_abort(1);                            // Will do exit
247
275
 
248
276
  /*
259
287
  {
260
288
    if (chdir(getDataHome().file_string().c_str()))
261
289
    {
262
 
      errmsg_printf(ERRMSG_LVL_ERROR,
 
290
      errmsg_printf(error::ERROR,
263
291
                    _("Data directory %s does not exist\n"),
264
292
                    getDataHome().file_string().c_str());
265
293
      unireg_abort(1);
270
298
    }
271
299
    if (chdir("local"))
272
300
    {
273
 
      errmsg_printf(ERRMSG_LVL_ERROR,
 
301
      errmsg_printf(error::ERROR,
274
302
                    _("Local catalog %s/local does not exist\n"),
275
303
                    getDataHome().file_string().c_str());
276
304
      unireg_abort(1);
277
305
    }
278
306
 
279
 
    full_data_home= fs::system_complete(getDataHome());
280
 
    getDataHomeCatalog()= "./";
281
 
    getDataHome()= "../";
 
307
    boost::filesystem::path &full_data_home= getFullDataHome();
 
308
    full_data_home= boost::filesystem::system_complete(getDataHome());
 
309
    errmsg_printf(error::INFO, "Data Home directory is : %s", full_data_home.native_file_string().c_str());
282
310
  }
283
311
 
284
312
 
288
316
    server_id= 1;
289
317
  }
290
318
 
291
 
  if (init_server_components(modules))
 
319
  try
 
320
  {
 
321
    if (init_server_components(modules))
 
322
      DRIZZLE_ABORT;
 
323
  }
 
324
  catch (abort_exception& ex)
 
325
  {
 
326
#if defined(DEBUG)
 
327
    cout << _("Drizzle has receieved an abort event.") << endl;
 
328
    cout << _("In Function: ") << *::boost::get_error_info<boost::throw_function>(ex) << endl;
 
329
    cout << _("In File: ") << *::boost::get_error_info<boost::throw_file>(ex) << endl;
 
330
    cout << _("On Line: ") << *::boost::get_error_info<boost::throw_line>(ex) << endl;
 
331
#endif
292
332
    unireg_abort(1);
 
333
  }
 
334
 
293
335
 
294
336
  /**
295
337
   * This check must be done after init_server_components for now
308
350
  if (plugin::Listen::setup())
309
351
    unireg_abort(1);
310
352
 
311
 
 
312
353
  assert(plugin::num_trx_monitored_objects > 0);
313
 
  if (drizzle_rm_tmp_tables() ||
314
 
      my_tz_init((Session *)0, default_tz_name))
 
354
  if (drizzle_rm_tmp_tables())
315
355
  {
316
356
    abort_loop= true;
317
357
    select_thread_in_use=0;
319
359
 
320
360
    (void) unlink(pid_file.file_string().c_str());      // Not needed anymore
321
361
 
322
 
    exit(1);
 
362
    unireg_abort(1);
323
363
  }
324
364
 
325
 
  errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_STARTUP)), internal::my_progname,
 
365
  errmsg_printf(error::INFO, _(ER(ER_STARTUP)), internal::my_progname,
326
366
                PANDORA_RELEASE_VERSION, COMPILATION_COMMENT);
327
367
 
328
368
 
336
376
    {
337
377
      currentSession().release();
338
378
      currentSession().reset(session.get());
339
 
      transaction_services.sendStartupEvent(session.get());
 
379
 
 
380
 
 
381
      transaction_services.sendStartupEvent(*session);
 
382
 
 
383
      plugin_startup_window(modules, *(session.get()));
340
384
    }
341
385
  }
342
386
 
 
387
  if (opt_daemon)
 
388
    daemon_is_ready();
343
389
 
344
 
  /* 
 
390
  /*
345
391
    Listen for new connections and start new session for each connection
346
392
     accepted. The listen.getClient() method will return NULL when the server
347
393
     should be shutdown.
350
396
  while ((client= plugin::Listen::getClient()) != NULL)
351
397
  {
352
398
    Session::shared_ptr session;
353
 
    session= Session::make_shared(client, catalog::local());
 
399
    session= Session::make_shared(client, client->catalog());
354
400
 
355
401
    if (not session)
356
402
    {
371
417
    {
372
418
      currentSession().release();
373
419
      currentSession().reset(session.get());
374
 
      transaction_services.sendShutdownEvent(session.get());
 
420
      transaction_services.sendShutdownEvent(*session.get());
375
421
    }
376
422
  }
377
423
 
382
428
  COND_thread_count.notify_all();
383
429
 
384
430
  /* Wait until cleanup is done */
385
 
  {
386
 
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
387
 
    while (not ready_to_exit)
388
 
      COND_server_end.wait(scopedLock);
389
 
  }
 
431
  session::Cache::singleton().shutdownSecond();
390
432
 
391
433
  clean_up(1);
392
434
  module::Registry::shutdown();