~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/signal_handler/signal_handler.cc

  • Committer: Brian Aker
  • Date: 2009-07-16 22:37:01 UTC
  • mto: This revision was merged to the branch mainline in revision 1100.
  • Revision ID: brian@gaz-20090716223701-vbbbo8dmgd2ljqqo
Refactor TableShare has to be behind class.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
 
#include "config.h"
 
16
#include <drizzled/server_includes.h>
17
17
#include <drizzled/gettext.h>
18
18
#include <drizzled/error.h>
19
19
#include <drizzled/unireg.h>
20
 
#include <drizzled/plugin/storage_engine.h>
21
 
#include <drizzled/cursor.h> /* for refresh_version */
22
 
#include "drizzled/pthread_globals.h"
23
 
#include "drizzled/internal/my_pthread.h"
24
 
#include "drizzled/internal/my_sys.h"
25
 
#include "drizzled/plugin/daemon.h"
26
 
 
27
 
#include <sys/stat.h>
28
 
#include <fcntl.h>
29
 
 
30
20
 
31
21
static bool kill_in_progress= false;
32
22
static bool volatile signal_thread_in_use= false;
 
23
extern int cleanup_done;
33
24
extern "C" pthread_handler_t signal_hand(void *);
34
25
 
35
 
namespace drizzled
36
 
{
37
 
extern int cleanup_done;
38
 
extern bool volatile abort_loop;
39
 
extern bool volatile shutdown_in_progress;
40
 
extern char pidfile_name[FN_REFLEN];
 
26
 
41
27
/* Prototypes -> all of these should be factored out into a propper shutdown */
42
28
extern void close_connections(void);
43
 
extern std::bitset<12> test_flags;
44
 
}
45
 
 
46
 
using namespace drizzled;
47
 
 
 
29
bool reload_cache(Session *session, ulong options, TableList *tables);
48
30
 
49
31
 
50
32
/**
69
51
  if (sig != 0) // 0 is not a valid signal number
70
52
    my_sigset(sig, SIG_IGN);                    /* purify inspected */
71
53
  if (sig == SIGTERM || sig == 0)
72
 
    errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_NORMAL_SHUTDOWN)),internal::my_progname);
 
54
    errmsg_printf(ERRMSG_LVL_INFO, _(ER(ER_NORMAL_SHUTDOWN)),my_progname);
73
55
  else
74
 
    errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_GOT_SIGNAL)),internal::my_progname,sig);
 
56
    errmsg_printf(ERRMSG_LVL_ERROR, _(ER(ER_GOT_SIGNAL)),my_progname,sig); /* purecov: inspected */
75
57
 
76
58
  close_connections();
77
59
  if (sig != SIGTERM && sig != 0)
78
 
    unireg_abort(1);
 
60
    unireg_abort(1);                            /* purecov: inspected */
79
61
  else
80
62
    unireg_end();
81
63
}
113
95
{
114
96
  sigset_t set;
115
97
  int sig;
116
 
  internal::my_thread_init();                           // Init new thread
 
98
  my_thread_init();                             // Init new thread
117
99
  signal_thread_in_use= true;
118
100
 
119
 
  if (internal::thd_lib_detected != THD_LIB_LT && 
 
101
  if (thd_lib_detected != THD_LIB_LT && 
120
102
      (test_flags.test(TEST_SIGINT)))
121
103
  {
122
104
    (void) sigemptyset(&set);                   // Setup up SIGINT for debug
134
116
  /* Save pid to this process (or thread on Linux) */
135
117
  create_pid_file();
136
118
 
 
119
#ifdef HAVE_STACK_TRACE_ON_SEGV
 
120
  if (opt_do_pstack)
 
121
  {
 
122
    sprintf(pstack_file_name,"drizzled-%lu-%%d-%%d.backtrace", (uint32_t)getpid());
 
123
    pstack_install_segv_action(pstack_file_name);
 
124
  }
 
125
#endif /* HAVE_STACK_TRACE_ON_SEGV */
 
126
 
137
127
  /*
138
128
    signal to init that we are ready
139
129
    This works by waiting for init to free mutex,
163
153
      while ((error= sigwait(&set,&sig)) == EINTR) ;
164
154
    if (cleanup_done)
165
155
    {
166
 
      internal::my_thread_end();
 
156
      my_thread_end();
167
157
      signal_thread_in_use= false;
168
158
 
169
159
      return NULL;
181
171
      break;
182
172
    case SIGHUP:
183
173
      if (!abort_loop)
184
 
      {
185
 
        refresh_version++;
186
 
        drizzled::plugin::StorageEngine::flushLogs(NULL);
187
 
      }
 
174
        reload_cache(NULL, (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST ), NULL); // Flush logs
188
175
      break;
189
176
    default:
190
 
      break;
 
177
      break;                                    /* purecov: tested */
191
178
    }
192
179
  }
193
180
}
194
181
 
195
 
class SignalHandler :
196
 
  public drizzled::plugin::Daemon
 
182
 
 
183
static int init(PluginRegistry&)
197
184
{
198
 
  SignalHandler(const SignalHandler &);
199
 
  SignalHandler& operator=(const SignalHandler &);
200
 
public:
201
 
  SignalHandler()
202
 
    : drizzled::plugin::Daemon("Signal Handler")
 
185
  int error;
 
186
  pthread_attr_t thr_attr;
 
187
  size_t my_thread_stack_size= 65536;
 
188
 
 
189
  (void) pthread_attr_init(&thr_attr);
 
190
  pthread_attr_setscope(&thr_attr, PTHREAD_SCOPE_SYSTEM);
 
191
  (void) pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED);
