~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
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
28
#include <sys/stat.h>
29
#include <fcntl.h>
30
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
31
900 by Brian Aker
Creating signal handler plugin.
32
static bool kill_in_progress= false;
33
static bool volatile signal_thread_in_use= false;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
34
extern "C" pthread_handler_t signal_hand(void *);
35
36
namespace drizzled
37
{
900 by Brian Aker
Creating signal handler plugin.
38
extern int cleanup_done;
1241.9.33 by Monty Taylor
Moved most of the global vars to set_var where they belong.
39
extern bool volatile abort_loop;
40
extern bool volatile shutdown_in_progress;
41
extern char pidfile_name[FN_REFLEN];
900 by Brian Aker
Creating signal handler plugin.
42
/* Prototypes -> all of these should be factored out into a propper shutdown */
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
43
extern void close_connections(void);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
44
extern std::bitset<12> test_flags;
45
}
46
47
using namespace drizzled;
48
900 by Brian Aker
Creating signal handler plugin.
49
50
51
/**
52
  Force server down. Kill all connections and threads and exit.
53
54
  @param  sig_ptr       Signal number that caused kill_server to be called.
55
56
  @note
57
    A signal number of 0 mean that the function was not called
58
    from a signal handler and there is thus no signal to block
59
    or stop, we just want to kill the server.
60
*/
61
1022.2.18 by Monty Taylor
Fixed the fix on solaris.
62
static void kill_server(void *sig_ptr)
900 by Brian Aker
Creating signal handler plugin.
63
{
64
  int sig=(int) (long) sig_ptr;			// This is passed a int
65
  // if there is a signal during the kill in progress, ignore the other
66
  if (kill_in_progress)				// Safety
1022.2.18 by Monty Taylor
Fixed the fix on solaris.
67
    return;
900 by Brian Aker
Creating signal handler plugin.
68
  kill_in_progress=true;
69
  abort_loop=1;					// This should be set
70
  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.
71
    ignore_signal(sig);                    /* purify inspected */
900 by Brian Aker
Creating signal handler plugin.
72
  if (sig == SIGTERM || sig == 0)
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
73
    errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_NORMAL_SHUTDOWN)),internal::my_progname);
900 by Brian Aker
Creating signal handler plugin.
74
  else
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
75
    errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_GOT_SIGNAL)),internal::my_progname,sig);
900 by Brian Aker
Creating signal handler plugin.
76
77
  close_connections();
78
  if (sig != SIGTERM && sig != 0)
971.6.11 by Eric Day
Removed purecov messages.
79
    unireg_abort(1);
900 by Brian Aker
Creating signal handler plugin.
80
  else
81
    unireg_end();
