Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: remoting/host/posix/signal_handler.cc

Issue 10905081: Pass Me2Me config via stdin. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Delete debugging and clean up comments. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // TODO(jamiewalch): Add unit tests for this.
6
7 #include "remoting/host/posix/signal_handler.h"
8
9 #include <list>
Lambros 2012/09/05 16:35:54 nit: C++ after C headers And #include <utility> fo
Jamie 2012/09/05 21:15:38 Done.
10
11 #include <errno.h>
12 #include <signal.h>
13
14 #include "base/compiler_specific.h"
15 #include "base/eintr_wrapper.h"
16 #include "base/message_loop.h"
17 #include "base/message_pump_libevent.h"
18 #include "base/threading/platform_thread.h"
19
20 namespace remoting {
21 namespace {
22
23 class SignalListener : public base::MessagePumpLibevent::Watcher {
24 public:
25 SignalListener();
26
27 void AddSignalHandler(int signal, const SignalHandler& handler);
28
29 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
30 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
31
32 // WatchFileDescriptor needs a controller through which the operation can be
33 // canceled. We don't use it, but this is as good a place as any to store it.
34 base::MessagePumpLibevent::FileDescriptorWatcher controller;
35
36 private:
37 typedef std::pair<int, SignalHandler> SignalAndHandler;
38 typedef std::list<SignalAndHandler> SignalHandlers;
Lambros 2012/09/05 16:35:54 std::multimap would make the code slightly shorter
Jamie 2012/09/05 21:15:38 I think I'll stick with list. multimap is not wide
39 SignalHandlers signal_handlers_;
40 };
41
42 SignalListener::SignalListener() {
43 }
44
45 void SignalListener::AddSignalHandler(int signal,
46 const SignalHandler& handler) {
47 signal_handlers_.push_back(SignalAndHandler(signal, handler));
48 }
49
50 void SignalListener::OnFileCanReadWithoutBlocking(int fd) {
51 char buffer;
52 int result = HANDLE_EINTR(read(fd, &buffer, sizeof(buffer)));
53 if (result > 0) {
54 for (SignalHandlers::const_iterator i = signal_handlers_.begin();
55 i != signal_handlers_.end();
56 ++i) {
57 if (i->first == buffer) {
58 i->second.Run(i->first);
59 }
60 }
61 }
62 }
63
64 SignalListener* g_signal_listener = NULL;
65 int g_write_fd = 0;
66
67 void GlobalSignalHandler(int signal) {
68 char byte = signal;
69 int r ALLOW_UNUSED = write(g_write_fd, &byte, 1);
70 }
71
72 } // namespace
73
74 // RegisterSignalHandler registers a signal handler that writes a byte to a
75 // pipe each time a signal is received. The read end of the pipe is registered
76 // with the current MessageLoop (which must be of type IO); whenever the pipe
77 // is readable, it invokes the specified callback.
78 //
79 // This arrangement is required because the set of system APIs that are safe to
80 // call from a signal handler is very limited (but does include write).
81 bool RegisterSignalHandler(int signum, const SignalHandler& handler) {
82 CHECK(signum < 256); // Don't want to worry about multi-byte writes.
83 if (!g_signal_listener) {
84 g_signal_listener = new SignalListener();
85 MessageLoopForIO* message_loop = MessageLoopForIO::current();
86 int pipefd[2];
87 int result = pipe(pipefd);
88 if (result < 0) {
89 LOG(ERROR) << "Could not create signal pipe: " << errno;
90 return false;
91 }
92 g_write_fd = pipefd[1];
93 result = message_loop->WatchFileDescriptor(
94 pipefd[0], true, MessageLoopForIO::WATCH_READ,
95 &g_signal_listener->controller, g_signal_listener);
96 if (!result) {
97 delete g_signal_listener;
98 g_signal_listener = NULL;
99 LOG(ERROR) << "Failed to create signal detector task.";
100 return false;
101 }
102 }
103 if (signal(signum, GlobalSignalHandler) == SIG_ERR) {
104 LOG(ERROR) << "signal() failed: " << errno;
105 return false;
106 }
107 g_signal_listener->AddSignalHandler(signum, handler);
108 return true;
109 }
110
111 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698