summaryrefslogtreecommitdiffstats
path: root/remoting/host/posix
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-17 20:54:46 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-17 20:54:46 +0000
commit5d065d725c8fcf9f2406e2d9c273a917288f09b0 (patch)
tree1f75f039f83cdde0be8db38f471d0f059df7f23b /remoting/host/posix
parent48280439bdbf6ab359ad38c45c94924ab9a9785f (diff)
downloadchromium_src-5d065d725c8fcf9f2406e2d9c273a917288f09b0.zip
chromium_src-5d065d725c8fcf9f2406e2d9c273a917288f09b0.tar.gz
chromium_src-5d065d725c8fcf9f2406e2d9c273a917288f09b0.tar.bz2
Update linux host to handle SIGHUP. Use it to reload config.
Also updated me2me_virtual_host.py to use that signal to reload config (instead of restarting the host), and when requesting the currently running instance of the script to reload the config (instead of SIGUSR1). BUG=120950 Review URL: https://chromiumcodereview.appspot.com/10825410 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152149 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host/posix')
-rw-r--r--remoting/host/posix/sighup_listener.cc94
-rw-r--r--remoting/host/posix/sighup_listener.h22
2 files changed, 116 insertions, 0 deletions
diff --git a/remoting/host/posix/sighup_listener.cc b/remoting/host/posix/sighup_listener.cc
new file mode 100644
index 0000000..5a4ad07
--- /dev/null
+++ b/remoting/host/posix/sighup_listener.cc
@@ -0,0 +1,94 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// TODO(jamiewalch): Add unit tests for this.
+
+#include "remoting/host/posix/sighup_listener.h"
+
+#include <errno.h>
+#include <signal.h>
+
+#include "base/compiler_specific.h"
+#include "base/eintr_wrapper.h"
+#include "base/message_loop.h"
+#include "base/message_pump_libevent.h"
+#include "base/threading/platform_thread.h"
+
+namespace {
+
+class SigHupListener : public base::MessagePumpLibevent::Watcher {
+ public:
+ SigHupListener(const base::Closure& callback);
+
+ virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
+ virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
+
+ // WatchFileDescriptor needs a controller through which the operation can be
+ // canceled. We don't use it, but this is as good a place as any to store it.
+ base::MessagePumpLibevent::FileDescriptorWatcher controller;
+
+ private:
+ base::Closure callback_;
+};
+
+SigHupListener::SigHupListener(const base::Closure& callback)
+ : callback_(callback) {
+}
+
+void SigHupListener::OnFileCanReadWithoutBlocking(int fd) {
+ char buffer;
+ int result = HANDLE_EINTR(read(fd, &buffer, sizeof(buffer)));
+ if (result > 0) {
+ callback_.Run();
+ }
+}
+
+SigHupListener* g_config_updater = NULL;
+int g_write_fd = 0;
+
+void HupSignalHandler(int signal) {
+ int r ALLOW_UNUSED = write(g_write_fd, "", 1);
+}
+
+} // namespace
+
+namespace remoting {
+
+// RegisterHupSignalHandler registers a signal handler that writes a byte to a
+// pipe each time SIGHUP is received. The read end of the pipe is registered
+// with the current MessageLoop (which must be of type IO); whenever the pipe
+// is readable, it invokes the specified callback.
+//
+// This arrangement is required because the set of system APIs that are safe to
+// call from a singal handler is very limited (but does include write).
+bool RegisterHupSignalHandler(const base::Closure& callback) {
+ DCHECK(!g_config_updater);
+ MessageLoopForIO* message_loop = MessageLoopForIO::current();
+ int pipefd[2];
+ int result = pipe(pipefd);
+ if (result < 0) {
+ LOG(ERROR) << "Could not create SIGHUP pipe: " << errno;
+ return false;
+ }
+ g_write_fd = pipefd[1];
+ g_config_updater = new SigHupListener(callback);
+ result = message_loop->WatchFileDescriptor(
+ pipefd[0], true, MessageLoopForIO::WATCH_READ,
+ &g_config_updater->controller, g_config_updater);
+ if (!result) {
+ delete g_config_updater;
+ g_config_updater = NULL;
+ LOG(ERROR) << "Failed to create SIGHUP detector task.";
+ return false;
+ }
+ if (signal(SIGHUP, HupSignalHandler) == SIG_ERR) {
+ delete g_config_updater;
+ g_config_updater = NULL;
+ LOG(ERROR) << "signal() failed: " << errno;
+ return false;
+ }
+ return true;
+}
+
+} // namespace remoting
diff --git a/remoting/host/posix/sighup_listener.h b/remoting/host/posix/sighup_listener.h
new file mode 100644
index 0000000..48140a3
--- /dev/null
+++ b/remoting/host/posix/sighup_listener.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This file implements a signal handler that is used to safely handle SIGHUP
+// and trigger the specified callback. It is used on Linux and Mac in order to
+// reload the me2me host configuration.
+
+#ifndef REMOTING_HOST_POSIX_SIGHUP_LISTENER_H_
+#define REMOTING_HOST_POSIX_SIGHUP_LISTENER_H_
+
+#include "base/callback_forward.h"
+
+namespace remoting {
+
+// Register for SIGHUP notifications on the current thread, which must have
+// an associated MessageLoopForIO.
+bool RegisterHupSignalHandler(const base::Closure& callback);
+
+} // namespace remoting
+
+#endif // REMOTING_HOST_POSIX_SIGHUP_LISTENER_H_