~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/signal_handler/signal_handler.cc

  • Committer: Brian Aker
  • Date: 2010-09-20 22:38:01 UTC
  • mto: This revision was merged to the branch mainline in revision 1781.
  • Revision ID: brian@gir-3-20100920223801-9vyiyulal1op0hnx
Fix issue with signal thread not shutting down (OSX). 

Show diffs side-by-side

added added

removed removed

Lines of Context:
124
124
  }
125
125
  (void) sigemptyset(&set);                     // Setup up SIGINT for debug
126
126
#ifndef IGNORE_SIGHUP_SIGQUIT
127
 
  (void) sigaddset(&set,SIGQUIT);
128
 
  (void) sigaddset(&set,SIGHUP);
 
127
  if (sigaddset(&set,SIGQUIT))
 
128
  {
 
129
    std::cerr << "failed setting sigaddset() with SIGQUIT\n";
 
130
  }
 
131
  if (sigaddset(&set,SIGHUP))
 
132
  {
 
133
    std::cerr << "failed setting sigaddset() with SIGHUP\n";
 
134
  }
129
135
#endif
130
 
  (void) sigaddset(&set,SIGTERM);
131
 
  (void) sigaddset(&set,SIGTSTP);
 
136
  if (sigaddset(&set,SIGTERM))
 
137
  {
 
138
    std::cerr << "failed setting sigaddset() with SIGTERM\n";
 
139
  }
 
140
  if (sigaddset(&set,SIGTSTP))
 
141
  {
 
142
    std::cerr << "failed setting sigaddset() with SIGTSTP\n";
 
143
  }
132
144
 
133
145
  /* Save pid to this process (or thread on Linux) */
134
146
  create_pid_file();
149
161
  LOCK_thread_count.unlock();
150
162
  COND_thread_count.notify_all();
151
163
 
152
 
  (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
 
164
  if (pthread_sigmask(SIG_BLOCK, &set, NULL))
 
165
  {
 
166
    std::cerr << "Failed to set pthread_sigmask() in signal handler\n";
 
167
  }
 
168
 
153
169
  for (;;)
154
170
  {
155
171
    int error;                                  // Used when debugging
161
177
    }
162
178
    else
163
179
    {
164
 
      while ((error= sigwait(&set,&sig)) == EINTR) ;
 
180
      while ((error= sigwait(&set, &sig)) == EINTR) ;
165
181
    }
166
182
 
167
183
    if (cleanup_done)
175
191
    case SIGTERM:
176
192
    case SIGQUIT:
177
193
    case SIGKILL:
 
194
    case SIGTSTP:
178
195
      /* switch to the old log message processing */
179
196
      if (!abort_loop)
180
197
      {
223
240
      Wait up to 100000 micro-seconds for signal thread to die. We use this mainly to
224
241
      avoid getting warnings that internal::my_thread_end has not been called
225
242
    */
226
 
    pthread_kill(signal_thread, SIGTERM);
227
 
    thread.join();
 
243
    bool completed= false;
 
244
    /*
 
245
     * We send SIGTERM and then do a timed join. If that fails we will on
 
246
     * the last pthread_kill() call SIGTSTP. OSX (and FreeBSD) seem to
 
247
     * prefer this. -Brian
 
248
   */
 
249
    uint32_t count= 2; // How many times to try join and see if the caller died.
 
250
    while (not completed and count--)
 
251
    {
 
252
      int error;
 
253
      int signal= count == 1 ? SIGTSTP : SIGTERM;
 
254
      
 
255
      if ((error= pthread_kill(thread.native_handle(), signal)))
 
256
      {
 
257
        char buffer[1024]; // No reason for number;
 
258
        strerror_r(error, buffer, sizeof(buffer));
 
259
        std::cerr << "pthread_kill() error on shutdown of signal thread (" << buffer << ")\n";
 
260
        break;
 
261
      }
 
262
      else
 
263
      {
 
264
        boost::posix_time::milliseconds duration(100);
 
265
        completed= thread.timed_join(duration);
 
266
      }
 
267
    }
228
268
  }
229
269
};
230
270