82
}
83
84
/**
85
  Create file to store pid number.
86
*/
87
static void create_pid_file()
88
{
914.2.1 by Brian Aker
Cleanup pid handler.
89
  int file;
90
  char buff[1024];
91
92
  assert(pidfile_name[0]);
93
  if ((file = open(pidfile_name, O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU|S_IRGRP|S_IROTH)) > 0)
900 by Brian Aker
Creating signal handler plugin.
94
  {
914.2.1 by Brian Aker
Cleanup pid handler.
95
    int length;
96
97
    length= snprintf(buff, 1024, "%ld\n", (long) getpid()); 
98
99
    if ((write(file, buff, length)) == length)
900 by Brian Aker
Creating signal handler plugin.
100
    {
914.2.1 by Brian Aker
Cleanup pid handler.
101
      if (close(file) != -1)
102
        return;
900 by Brian Aker
Creating signal handler plugin.
103
    }
914.2.1 by Brian Aker
Cleanup pid handler.
104
    (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.
105
  }
914.2.1 by Brian Aker
Cleanup pid handler.
106
  snprintf(buff, 1024, "Can't start server: can't create PID file (%s)", pidfile_name);
107
  sql_perror(buff);
900 by Brian Aker
Creating signal handler plugin.
108
  exit(1);
109
}
110
111
112
/** This threads handles all signals and alarms. */
113
pthread_handler_t signal_hand(void *)
114
{
115
  sigset_t set;
116
  int sig;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
117
  internal::my_thread_init();				// Init new thread
900 by Brian Aker
Creating signal handler plugin.
118
  signal_thread_in_use= true;
119
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
120
  if (internal::thd_lib_detected != THD_LIB_LT && 
1089.6.1 by Padraig O'Sullivan
Converted the test_flags variable from a uint32_t to std::bitset.
121
      (test_flags.test(TEST_SIGINT)))
900 by Brian Aker
Creating signal handler plugin.
122
  {
123
    (void) sigemptyset(&set);			// Setup up SIGINT for debug
124
    (void) sigaddset(&set,SIGINT);		// For debugging
125
    (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
126
  }
127
  (void) sigemptyset(&set);			// Setup up SIGINT for debug
128
#ifndef IGNORE_SIGHUP_SIGQUIT
129
  (void) sigaddset(&set,SIGQUIT);
130
  (void) sigaddset(&set,SIGHUP);
131
#endif
132
  (void) sigaddset(&set,SIGTERM);
133
  (void) sigaddset(&set,SIGTSTP);
134
135
  /* Save pid to this process (or thread on Linux) */
136
  create_pid_file();
137
138
  /*
905 by Brian Aker
Code cleanup in signal_handler.cc
139
    signal to init that we are ready
140
    This works by waiting for init to free mutex,
900 by Brian Aker
Creating signal handler plugin.
141
    after which we signal it that we are ready.
142
    At this pointer there is no other threads running, so there
143
    should not be any other pthread_cond_signal() calls.
144
145
    We call lock/unlock to out wait any thread/session which is
146
    dieing. Since only comes from this code, this should be safe.
147
    (Asked MontyW over the phone about this.) -Brian
148
149
  */
150
  if (pthread_mutex_lock(&LOCK_thread_count) == 0)
151
    (void) pthread_mutex_unlock(&LOCK_thread_count);
152
  (void) pthread_cond_broadcast(&COND_thread_count);
153
154
  (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
155
  for (;;)
156
  {
157
    int error;					// Used when debugging
158
    if (shutdown_in_progress && !abort_loop)
159
    {
160
      sig= SIGTERM;
161
      error=0;
162
    }
163
    else
164
      while ((error= sigwait(&set,&sig)) == EINTR) ;
165
    if (cleanup_done)
166
    {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
167
      internal::my_thread_end();
900 by Brian Aker
Creating signal handler plugin.
168
      signal_thread_in_use= false;
169
170
      return NULL;
171
    }
172
    switch (sig) {
173
    case SIGTERM:
174
    case SIGQUIT:
175
    case SIGKILL:
176
      /* switch to the old log message processing */
177
      if (!abort_loop)
178
      {
179
        abort_loop=1;				// mark abort for threads
180
        kill_server((void*) sig);	// MIT THREAD has a alarm thread
181
      }
182
      break;
183
    case SIGHUP:
184
      if (!abort_loop)
1109.1.4 by Brian Aker
More Table refactor
185
      {
186
        refresh_version++;
1152.1.3 by Brian Aker
refactored drizzled::plugin::StorageEngine::flushLogs()
187
        drizzled::plugin::StorageEngine::flushLogs(NULL);
1109.1.4 by Brian Aker
More Table refactor
188
      }
900 by Brian Aker
Creating signal handler plugin.
189
      break;
190
    default:
971.6.11 by Eric Day
Removed purecov messages.
191
      break;
900 by Brian Aker
Creating signal handler plugin.
192
    }
193
  }
194
}
195
1324.2.3 by Monty Taylor
Remove plugin deinit.
196
class SignalHandler :
197
  public drizzled::plugin::Daemon
900 by Brian Aker
Creating signal handler plugin.
198
{
1324.2.3 by Monty Taylor
Remove plugin deinit.
199
  SignalHandler(const SignalHandler &);
200
  SignalHandler& operator=(const SignalHandler &);
201
public:
202
  SignalHandler()
203
    : drizzled::plugin::Daemon("Signal Handler")
900 by Brian Aker
Creating signal handler plugin.
204
  {
1324.2.3 by Monty Taylor
Remove plugin deinit.
205
    int error;
206
    pthread_attr_t thr_attr;
207
    size_t my_thread_stack_size= 65536;
208
209
    (void) pthread_attr_init(&thr_attr);
210
    pthread_attr_setscope(&thr_attr, PTHREAD_SCOPE_SYSTEM);
211
    (void) pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED);
212
    {
213
      struct sched_param tmp_sched_param;
214
215
      memset(&tmp_sched_param, 0, sizeof(tmp_sched_param));
216
      tmp_sched_param.sched_priority= INTERRUPT_PRIOR;
217
      (void)pthread_attr_setschedparam(&thr_attr, &tmp_sched_param);
218
    }
900 by Brian Aker
Creating signal handler plugin.
219
#if defined(__ia64__) || defined(__ia64)
1324.2.3 by Monty Taylor
Remove plugin deinit.
220
    /*
221
      Peculiar things with ia64 platforms - it seems we only have half the
222
      stack size in reality, so we have to double it here
223
    */
224
    pthread_attr_setstacksize(&thr_attr, my_thread_stack_size*2);
900 by Brian Aker
Creating signal handler plugin.
225
# else
1324.2.3 by Monty Taylor
Remove plugin deinit.
226
    pthread_attr_setstacksize(&thr_attr, my_thread_stack_size);
900 by Brian Aker
Creating signal handler plugin.
227
#endif
228
1324.2.3 by Monty Taylor
Remove plugin deinit.
229
    (void) pthread_mutex_lock(&LOCK_thread_count);
230
    if ((error=pthread_create(&signal_thread, &thr_attr, signal_hand, 0)))
231
    {
232
      errmsg_printf(ERRMSG_LVL_ERROR,
233
                    _("Can't create interrupt-thread (error %d, errno: %d)"),
900 by Brian Aker
Creating signal handler plugin.
234
                    error,errno);
1324.2.3 by Monty Taylor
Remove plugin deinit.
235
      exit(1);
236
    }
237
    (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
238
    pthread_mutex_unlock(&LOCK_thread_count);
239
240
    (void) pthread_attr_destroy(&thr_attr);
900 by Brian Aker
Creating signal handler plugin.
241
  }
1324.2.3 by Monty Taylor
Remove plugin deinit.
242
243
  /**
244
    This is mainly needed when running with purify, but it's still nice to
245
    know that all child threads have died when drizzled exits.
900 by Brian Aker
Creating signal handler plugin.
246
  */
1324.2.3 by Monty Taylor
Remove plugin deinit.
247
  ~SignalHandler()
900 by Brian Aker
Creating signal handler plugin.
248
  {
1324.2.3 by Monty Taylor
Remove plugin deinit.
249
    uint32_t i;
250
    /*
251
      Wait up to 10 seconds for signal thread to die. We use this mainly to
252
      avoid getting warnings that internal::my_thread_end has not been called
253
    */
254
    for (i= 0 ; i < 100 && signal_thread_in_use; i++)
255
    {
256
      if (pthread_kill(signal_thread, SIGTERM) != ESRCH)
257
        break;
258
      usleep(100);				// Give it time to die
259
    }
260
900 by Brian Aker
Creating signal handler plugin.
261
  }
1324.2.3 by Monty Taylor
Remove plugin deinit.
262
};
900 by Brian Aker
Creating signal handler plugin.
263
1530.2.6 by Monty Taylor
Moved plugin::Context to module::Context.
264
static int init(drizzled::module::Context& context)
1324.2.3 by Monty Taylor
Remove plugin deinit.
265
{
266
  SignalHandler *handler= new SignalHandler;
267
  context.add(handler);
900 by Brian Aker
Creating signal handler plugin.
268
  return 0;
269
}
270
1324.2.3 by Monty Taylor
Remove plugin deinit.
271
1228.1.5 by Monty Taylor
Merged in some naming things.
272
static drizzle_sys_var* system_variables[]= {
900 by Brian Aker
Creating signal handler plugin.
273
  NULL
274
};
275
1228.1.5 by Monty Taylor
Merged in some naming things.
276
DRIZZLE_DECLARE_PLUGIN
900 by Brian Aker
Creating signal handler plugin.
277
{
1241.10.2 by Monty Taylor
Added support for embedding the drizzle version number in the plugin file.
278
  DRIZZLE_VERSION_ID,
900 by Brian Aker
Creating signal handler plugin.
279
  "signal_handler",
280
  "0.1",
281
  "Brian Aker",
282
  "Default Signal Handler",
283
  PLUGIN_LICENSE_GPL,
284
  init, /* Plugin Init */
285
  system_variables,   /* system variables */
286
  NULL    /* config options */
287
}
1228.1.5 by Monty Taylor
Merged in some naming things.
288
DRIZZLE_DECLARE_PLUGIN_END;