Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Handle signals during shutdown properly

  • Loading branch information...
commit b388d90a063e6da3e4bc6d84e225378be0945d82 1 parent 358f819
@evanphx evanphx authored
View
8 vm/environment.cpp
@@ -108,6 +108,8 @@ namespace rubinius {
}
Environment::~Environment() {
+ delete sig_handler_;
+
VM::discard(state, root_vm);
SharedState::discard(shared);
delete state;
@@ -274,9 +276,9 @@ namespace rubinius {
#endif
state->vm()->set_run_signals(true);
- SignalHandler* handler = new SignalHandler(state);
- shared->set_signal_handler(handler);
- handler->run(state);
+ sig_handler_ = new SignalHandler(state);
+ shared->set_signal_handler(sig_handler_);
+ sig_handler_->run(state);
#ifndef RBX_WINDOWS
// Ignore sigpipe.
View
3  vm/environment.hpp
@@ -12,6 +12,7 @@ namespace rubinius {
class ConfigParser;
class QueryAgent;
+ class SignalHandler;
/**
* Thrown when there is a bad signature on a kernel .rbc file.
@@ -44,6 +45,8 @@ namespace rubinius {
// The Ruby library version with which the .rbc file is compatible.
int version_;
+ SignalHandler* sig_handler_;
+
public:
SharedState* shared;
VM* root_vm;
View
26 vm/signal.cpp
@@ -77,10 +77,20 @@ namespace rubinius {
}
void SignalHandler::shutdown() {
- if(handler_) handler_->shutdown_i();
+ if(handler_) {
+ handler_->shutdown_i();
+ handler_ = 0;
+ }
}
void SignalHandler::shutdown_i() {
+ for(std::list<int>::iterator i = watched_signals_.begin();
+ i != watched_signals_.end();
+ ++i)
+ {
+ signal(*i, SIG_DFL);
+ }
+
pthread_t os = self_->os_thread();
exit_ = true;
@@ -148,19 +158,14 @@ namespace rubinius {
}
void SignalHandler::handle_signal(int sig) {
+ if(exit_) return;
+
queued_signals_ = 1;
pending_signals_[sig] = 1;
- // If the main thread is running, just tell it that
- // there are local interrupts waiting.
- if(!target_->waiting_p()) {
- target_->check_local_interrupts = true;
- return;
- }
+ target_->check_local_interrupts = true;
if(target_->should_interrupt_with_signal()) {
- target_->check_local_interrupts = true;
-
if(!pthread_equal(pthread_self(), main_thread)) {
#ifdef RBX_WINDOWS
// TODO: Windows
@@ -189,10 +194,13 @@ namespace rubinius {
if(type == eDefault) {
action.sa_handler = SIG_DFL;
+ watched_signals_.remove(sig);
} else if(type == eIgnore) {
action.sa_handler = SIG_IGN;
+ watched_signals_.push_back(sig);
} else {
action.sa_handler = signal_tramp;
+ watched_signals_.push_back(sig);
}
action.sa_flags = 0;
View
2  vm/signal.hpp
@@ -26,6 +26,8 @@ namespace rubinius {
TypedRoot<Thread*> thread_;
+ std::list<int> watched_signals_;
+
public:
enum HandlerType {
eDefault,
Please sign in to comment.
Something went wrong with that request. Please try again.