From ae862d695b018d99d6f371e5dbae125c02edcd07 Mon Sep 17 00:00:00 2001 From: Matthew Horan Date: Sun, 29 Jun 2014 22:53:01 -0400 Subject: [PATCH] Simplify shutdown logic for Connection * Use a QSocketNotifier listening to stdin to determine when the parent process has detached. --- lib/capybara/webkit/connection.rb | 22 +--------------------- spec/connection_spec.rb | 21 +++++++++++++++++++++ src/StdinNotifier.cpp | 16 ++++++++++++++++ src/StdinNotifier.h | 20 ++++++++++++++++++++ src/main.cpp | 4 ++++ src/webkit_server.pro | 6 ++++-- 6 files changed, 66 insertions(+), 23 deletions(-) create mode 100644 src/StdinNotifier.cpp create mode 100644 src/StdinNotifier.h diff --git a/lib/capybara/webkit/connection.rb b/lib/capybara/webkit/connection.rb index f7b7afa..084da11 100644 --- a/lib/capybara/webkit/connection.rb +++ b/lib/capybara/webkit/connection.rb @@ -52,27 +52,7 @@ module Capybara::Webkit end def open_pipe - _, @pipe_stdout, @pipe_stderr, @wait_thr = Open3.popen3(SERVER_PATH) - register_shutdown_hook - end - - def register_shutdown_hook - @owner_pid = Process.pid - at_exit do - if Process.pid == @owner_pid - kill_process - end - end - end - - def kill_process - if RUBY_PLATFORM =~ /mingw32/ - Process.kill(9, @pid) - else - Process.kill("INT", @pid) - end - rescue Errno::ESRCH - # This just means that the webkit_server process has already ended + @pipe_stdin, @pipe_stdout, @pipe_stderr, @wait_thr = Open3.popen3(SERVER_PATH) end def discover_port diff --git a/spec/connection_spec.rb b/spec/connection_spec.rb index 25231e7..6668b14 100644 --- a/spec/connection_spec.rb +++ b/spec/connection_spec.rb @@ -2,6 +2,27 @@ require 'spec_helper' require 'capybara/webkit/connection' describe Capybara::Webkit::Connection do + it "kills the process when the parent process dies", skip_on_windows: true, skip_on_jruby: true do + read_io, write_io = IO.pipe + + fork_pid = fork do + read_io.close + connection = Capybara::Webkit::Connection.new + write_io.write(connection.pid) + write_io.close + Process.wait(connection.pid) + end + + write_io.close + + webkit_pid = read_io.read.to_i + webkit_pid.should be > 1 + read_io.close + Process.kill(9, fork_pid) + sleep 1 + expect { Process.getpgid(webkit_pid) }.to raise_error Errno::ESRCH + end + it "boots a server to talk to" do url = "http://#{@rack_server.host}:#{@rack_server.port}/" connection.puts "Visit" diff --git a/src/StdinNotifier.cpp b/src/StdinNotifier.cpp new file mode 100644 index 0000000..b439402 --- /dev/null +++ b/src/StdinNotifier.cpp @@ -0,0 +1,16 @@ +#include "StdinNotifier.h" + +#include + +StdinNotifier::StdinNotifier(QObject *parent) : QObject(parent) { + m_notifier = new QSocketNotifier(fileno(stdin), QSocketNotifier::Read, this); + connect(m_notifier, SIGNAL(activated(int)), this, SLOT(notifierActivated())); +} + +void StdinNotifier::notifierActivated() { + std::string line; + std::getline(std::cin, line); + if (std::cin.eof()) { + emit eof(); + } +} diff --git a/src/StdinNotifier.h b/src/StdinNotifier.h new file mode 100644 index 0000000..71a6495 --- /dev/null +++ b/src/StdinNotifier.h @@ -0,0 +1,20 @@ +#include + +class QSocketNotifier; + +class StdinNotifier : public QObject { + Q_OBJECT + + public: + StdinNotifier(QObject *parent = 0); + + public slots: + void notifierActivated(); + + signals: + void eof(); + + private: + QSocketNotifier *m_notifier; +}; + diff --git a/src/main.cpp b/src/main.cpp index 6b45867..e38f89e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,6 @@ #include "Server.h" #include "IgnoreDebugOutput.h" +#include "StdinNotifier.h" #include #include #ifdef Q_OS_UNIX @@ -19,6 +20,9 @@ int main(int argc, char **argv) { app.setOrganizationName("thoughtbot, inc"); app.setOrganizationDomain("thoughtbot.com"); + StdinNotifier notifier; + QObject::connect(¬ifier, SIGNAL(eof()), &app, SLOT(quit())); + ignoreDebugOutput(); Server server(0); diff --git a/src/webkit_server.pro b/src/webkit_server.pro index f4c27eb..af90da0 100644 --- a/src/webkit_server.pro +++ b/src/webkit_server.pro @@ -75,7 +75,8 @@ HEADERS = \ JavascriptCommand.h \ FindXpath.h \ NetworkReplyProxy.h \ - IgnoreDebugOutput.h + IgnoreDebugOutput.h \ + StdinNotifier.h SOURCES = \ GoForward.cpp \ @@ -147,7 +148,8 @@ SOURCES = \ JavascriptCommand.cpp \ FindXpath.cpp \ NetworkReplyProxy.cpp \ - IgnoreDebugOutput.cpp + IgnoreDebugOutput.cpp \ + StdinNotifier.cpp RESOURCES = webkit_server.qrc QT += network