diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-26 03:40:00 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-26 03:40:00 +0000 |
commit | 546e475189122517024ac36599ca9c852b37ca6b (patch) | |
tree | 84f43f4eb069edc511c3459ecd4c1789b4d48977 /net/test | |
parent | 95d6b36ee89809ab261ced025d57405f65adf8d0 (diff) | |
download | chromium_src-546e475189122517024ac36599ca9c852b37ca6b.zip chromium_src-546e475189122517024ac36599ca9c852b37ca6b.tar.gz chromium_src-546e475189122517024ac36599ca9c852b37ca6b.tar.bz2 |
Added ReadData() function to test_server_{posix,win}.cc
This is split off from 5196001.
BUG=53934
TEST=manually
TBR=cbentzel
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67430 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/test')
-rw-r--r-- | net/test/test_server_posix.cc | 76 | ||||
-rw-r--r-- | net/test/test_server_win.cc | 80 |
2 files changed, 92 insertions, 64 deletions
diff --git a/net/test/test_server_posix.cc b/net/test/test_server_posix.cc index 9c0210b..f9c594d 100644 --- a/net/test/test_server_posix.cc +++ b/net/test/test_server_posix.cc @@ -53,6 +53,42 @@ class OrphanedTestServerFilter : public base::ProcessFilter { DISALLOW_COPY_AND_ASSIGN(OrphanedTestServerFilter); }; +// Given a file descriptor, reads into |buffer| until |bytes_max| +// bytes has been read or an error has been encountered. Returns true +// if the read was successful. |remaining_time| is used as a timeout. +bool ReadData(int fd, ssize_t bytes_max, uint8* buffer, + base::TimeDelta* remaining_time) { + ssize_t bytes_read = 0; + base::Time previous_time = base::Time::Now(); + while (bytes_read < bytes_max) { + struct pollfd poll_fds[1]; + + poll_fds[0].fd = fd; + poll_fds[0].events = POLLIN | POLLPRI; + poll_fds[0].revents = 0; + + int rv = HANDLE_EINTR(poll(poll_fds, 1, + remaining_time->InMilliseconds())); + if (rv != 1) { + LOG(ERROR) << "Failed to poll for the child file descriptor."; + return false; + } + + base::Time current_time = base::Time::Now(); + base::TimeDelta elapsed_time_cycle = current_time - previous_time; + DCHECK(elapsed_time_cycle.InMilliseconds() >= 0); + *remaining_time -= elapsed_time_cycle; + previous_time = current_time; + + ssize_t num_bytes = HANDLE_EINTR(read(fd, buffer + bytes_read, + bytes_max - bytes_read)); + if (num_bytes <= 0) + return false; + bytes_read += num_bytes; + } + return true; +} + } // namespace namespace net { @@ -98,43 +134,19 @@ bool TestServer::LaunchPython(const FilePath& testserver_path) { } bool TestServer::WaitToStart() { - uint16 port; - uint8* buffer = reinterpret_cast<uint8*>(&port); - ssize_t bytes_read = 0; - ssize_t bytes_max = sizeof(port); + file_util::ScopedFD child_fd_closer(child_fd_closer_.release()); + base::TimeDelta remaining_time = base::TimeDelta::FromMilliseconds( TestTimeouts::action_max_timeout_ms()); - base::Time previous_time = base::Time::Now(); - while (bytes_read < bytes_max) { - struct pollfd poll_fds[1]; - - poll_fds[0].fd = child_fd_; - poll_fds[0].events = POLLIN | POLLPRI; - poll_fds[0].revents = 0; - - int rv = HANDLE_EINTR(poll(poll_fds, 1, remaining_time.InMilliseconds())); - if (rv != 1) { - LOG(ERROR) << "Failed to poll for the child file descriptor."; - return false; - } - - base::Time current_time = base::Time::Now(); - base::TimeDelta elapsed_time_cycle = current_time - previous_time; - DCHECK(elapsed_time_cycle.InMilliseconds() >= 0); - remaining_time -= elapsed_time_cycle; - previous_time = current_time; - ssize_t num_bytes = HANDLE_EINTR(read(child_fd_, buffer + bytes_read, - bytes_max - bytes_read)); - if (num_bytes <= 0) - break; - bytes_read += num_bytes; + // Try to read two bytes from the pipe indicating the ephemeral port number. + uint16 port = 0; + if (!ReadData(child_fd_, sizeof(port), + reinterpret_cast<uint8*>(&port), &remaining_time)) { + LOG(ERROR) << "Could not read port"; + return false; } - // We don't need the FD anymore. - child_fd_closer_.reset(NULL); - if (bytes_read < bytes_max) - return false; host_port_pair_.set_port(port); return true; } diff --git a/net/test/test_server_win.cc b/net/test/test_server_win.cc index a363755..b5001aa 100644 --- a/net/test/test_server_win.cc +++ b/net/test/test_server_win.cc @@ -80,12 +80,53 @@ void UnblockPipe(HANDLE handle, bool* unblocked) { // Unblock the ReadFile in TestServer::WaitToStart by writing to the pipe. // Make sure the call succeeded, otherwise we are very likely to hang. DWORD bytes_written = 0; + LOG(WARNING) << "Timeout reached; unblocking pipe"; CHECK(WriteFile(handle, kUnblock, arraysize(kUnblock), &bytes_written, NULL)); CHECK_EQ(arraysize(kUnblock), bytes_written); *unblocked = true; } +// Given a file handle, reads into |buffer| until |bytes_max| bytes +// has been read or an error has been encountered. Returns +// true if the read was successful. +bool ReadData(HANDLE read_fd, HANDLE write_fd, + DWORD bytes_max, uint8* buffer) { + base::Thread thread("test_server_watcher"); + if (!thread.Start()) + return false; + + // Prepare a timeout in case the server fails to start. + bool unblocked = false; + thread.message_loop()->PostDelayedTask(FROM_HERE, + NewRunnableFunction(UnblockPipe, write_fd, &unblocked), + TestTimeouts::action_max_timeout_ms()); + + DWORD bytes_read = 0; + while (bytes_read < bytes_max) { + DWORD num_bytes; + if (!ReadFile(read_fd, buffer + bytes_read, bytes_max - bytes_read, + &num_bytes, NULL)) { + PLOG(ERROR) << "ReadFile failed"; + return false; + } + if (num_bytes <= 0) { + LOG(ERROR) << "ReadFile returned invalid byte count: " << num_bytes; + return false; + } + bytes_read += num_bytes; + } + + thread.Stop(); + // If the timeout kicked in, abort. + if (unblocked) { + LOG(ERROR) << "Timeout exceeded for ReadData"; + return false; + } + + return true; +} + } // namespace namespace net { @@ -146,41 +187,16 @@ bool TestServer::LaunchPython(const FilePath& testserver_path) { } bool TestServer::WaitToStart() { - base::Thread thread("test_server_watcher"); - if (!thread.Start()) - return false; - - // Prepare a timeout in case the server fails to start. - bool unblocked = false; - thread.message_loop()->PostDelayedTask(FROM_HERE, - NewRunnableFunction(UnblockPipe, child_write_fd_.Get(), &unblocked), - TestTimeouts::action_max_timeout_ms()); + ScopedHandle read_fd(child_read_fd_.Take()); + ScopedHandle write_fd(child_write_fd_.Take()); // Try to read two bytes from the pipe indicating the ephemeral port number. - uint16 port; - uint8* buffer = reinterpret_cast<uint8*>(&port); - DWORD bytes_read = 0; - DWORD bytes_max = sizeof(port); - while (bytes_read < bytes_max) { - DWORD num_bytes; - if (!ReadFile(child_read_fd_, buffer + bytes_read, bytes_max - bytes_read, - &num_bytes, NULL)) - break; - if (num_bytes <= 0) - break; - bytes_read += num_bytes; - } - thread.Stop(); - child_read_fd_.Close(); - child_write_fd_.Close(); - - // If we hit the timeout, fail. - if (unblocked) - return false; - - // If not enough bytes were read, fail. - if (bytes_read < bytes_max) + uint16 port = 0; + if (!ReadData(read_fd.Get(), write_fd.Get(), sizeof(port), + reinterpret_cast<uint8*>(&port))) { + LOG(ERROR) << "Could not read port"; return false; + } host_port_pair_.set_port(port); return true; |