~drizzle-trunk/drizzle/development

900 by Brian Aker
Creating signal handler plugin.
1
/* Copyright (C) 2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
16
#include "config.h"
900 by Brian Aker
Creating signal handler plugin.
17
#include <drizzled/gettext.h>
18
#include <drizzled/error.h>
1022.2.2 by Monty Taylor
Small cleanup inspired by merge.
19
#include <drizzled/unireg.h>
1237.9.3 by Padraig O'Sullivan
Removed one the includes I put in server_includes.h for the last commit to get rid of the inclusion
20
#include <drizzled/plugin/storage_engine.h>
21
#include <drizzled/cursor.h> /* for refresh_version */
1241.9.31 by Monty Taylor
Moved global pthread variables into their own header.
22
#include "drizzled/pthread_globals.h"
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
23
#include "drizzled/internal/my_pthread.h"
24
#include "drizzled/internal/my_sys.h"
1324.2.3 by Monty Taylor
Remove plugin deinit.
25
#include "drizzled/plugin/daemon.h"
1300.5.22 by Monty Taylor
Moved and reworked a wrapper around sigset - which we shouldn't be using
26
#include "drizzled/signal_handler.h"
900 by Brian Aker
Creating signal handler plugin.
27
1966.2.5 by Brian Aker
Style change around session list.
28
#include "drizzled/session/cache.h"
1932.3.4 by Brian Aker
Move counter lock so that ownership is held by session_list.
29
1733.3.1 by LinuxJedi
Make exit happen in main thread rather than signal handler thread thus avoiding a segfault due to a double kill of the signal handler thread
30
#include "drizzled/drizzled.h"
31
1755.2.11 by Brian Aker
Update for boost.
32
#include <boost/thread/thread.hpp>
1813.2.2 by Monty Taylor
Replaced pid-file with fs::path.
33
#include <boost/filesystem.hpp>
1755.2.11 by Brian Aker
Update for boost.
34
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
35
#include <sys/stat.h>
36
#include <fcntl.h>
37
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
38
900 by Brian Aker
Creating signal handler plugin.
39
static bool kill_in_progress= false;
1755.2.11 by Brian Aker
Update for boost.
40
void signal_hand(void);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
41
42
namespace drizzled
43
{
900 by Brian Aker
Creating signal handler plugin.
44
extern int cleanup_done;
1241.9.33 by Monty Taylor
Moved most of the global vars to set_var where they belong.
45
extern bool volatile abort_loop;
46
extern bool volatile shutdown_in_progress;
1813.2.2 by Monty Taylor
Replaced pid-file with fs::path.
47
extern boost::filesystem::path pid_file;
900 by Brian Aker
Creating signal handler plugin.
48
/* Prototypes -> all of these should be factored out into a propper shutdown */
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
49
extern void close_connections(void);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
50
extern std::bitset<12> test_flags;
51
}
52
53
using namespace drizzled;
54
900 by Brian Aker
Creating signal handler plugin.
55
56
1932.3.4 by Brian Aker
Move counter lock so that ownership is held by session_list.
57
900 by Brian Aker
Creating signal handler plugin.
58
/**
59
  Force server down. Kill all connections and threads and exit.
60
61
  @param  sig_ptr       Signal number that caused kill_server to be called.
62
63
  @note
64
    A signal number of 0 mean that the function was not called
65
    from a signal handler and there is thus no signal to block
66
    or stop, we just want to kill the server.
67
*/
68
1816.2.6 by Monty Taylor
Fixed three more ICC warnings.
69
static void kill_server(int sig)
900 by Brian Aker
Creating signal handler plugin.
70
{
71
  // if there is a signal during the kill in progress, ignore the other
72
  if (kill_in_progress)				// Safety
1022.2.18 by Monty Taylor
Fixed the fix on solaris.
73
    return;
900 by Brian Aker
Creating signal handler plugin.
74
  kill_in_progress=true;
75
  abort_loop=1;					// This should be set
76
  if (sig != 0) // 0 is not a valid signal number
1300.5.23 by Monty Taylor
Merged in revs removing depend on the plugin tree.
77
    ignore_signal(sig);                    /* purify inspected */
900 by Brian Aker
Creating signal handler plugin.
78
  if (sig == SIGTERM || sig == 0)
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
79
    errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_NORMAL_SHUTDOWN)),internal::my_progname);
