diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-17 20:54:46 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-17 20:54:46 +0000 |
commit | 5d065d725c8fcf9f2406e2d9c273a917288f09b0 (patch) | |
tree | 1f75f039f83cdde0be8db38f471d0f059df7f23b /remoting/host/posix | |
parent | 48280439bdbf6ab359ad38c45c94924ab9a9785f (diff) | |
download | chromium_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.cc | 94 | ||||
-rw-r--r-- | remoting/host/posix/sighup_listener.h | 22 |
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_ |