OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/test/spawned_test_server/local_test_server.h" | 5 #include "net/test/spawned_test_server/local_test_server.h" |
6 | 6 |
7 #include <poll.h> | 7 #include <poll.h> |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 11 matching lines...) Expand all Loading... |
22 | 22 |
23 namespace { | 23 namespace { |
24 | 24 |
25 // Helper class used to detect and kill orphaned python test server processes. | 25 // Helper class used to detect and kill orphaned python test server processes. |
26 // Checks if the command line of a process contains |path_string| (the path | 26 // Checks if the command line of a process contains |path_string| (the path |
27 // from which the test server was launched) and |port_string| (the port used by | 27 // from which the test server was launched) and |port_string| (the port used by |
28 // the test server), and if the parent pid of the process is 1 (indicating that | 28 // the test server), and if the parent pid of the process is 1 (indicating that |
29 // it is an orphaned process). | 29 // it is an orphaned process). |
30 class OrphanedTestServerFilter : public base::ProcessFilter { | 30 class OrphanedTestServerFilter : public base::ProcessFilter { |
31 public: | 31 public: |
32 OrphanedTestServerFilter( | 32 OrphanedTestServerFilter(const std::string& path_string, |
33 const std::string& path_string, const std::string& port_string) | 33 const std::string& port_string) |
34 : path_string_(path_string), | 34 : path_string_(path_string), port_string_(port_string) {} |
35 port_string_(port_string) {} | |
36 | 35 |
37 virtual bool Includes(const base::ProcessEntry& entry) const OVERRIDE { | 36 virtual bool Includes(const base::ProcessEntry& entry) const OVERRIDE { |
38 if (entry.parent_pid() != 1) | 37 if (entry.parent_pid() != 1) |
39 return false; | 38 return false; |
40 bool found_path_string = false; | 39 bool found_path_string = false; |
41 bool found_port_string = false; | 40 bool found_port_string = false; |
42 for (std::vector<std::string>::const_iterator it = | 41 for (std::vector<std::string>::const_iterator it = |
43 entry.cmd_line_args().begin(); | 42 entry.cmd_line_args().begin(); |
44 it != entry.cmd_line_args().end(); | 43 it != entry.cmd_line_args().end(); |
45 ++it) { | 44 ++it) { |
46 if (it->find(path_string_) != std::string::npos) | 45 if (it->find(path_string_) != std::string::npos) |
47 found_path_string = true; | 46 found_path_string = true; |
48 if (it->find(port_string_) != std::string::npos) | 47 if (it->find(port_string_) != std::string::npos) |
49 found_port_string = true; | 48 found_port_string = true; |
50 } | 49 } |
51 return found_path_string && found_port_string; | 50 return found_path_string && found_port_string; |
52 } | 51 } |
53 | 52 |
54 private: | 53 private: |
55 std::string path_string_; | 54 std::string path_string_; |
56 std::string port_string_; | 55 std::string port_string_; |
57 DISALLOW_COPY_AND_ASSIGN(OrphanedTestServerFilter); | 56 DISALLOW_COPY_AND_ASSIGN(OrphanedTestServerFilter); |
58 }; | 57 }; |
59 | 58 |
60 // Given a file descriptor, reads into |buffer| until |bytes_max| | 59 // Given a file descriptor, reads into |buffer| until |bytes_max| |
61 // bytes has been read or an error has been encountered. Returns true | 60 // bytes has been read or an error has been encountered. Returns true |
62 // if the read was successful. |remaining_time| is used as a timeout. | 61 // if the read was successful. |remaining_time| is used as a timeout. |
63 bool ReadData(int fd, ssize_t bytes_max, uint8* buffer, | 62 bool ReadData(int fd, |
| 63 ssize_t bytes_max, |
| 64 uint8* buffer, |
64 base::TimeDelta* remaining_time) { | 65 base::TimeDelta* remaining_time) { |
65 ssize_t bytes_read = 0; | 66 ssize_t bytes_read = 0; |
66 base::TimeTicks previous_time = base::TimeTicks::Now(); | 67 base::TimeTicks previous_time = base::TimeTicks::Now(); |
67 while (bytes_read < bytes_max) { | 68 while (bytes_read < bytes_max) { |
68 struct pollfd poll_fds[1]; | 69 struct pollfd poll_fds[1]; |
69 | 70 |
70 poll_fds[0].fd = fd; | 71 poll_fds[0].fd = fd; |
71 poll_fds[0].events = POLLIN | POLLPRI; | 72 poll_fds[0].events = POLLIN | POLLPRI; |
72 poll_fds[0].revents = 0; | 73 poll_fds[0].revents = 0; |
73 | 74 |
74 int rv = HANDLE_EINTR(poll(poll_fds, 1, | 75 int rv = HANDLE_EINTR(poll(poll_fds, 1, remaining_time->InMilliseconds())); |
75 remaining_time->InMilliseconds())); | |
76 if (rv == 0) { | 76 if (rv == 0) { |
77 LOG(ERROR) << "poll() timed out; bytes_read=" << bytes_read; | 77 LOG(ERROR) << "poll() timed out; bytes_read=" << bytes_read; |
78 return false; | 78 return false; |
79 } else if (rv < 0) { | 79 } else if (rv < 0) { |
80 PLOG(ERROR) << "poll() failed for child file descriptor; bytes_read=" | 80 PLOG(ERROR) << "poll() failed for child file descriptor; bytes_read=" |
81 << bytes_read; | 81 << bytes_read; |
82 return false; | 82 return false; |
83 } | 83 } |
84 | 84 |
85 base::TimeTicks current_time = base::TimeTicks::Now(); | 85 base::TimeTicks current_time = base::TimeTicks::Now(); |
86 base::TimeDelta elapsed_time_cycle = current_time - previous_time; | 86 base::TimeDelta elapsed_time_cycle = current_time - previous_time; |
87 DCHECK_GE(elapsed_time_cycle.InMilliseconds(), 0); | 87 DCHECK_GE(elapsed_time_cycle.InMilliseconds(), 0); |
88 *remaining_time -= elapsed_time_cycle; | 88 *remaining_time -= elapsed_time_cycle; |
89 previous_time = current_time; | 89 previous_time = current_time; |
90 | 90 |
91 ssize_t num_bytes = HANDLE_EINTR(read(fd, buffer + bytes_read, | 91 ssize_t num_bytes = |
92 bytes_max - bytes_read)); | 92 HANDLE_EINTR(read(fd, buffer + bytes_read, bytes_max - bytes_read)); |
93 if (num_bytes <= 0) | 93 if (num_bytes <= 0) |
94 return false; | 94 return false; |
95 bytes_read += num_bytes; | 95 bytes_read += num_bytes; |
96 } | 96 } |
97 return true; | 97 return true; |
98 } | 98 } |
99 | 99 |
100 } // namespace | 100 } // namespace |
101 | 101 |
102 namespace net { | 102 namespace net { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 | 146 |
147 return true; | 147 return true; |
148 } | 148 } |
149 | 149 |
150 bool LocalTestServer::WaitToStart() { | 150 bool LocalTestServer::WaitToStart() { |
151 base::ScopedFD our_fd(child_fd_.release()); | 151 base::ScopedFD our_fd(child_fd_.release()); |
152 | 152 |
153 base::TimeDelta remaining_time = TestTimeouts::action_timeout(); | 153 base::TimeDelta remaining_time = TestTimeouts::action_timeout(); |
154 | 154 |
155 uint32 server_data_len = 0; | 155 uint32 server_data_len = 0; |
156 if (!ReadData(our_fd.get(), sizeof(server_data_len), | 156 if (!ReadData(our_fd.get(), |
| 157 sizeof(server_data_len), |
157 reinterpret_cast<uint8*>(&server_data_len), | 158 reinterpret_cast<uint8*>(&server_data_len), |
158 &remaining_time)) { | 159 &remaining_time)) { |
159 LOG(ERROR) << "Could not read server_data_len"; | 160 LOG(ERROR) << "Could not read server_data_len"; |
160 return false; | 161 return false; |
161 } | 162 } |
162 std::string server_data(server_data_len, '\0'); | 163 std::string server_data(server_data_len, '\0'); |
163 if (!ReadData(our_fd.get(), server_data_len, | 164 if (!ReadData(our_fd.get(), |
| 165 server_data_len, |
164 reinterpret_cast<uint8*>(&server_data[0]), | 166 reinterpret_cast<uint8*>(&server_data[0]), |
165 &remaining_time)) { | 167 &remaining_time)) { |
166 LOG(ERROR) << "Could not read server_data (" << server_data_len | 168 LOG(ERROR) << "Could not read server_data (" << server_data_len |
167 << " bytes)"; | 169 << " bytes)"; |
168 return false; | 170 return false; |
169 } | 171 } |
170 | 172 |
171 if (!ParseServerData(server_data)) { | 173 if (!ParseServerData(server_data)) { |
172 LOG(ERROR) << "Could not parse server_data: " << server_data; | 174 LOG(ERROR) << "Could not parse server_data: " << server_data; |
173 return false; | 175 return false; |
174 } | 176 } |
175 | 177 |
176 return true; | 178 return true; |
177 } | 179 } |
178 | 180 |
179 } // namespace net | 181 } // namespace net |
OLD | NEW |