203
192
  {
204
 
    int error;
205
 
    pthread_attr_t thr_attr;
206
 
    size_t my_thread_stack_size= 65536;
207
 
 
208
 
    (void) pthread_attr_init(&thr_attr);
209
 
    pthread_attr_setscope(&thr_attr, PTHREAD_SCOPE_SYSTEM);
210
 
    (void) pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED);
211
 
    {
212
 
      struct sched_param tmp_sched_param;
213
 
 
214
 
      memset(&tmp_sched_param, 0, sizeof(tmp_sched_param));
215
 
      tmp_sched_param.sched_priority= INTERRUPT_PRIOR;
216
 
      (void)pthread_attr_setschedparam(&thr_attr, &tmp_sched_param);
217
 
    }
 
193
    struct sched_param tmp_sched_param;
 
194
 
 
195
    memset(&tmp_sched_param, 0, sizeof(tmp_sched_param));
 
196
    tmp_sched_param.sched_priority= INTERRUPT_PRIOR;
 
197
    (void)pthread_attr_setschedparam(&thr_attr, &tmp_sched_param);
 
198
  }
218
199
#if defined(__ia64__) || defined(__ia64)
219
 
    /*
220
 
      Peculiar things with ia64 platforms - it seems we only have half the
221
 
      stack size in reality, so we have to double it here
222
 
    */
223
 
    pthread_attr_setstacksize(&thr_attr, my_thread_stack_size*2);
 
200
  /*
 
201
    Peculiar things with ia64 platforms - it seems we only have half the
 
202
    stack size in reality, so we have to double it here
 
203
  */
 
204
  pthread_attr_setstacksize(&thr_attr, my_thread_stack_size*2);
224
205
# else
225
 
    pthread_attr_setstacksize(&thr_attr, my_thread_stack_size);
 
206
  pthread_attr_setstacksize(&thr_attr, my_thread_stack_size);
226
207
#endif
227
208
 
228
 
    (void) pthread_mutex_lock(&LOCK_thread_count);
229
 
    if ((error=pthread_create(&signal_thread, &thr_attr, signal_hand, 0)))
230
 
    {
231
 
      errmsg_printf(ERRMSG_LVL_ERROR,
232
 
                    _("Can't create interrupt-thread (error %d, errno: %d)"),
 
209
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
210
  if ((error=pthread_create(&signal_thread, &thr_attr, signal_hand, 0)))
 
211
  {
 
212
      errmsg_printf(ERRMSG_LVL_ERROR, _("Can't create interrupt-thread (error %d, errno: %d)"),
233
213
                    error,errno);
234
 
      exit(1);
235
 
    }
236
 
    (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
237
 
    pthread_mutex_unlock(&LOCK_thread_count);
238
 
 
239
 
    (void) pthread_attr_destroy(&thr_attr);
 
214
    exit(1);
240
215
  }
241
 
 
242
 
  /**
243
 
    This is mainly needed when running with purify, but it's still nice to
244
 
    know that all child threads have died when drizzled exits.
 
216
  (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
 
217
  pthread_mutex_unlock(&LOCK_thread_count);
 
218
 
 
219
  (void) pthread_attr_destroy(&thr_attr);
 
220
 
 
221
  return 0;
 
222
}
 
223
 
 
224
/**
 
225
  This is mainly needed when running with purify, but it's still nice to
 
226
  know that all child threads have died when drizzled exits.
 
227
*/
 
228
static int deinit(PluginRegistry&)
 
229
{
 
230
  uint32_t i;
 
231
  /*
 
232
    Wait up to 10 seconds for signal thread to die. We use this mainly to
 
233
    avoid getting warnings that my_thread_end has not been called
245
234
  */
246
 
  ~SignalHandler()
 
235
  for (i= 0 ; i < 100 && signal_thread_in_use; i++)
247
236
  {
248
 
    uint32_t i;
249
 
    /*
250
 
      Wait up to 10 seconds for signal thread to die. We use this mainly to
251
 
      avoid getting warnings that internal::my_thread_end has not been called
252
 
    */
253
 
    for (i= 0 ; i < 100 && signal_thread_in_use; i++)
254
 
    {
255
 
      if (pthread_kill(signal_thread, SIGTERM) != ESRCH)
256
 
        break;
257
 
      usleep(100);                              // Give it time to die
258
 
    }
259
 
 
 
237
    if (pthread_kill(signal_thread, SIGTERM) != ESRCH)
 
238
      break;
 
239
    usleep(100);                                // Give it time to die
260
240
  }
261
 
};
262
241
 
263
 
static int init(drizzled::plugin::Context& context)
264
 
{
265
 
  SignalHandler *handler= new SignalHandler;
266
 
  context.add(handler);
267
242
  return 0;
268
243
}
269
244
 
270
 
 
271
 
static drizzle_sys_var* system_variables[]= {
 
245
static struct st_mysql_sys_var* system_variables[]= {
272
246
  NULL
273
247
};
274
248
 
275
 
DRIZZLE_DECLARE_PLUGIN
 
249
drizzle_declare_plugin(signal_handler)
276
250
{
277
 
  DRIZZLE_VERSION_ID,
278
251
  "signal_handler",
279
252
  "0.1",
280
253
  "Brian Aker",
281
254
  "Default Signal Handler",
282
255
  PLUGIN_LICENSE_GPL,
283
256
  init, /* Plugin Init */
 
257
  deinit, /* Plugin Deinit */
 
258
  NULL,   /* status variables */
284
259
  system_variables,   /* system variables */
285
260
  NULL    /* config options */
286
261
}
287
 
DRIZZLE_DECLARE_PLUGIN_END;
 
262
drizzle_declare_plugin_end;