Simplify shutdown logic for Connection

* Use a QSocketNotifier listening to stdin to determine when the parent
  process has detached.
This commit is contained in:
Matthew Horan 2014-06-29 22:53:01 -04:00 committed by Matthew Horan
parent 259bcd9fd4
commit ae862d695b
6 changed files with 66 additions and 23 deletions

View File

@ -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

View File

@ -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"

16
src/StdinNotifier.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "StdinNotifier.h"
#include <QTcpServer>
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();
}
}

20
src/StdinNotifier.h Normal file
View File

@ -0,0 +1,20 @@
#include <QObject>
class QSocketNotifier;
class StdinNotifier : public QObject {
Q_OBJECT
public:
StdinNotifier(QObject *parent = 0);
public slots:
void notifierActivated();
signals:
void eof();
private:
QSocketNotifier *m_notifier;
};

View File

@ -1,5 +1,6 @@
#include "Server.h"
#include "IgnoreDebugOutput.h"
#include "StdinNotifier.h"
#include <QApplication>
#include <iostream>
#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(&notifier, SIGNAL(eof()), &app, SLOT(quit()));
ignoreDebugOutput();
Server server(0);

View File

@ -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