900 by Brian Aker
Creating signal handler plugin.
80
  else
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
81
    errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_GOT_SIGNAL)),internal::my_progname,sig);
900 by Brian Aker
Creating signal handler plugin.
82
  close_connections();
1733.3.3 by LinuxJedi
Fix valgrind warnings (plus make exit clean up properly)
83
  clean_up(1);
900 by Brian Aker
Creating signal handler plugin.
84
}
85
86
/**
87
  Create file to store pid number.
88
*/
89
static void create_pid_file()
90
{
914.2.1 by Brian Aker
Cleanup pid handler.
91
  int file;
92
  char buff[1024];
93
1813.2.2 by Monty Taylor
Replaced pid-file with fs::path.
94
  if ((file = open(pid_file.file_string().c_str(), O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU|S_IRGRP|S_IROTH)) > 0)
900 by Brian Aker
Creating signal handler plugin.
95
  {
914.2.1 by Brian Aker
Cleanup pid handler.
96
    int length;
97
98
    length= snprintf(buff, 1024, "%ld\n", (long) getpid()); 
99
100
    if ((write(file, buff, length)) == length)
900 by Brian Aker
Creating signal handler plugin.
101
    {
914.2.1 by Brian Aker
Cleanup pid handler.
102
      if (close(file) != -1)
103
        return;
900 by Brian Aker
Creating signal handler plugin.
104
    }
914.2.1 by Brian Aker
Cleanup pid handler.
105
    (void)close(file); /* We can ignore the error, since we are going to error anyway at this point */
900 by Brian Aker
Creating signal handler plugin.
106
  }
1798.2.2 by Monty Taylor
Fix trailing 0 problem.
107
  memset(buff, 0, sizeof(buff));
1813.2.2 by Monty Taylor
Replaced pid-file with fs::path.
108
  snprintf(buff, sizeof(buff)-1, "Can't start server: can't create PID file (%s)", pid_file.file_string().c_str());
914.2.1 by Brian Aker
Cleanup pid handler.
109
  sql_perror(buff);
900 by Brian Aker
Creating signal handler plugin.
110
  exit(1);
111
}
112
113
114
/** This threads handles all signals and alarms. */
1755.2.11 by Brian Aker
Update for boost.
115
void signal_hand()
900 by Brian Aker
Creating signal handler plugin.
116
{
117
  sigset_t set;
118
  int sig;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
119
  internal::my_thread_init();				// Init new thread
1782.3.1 by Brian Aker
Pushes up thread ownership to the modules that create them.
120
  boost::this_thread::at_thread_exit(&internal::my_thread_end);
900 by Brian Aker
Creating signal handler plugin.
121
  signal_thread_in_use= true;
122
1711.6.6 by Brian Aker
Remove the code surrounding stack trace.
123
  if ((test_flags.test(TEST_SIGINT)))
900 by Brian Aker
Creating signal handler plugin.
124
  {
125
    (void) sigemptyset(&set);			// Setup up SIGINT for debug
126
    (void) sigaddset(&set,SIGINT);		// For debugging
127
    (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
128
  }
129
  (void) sigemptyset(&set);			// Setup up SIGINT for debug
130
#ifndef IGNORE_SIGHUP_SIGQUIT
1779.2.1 by Brian Aker
Fix issue with signal thread not shutting down (OSX).
131
  if (sigaddset(&set,SIGQUIT))
132
  {
133
    std::cerr << "failed setting sigaddset() with SIGQUIT\n";
134
  }
135
  if (sigaddset(&set,SIGHUP))
136
  {
137
    std::cerr << "failed setting sigaddset() with SIGHUP\n";
138
  }
900 by Brian Aker
Creating signal handler plugin.
139
#endif
1779.2.1 by Brian Aker
Fix issue with signal thread not shutting down (OSX).
140
  if (sigaddset(&set,SIGTERM))
141
  {
142
    std::cerr << "failed setting sigaddset() with SIGTERM\n";
143
  }
144
  if (sigaddset(&set,SIGTSTP))
145
  {
146
    std::cerr << "failed setting sigaddset() with SIGTSTP\n";
147
  }
900 by Brian Aker
Creating signal handler plugin.
148
149
  /* Save pid to this process (or thread on Linux) */
150
  create_pid_file();
151
152
  /*
905 by Brian Aker
Code cleanup in signal_handler.cc
153
    signal to init that we are ready
154
    This works by waiting for init to free mutex,
900 by Brian Aker
Creating signal handler plugin.
155
    after which we signal it that we are ready.
156
    At this pointer there is no other threads running, so there
157
    should not be any other pthread_cond_signal() calls.
158
159
    We call lock/unlock to out wait any thread/session which is
160
    dieing. Since only comes from this code, this should be safe.
161
    (Asked MontyW over the phone about this.) -Brian
162
163
  */
1932.3.4 by Brian Aker
Move counter lock so that ownership is held by session_list.
164
  session::Cache::singleton().mutex().lock();
165
  session::Cache::singleton().mutex().unlock();
1689.2.5 by Brian Aker
Convert COND_thread_count to boost.
166
  COND_thread_count.notify_all();
900 by Brian Aker
Creating signal handler plugin.
167
1779.2.1 by Brian Aker
Fix issue with signal thread not shutting down (OSX).
168
  if (pthread_sigmask(SIG_BLOCK, &set, NULL))
169
  {
170
    std::cerr << "Failed to set pthread_sigmask() in signal handler\n";
171
  }
172
900 by Brian Aker
Creating signal handler plugin.
173
  for (;;)
174
  {
175
    int error;					// Used when debugging
1755.2.13 by Brian Aker
Add join in order to allow for signal thread to be shutdown during shutdown
176
900 by Brian Aker
Creating signal handler plugin.
177
    if (shutdown_in_progress && !abort_loop)
178
    {
179
      sig= SIGTERM;
180
      error=0;
181
    }
182
    else
1755.2.13 by Brian Aker
Add join in order to allow for signal thread to be shutdown during shutdown
183
    {
1779.2.1 by Brian Aker
Fix issue with signal thread not shutting down (OSX).
184
      while ((error= sigwait(&set, &sig)) == EINTR) ;
1755.2.13 by Brian Aker
Add join in order to allow for signal thread to be shutdown during shutdown
185
    }
186
900 by Brian Aker
Creating signal handler plugin.
187
    if (cleanup_done)
188
    {
189
      signal_thread_in_use= false;
190
1755.2.11 by Brian Aker
Update for boost.
191
      return;
900 by Brian Aker
Creating signal handler plugin.
192
    }
193
    switch (sig) {
194
    case SIGTERM:
195
    case SIGQUIT:
196
    case SIGKILL:
1779.2.1 by Brian Aker
Fix issue with signal thread not shutting down (OSX).
197
    case SIGTSTP:
900 by Brian Aker
Creating signal handler plugin.
198
      /* switch to the old log message processing */
199
      if (!abort_loop)
200
      {
201
        abort_loop=1;				// mark abort for threads
1816.2.6 by Monty Taylor
Fixed three more ICC warnings.
202
        kill_server(sig);		// MIT THREAD has a alarm thread
900 by Brian Aker
Creating signal handler plugin.
203
      }
204
      break;
205
    case SIGHUP:
206
      if (!abort_loop)
1109.1.4 by Brian Aker
More Table refactor
207
      {
208
        refresh_version++;
1152.1.3 by Brian Aker
refactored drizzled::plugin::StorageEngine::flushLogs()
209
        drizzled::plugin::StorageEngine::flushLogs(NULL);
1109.1.4 by Brian Aker
More Table refactor
210
      }
900 by Brian Aker
Creating signal handler plugin.
211
      break;
212
    default:
971.6.11 by Eric Day
Removed purecov messages.
213
      break;
900 by Brian Aker
Creating signal handler plugin.
214
    }
215
  }
216
}
217
1324.2.3 by Monty Taylor
Remove plugin deinit.
218
class SignalHandler :
219
  public drizzled::plugin::Daemon
900 by Brian Aker
Creating signal handler plugin.
220
{
1324.2.3 by Monty Taylor
Remove plugin deinit.
221
  SignalHandler(const SignalHandler &);
222
  SignalHandler& operator=(const SignalHandler &);
1755.2.11 by Brian Aker
Update for boost.
223
  boost::thread thread;
224
1324.2.3 by Monty Taylor
Remove plugin deinit.
225
public:
1755.2.11 by Brian Aker
Update for boost.
226
  SignalHandler() :
227
    drizzled::plugin::Daemon("Signal Handler")
900 by Brian Aker
Creating signal handler plugin.
228
  {
1689.2.5 by Brian Aker
Convert COND_thread_count to boost.
229
    // @todo fix spurious wakeup issue
1932.3.4 by Brian Aker
Move counter lock so that ownership is held by session_list.
230
    boost::mutex::scoped_lock scopedLock(session::Cache::singleton().mutex());
1755.2.11 by Brian Aker
Update for boost.
231
    thread= boost::thread(signal_hand);
232
    signal_thread= thread.native_handle();
233
    COND_thread_count.wait(scopedLock);
900 by Brian Aker
Creating signal handler plugin.
234
  }
1324.2.3 by Monty Taylor
Remove plugin deinit.
235
236
  /**
237
    This is mainly needed when running with purify, but it's still nice to
238
    know that all child threads have died when drizzled exits.
900 by Brian Aker
Creating signal handler plugin.
239
  */
1324.2.3 by Monty Taylor
Remove plugin deinit.
240
  ~SignalHandler()
900 by Brian Aker
Creating signal handler plugin.
241
  {
1324.2.3 by Monty Taylor
Remove plugin deinit.
242
    /*
1672.3.7 by Brian Aker
Remve usleep for nanosleep.
243
      Wait up to 100000 micro-seconds for signal thread to die. We use this mainly to
1324.2.3 by Monty Taylor
Remove plugin deinit.
244
      avoid getting warnings that internal::my_thread_end has not been called
245
    */
1779.2.1 by Brian Aker
Fix issue with signal thread not shutting down (OSX).
246
    bool completed= false;
247
    /*
248
     * We send SIGTERM and then do a timed join. If that fails we will on
249
     * the last pthread_kill() call SIGTSTP. OSX (and FreeBSD) seem to
250
     * prefer this. -Brian
251
   */
252
    uint32_t count= 2; // How many times to try join and see if the caller died.
253
    while (not completed and count--)
254
    {
255
      int error;
256
      int signal= count == 1 ? SIGTSTP : SIGTERM;
257
      
258
      if ((error= pthread_kill(thread.native_handle(), signal)))
259
      {
260
        char buffer[1024]; // No reason for number;
261
        strerror_r(error, buffer, sizeof(buffer));
262
        std::cerr << "pthread_kill() error on shutdown of signal thread (" << buffer << ")\n";
263
        break;
264
      }
265
      else
266
      {
267
        boost::posix_time::milliseconds duration(100);
268
        completed= thread.timed_join(duration);
269
      }
270
    }
900 by Brian Aker
Creating signal handler plugin.
271
  }
1324.2.3 by Monty Taylor
Remove plugin deinit.
272
};
900 by Brian Aker
Creating signal handler plugin.
273
1530.2.6 by Monty Taylor
Moved plugin::Context to module::Context.
274
static int init(drizzled::module::Context& context)
1324.2.3 by Monty Taylor
Remove plugin deinit.
275
{
1755.2.10 by Brian Aker
Clean up the calls around the signal handler.
276
  context.add(new SignalHandler);
277
900 by Brian Aker
Creating signal handler plugin.
278
  return 0;
279
}
280
1324.2.3 by Monty Taylor
Remove plugin deinit.
281
1228.1.5 by Monty Taylor
Merged in some naming things.
282
static drizzle_sys_var* system_variables[]= {
900 by Brian Aker
Creating signal handler plugin.
283
  NULL
284
};
285
1228.1.5 by Monty Taylor
Merged in some naming things.
286
DRIZZLE_DECLARE_PLUGIN
900 by Brian Aker
Creating signal handler plugin.
287
{
1241.10.2 by Monty Taylor
Added support for embedding the drizzle version number in the plugin file.
288
  DRIZZLE_VERSION_ID,
900 by Brian Aker
Creating signal handler plugin.
289
  "signal_handler",
290
  "0.1",
291
  "Brian Aker",
292
  "Default Signal Handler",
293
  PLUGIN_LICENSE_GPL,
294
  init, /* Plugin Init */
295
  system_variables,   /* system variables */
296
  NULL    /* config options */
297
}
1228.1.5 by Monty Taylor
Merged in some naming things.
298
DRIZZLE_DECLARE_PLUGIN_END;