summaryrefslogtreecommitdiffstats
path: root/mojo/system
diff options
context:
space:
mode:
authorviettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-29 17:30:07 +0000
committerviettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-29 17:30:07 +0000
commit6b120fe6d6e44faea821d7ce4211cca4d146b020 (patch)
tree315b6ffbf83ec87cde66871a6c7ca999051b7dae /mojo/system
parent9783f24f639c94c8c8b3706cba448f872b8a49eb (diff)
downloadchromium_src-6b120fe6d6e44faea821d7ce4211cca4d146b020.zip
chromium_src-6b120fe6d6e44faea821d7ce4211cca4d146b020.tar.gz
chromium_src-6b120fe6d6e44faea821d7ce4211cca4d146b020.tar.bz2
Reland r285211: "Debugging RawChannelWin: replace DCHECK with CHECK and record write stats."
But clang-formatted (and after the changed files were clang-formatted). This should be reverted on the same schedule as the original change (no later than August 1, 2014). > Debugging RawChannelWin: replace DCHECK with CHECK and record write stats. > > This is a temp change for debugging purpose. It should be reverted once > we fix the issue or find out the change doesn't reveal anything. (No later than Aug 1, 2014.) > > BUG=385795 > TEST=None BUG=385795 TBR=yzshen@chromium.org Review URL: https://codereview.chromium.org/430473004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@286239 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/system')
-rw-r--r--mojo/system/raw_channel.cc68
-rw-r--r--mojo/system/raw_channel_win.cc188
2 files changed, 174 insertions, 82 deletions
diff --git a/mojo/system/raw_channel.cc b/mojo/system/raw_channel.cc
index 932f240..e59f161 100644
--- a/mojo/system/raw_channel.cc
+++ b/mojo/system/raw_channel.cc
@@ -30,7 +30,7 @@ RawChannel::ReadBuffer::~ReadBuffer() {
}
void RawChannel::ReadBuffer::GetBuffer(char** addr, size_t* size) {
- DCHECK_GE(buffer_.size(), num_valid_bytes_ + kReadSize);
+ CHECK_GE(buffer_.size(), num_valid_bytes_ + kReadSize);
*addr = &buffer_[0] + num_valid_bytes_;
*size = kReadSize;
}
@@ -59,11 +59,11 @@ bool RawChannel::WriteBuffer::HavePlatformHandlesToSend() const {
const embedder::PlatformHandleVector* all_platform_handles =
transport_data->platform_handles();
if (!all_platform_handles) {
- DCHECK_EQ(platform_handles_offset_, 0u);
+ CHECK_EQ(platform_handles_offset_, 0u);
return false;
}
if (platform_handles_offset_ >= all_platform_handles->size()) {
- DCHECK_EQ(platform_handles_offset_, all_platform_handles->size());
+ CHECK_EQ(platform_handles_offset_, all_platform_handles->size());
return false;
}
@@ -74,7 +74,7 @@ void RawChannel::WriteBuffer::GetPlatformHandlesToSend(
size_t* num_platform_handles,
embedder::PlatformHandle** platform_handles,
void** serialization_data) {
- DCHECK(HavePlatformHandlesToSend());
+ CHECK(HavePlatformHandlesToSend());
TransportData* transport_data = message_queue_.front()->transport_data();
embedder::PlatformHandleVector* all_platform_handles =
@@ -84,7 +84,7 @@ void RawChannel::WriteBuffer::GetPlatformHandlesToSend(
*platform_handles = &(*all_platform_handles)[platform_handles_offset_];
size_t serialization_data_offset =
transport_data->platform_handle_table_offset();
- DCHECK_GT(serialization_data_offset, 0u);
+ CHECK_GT(serialization_data_offset, 0u);
serialization_data_offset +=
platform_handles_offset_ * serialized_platform_handle_size_;
*serialization_data =
@@ -98,7 +98,7 @@ void RawChannel::WriteBuffer::GetBuffers(std::vector<Buffer>* buffers) const {
return;
MessageInTransit* message = message_queue_.front();
- DCHECK_LT(data_offset_, message->total_size());
+ CHECK_LT(data_offset_, message->total_size());
size_t bytes_to_write = message->total_size() - data_offset_;
size_t transport_data_buffer_size =
@@ -106,8 +106,8 @@ void RawChannel::WriteBuffer::GetBuffers(std::vector<Buffer>* buffers) const {
if (!transport_data_buffer_size) {
// Only write from the main buffer.
- DCHECK_LT(data_offset_, message->main_buffer_size());
- DCHECK_LE(bytes_to_write, message->main_buffer_size());
+ CHECK_LT(data_offset_, message->main_buffer_size());
+ CHECK_LE(bytes_to_write, message->main_buffer_size());
Buffer buffer = {
static_cast<const char*>(message->main_buffer()) + data_offset_,
bytes_to_write};
@@ -117,9 +117,9 @@ void RawChannel::WriteBuffer::GetBuffers(std::vector<Buffer>* buffers) const {
if (data_offset_ >= message->main_buffer_size()) {
// Only write from the transport data buffer.
- DCHECK_LT(data_offset_ - message->main_buffer_size(),
- transport_data_buffer_size);
- DCHECK_LE(bytes_to_write, transport_data_buffer_size);
+ CHECK_LT(data_offset_ - message->main_buffer_size(),
+ transport_data_buffer_size);
+ CHECK_LE(bytes_to_write, transport_data_buffer_size);
Buffer buffer = {
static_cast<const char*>(message->transport_data()->buffer()) +
(data_offset_ - message->main_buffer_size()),
@@ -133,7 +133,7 @@ void RawChannel::WriteBuffer::GetBuffers(std::vector<Buffer>* buffers) const {
// attached.
// Write from both buffers.
- DCHECK_EQ(
+ CHECK_EQ(
bytes_to_write,
message->main_buffer_size() - data_offset_ + transport_data_buffer_size);
Buffer buffer1 = {
@@ -157,30 +157,30 @@ RawChannel::RawChannel()
}
RawChannel::~RawChannel() {
- DCHECK(!read_buffer_);
- DCHECK(!write_buffer_);
+ CHECK(!read_buffer_);
+ CHECK(!write_buffer_);
// No need to take the |write_lock_| here -- if there are still weak pointers
// outstanding, then we're hosed anyway (since we wouldn't be able to
// invalidate them cleanly, since we might not be on the I/O thread).
- DCHECK(!weak_ptr_factory_.HasWeakPtrs());
+ CHECK(!weak_ptr_factory_.HasWeakPtrs());
}
bool RawChannel::Init(Delegate* delegate) {
- DCHECK(delegate);
+ CHECK(delegate);
- DCHECK(!delegate_);
+ CHECK(!delegate_);
delegate_ = delegate;
CHECK_EQ(base::MessageLoop::current()->type(), base::MessageLoop::TYPE_IO);
- DCHECK(!message_loop_for_io_);
+ CHECK(!message_loop_for_io_);
message_loop_for_io_ =
static_cast<base::MessageLoopForIO*>(base::MessageLoop::current());
// No need to take the lock. No one should be using us yet.
- DCHECK(!read_buffer_);
+ CHECK(!read_buffer_);
read_buffer_.reset(new ReadBuffer);
- DCHECK(!write_buffer_);
+ CHECK(!write_buffer_);
write_buffer_.reset(new WriteBuffer(GetSerializedPlatformHandleSize()));
if (!OnInit()) {
@@ -207,7 +207,7 @@ bool RawChannel::Init(Delegate* delegate) {
}
void RawChannel::Shutdown() {
- DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
+ CHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
base::AutoLock locker(write_lock_);
@@ -225,7 +225,7 @@ void RawChannel::Shutdown() {
// Reminder: This must be thread-safe.
bool RawChannel::WriteMessage(scoped_ptr<MessageInTransit> message) {
- DCHECK(message);
+ CHECK(message);
base::AutoLock locker(write_lock_);
if (write_stopped_)
@@ -237,7 +237,7 @@ bool RawChannel::WriteMessage(scoped_ptr<MessageInTransit> message) {
}
EnqueueMessageNoLock(message.Pass());
- DCHECK_EQ(write_buffer_->data_offset_, 0u);
+ CHECK_EQ(write_buffer_->data_offset_, 0u);
size_t platform_handles_written = 0;
size_t bytes_written = 0;
@@ -266,7 +266,7 @@ bool RawChannel::IsWriteBufferEmpty() {
}
void RawChannel::OnReadCompleted(bool result, size_t bytes_read) {
- DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
+ CHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
if (read_stopped_) {
NOTREACHED();
@@ -310,12 +310,12 @@ void RawChannel::OnReadCompleted(bool result, size_t bytes_read) {
remaining_bytes >= message_size) {
MessageInTransit::View message_view(
message_size, &read_buffer_->buffer_[read_buffer_start]);
- DCHECK_EQ(message_view.total_size(), message_size);
+ CHECK_EQ(message_view.total_size(), message_size);
const char* error_message = NULL;
if (!message_view.IsValid(GetSerializedPlatformHandleSize(),
&error_message)) {
- DCHECK(error_message);
+ CHECK(error_message);
LOG(WARNING) << "Received invalid message: " << error_message;
read_stopped_ = true;
CallOnFatalError(Delegate::FATAL_ERROR_READ);
@@ -355,7 +355,7 @@ void RawChannel::OnReadCompleted(bool result, size_t bytes_read) {
// for the POSIX implementation, we should confirm that none are stored.
// Dispatch the message.
- DCHECK(delegate_);
+ CHECK(delegate_);
delegate_->OnReadMessage(message_view, platform_handles.Pass());
if (read_stopped_) {
// |Shutdown()| was called in |OnReadMessage()|.
@@ -413,12 +413,12 @@ void RawChannel::OnReadCompleted(bool result, size_t bytes_read) {
void RawChannel::OnWriteCompleted(bool result,
size_t platform_handles_written,
size_t bytes_written) {
- DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
+ CHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
bool did_fail = false;
{
base::AutoLock locker(write_lock_);
- DCHECK_EQ(write_stopped_, write_buffer_->message_queue_.empty());
+ CHECK_EQ(write_stopped_, write_buffer_->message_queue_.empty());
if (write_stopped_) {
NOTREACHED();
@@ -447,7 +447,7 @@ bool RawChannel::OnReadMessageForRawChannel(
}
void RawChannel::CallOnFatalError(Delegate::FatalError fatal_error) {
- DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
+ CHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
// TODO(vtl): Add a "write_lock_.AssertNotAcquired()"?
if (delegate_)
delegate_->OnFatalError(fatal_error);
@@ -458,8 +458,8 @@ bool RawChannel::OnWriteCompletedNoLock(bool result,
size_t bytes_written) {
write_lock_.AssertAcquired();
- DCHECK(!write_stopped_);
- DCHECK(!write_buffer_->message_queue_.empty());
+ CHECK(!write_stopped_);
+ CHECK(!write_buffer_->message_queue_.empty());
if (result) {
write_buffer_->platform_handles_offset_ += platform_handles_written;
@@ -468,7 +468,7 @@ bool RawChannel::OnWriteCompletedNoLock(bool result,
MessageInTransit* message = write_buffer_->message_queue_.front();
if (write_buffer_->data_offset_ >= message->total_size()) {
// Complete write.
- DCHECK_EQ(write_buffer_->data_offset_, message->total_size());
+ CHECK_EQ(write_buffer_->data_offset_, message->total_size());
write_buffer_->message_queue_.pop_front();
delete message;
write_buffer_->platform_handles_offset_ = 0;
@@ -482,7 +482,7 @@ bool RawChannel::OnWriteCompletedNoLock(bool result,
IOResult io_result = ScheduleWriteNoLock();
if (io_result == IO_PENDING)
return true;
- DCHECK_EQ(io_result, IO_FAILED);
+ CHECK_EQ(io_result, IO_FAILED);
}
write_stopped_ = true;
diff --git a/mojo/system/raw_channel_win.cc b/mojo/system/raw_channel_win.cc
index fee6c86..5dcb418 100644
--- a/mojo/system/raw_channel_win.cc
+++ b/mojo/system/raw_channel_win.cc
@@ -9,6 +9,7 @@
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
+#include "base/debug/alias.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
@@ -88,6 +89,30 @@ class RawChannelWin : public RawChannel {
// - there is no pending write.
class RawChannelIOHandler : public base::MessageLoopForIO::IOHandler {
public:
+ // TODO(yzshen): This is for debugging http://crbug.com/385795.
+ // This code should be removed once the issue is fixed or nothing is
+ // revealed by it. (No later than Aug 1, 2014.)
+ struct WriteStats {
+ WriteStats()
+ : write_no_lock_call(0),
+ schedule_write_no_lock_call(0),
+ os_write_call(0),
+ os_write_pending(0),
+ os_write_failure(0),
+ task_posted_by_schedule_write(0),
+ write_completion(0),
+ write_completion_failure(0) {}
+
+ uint32_t write_no_lock_call;
+ uint32_t schedule_write_no_lock_call;
+ uint32_t os_write_call;
+ uint32_t os_write_pending;
+ uint32_t os_write_failure;
+ uint32_t task_posted_by_schedule_write;
+ uint32_t write_completion;
+ uint32_t write_completion_failure;
+ };
+
RawChannelIOHandler(RawChannelWin* owner,
embedder::ScopedPlatformHandle handle);
@@ -105,6 +130,7 @@ class RawChannelWin : public RawChannel {
base::MessageLoopForIO::IOContext* write_context_no_lock();
// Instructs the object to wait for an |OnIOCompleted()| notification.
void OnPendingWriteStartedNoLock();
+ WriteStats* write_stats_no_lock();
// |base::MessageLoopForIO::IOHandler| implementation:
// Must be called on the I/O thread. It could be called before or after
@@ -156,6 +182,8 @@ class RawChannelWin : public RawChannel {
bool pending_write_;
base::MessageLoopForIO::IOContext write_context_;
+ WriteStats write_stats_;
+
DISALLOW_COPY_AND_ASSIGN(RawChannelIOHandler);
};
@@ -199,55 +227,74 @@ RawChannelWin::RawChannelIOHandler::RawChannelIOHandler(
}
RawChannelWin::RawChannelIOHandler::~RawChannelIOHandler() {
- DCHECK(ShouldSelfDestruct());
+ CHECK(ShouldSelfDestruct());
+
+ VLOG(4) << "write_no_lock_call: " << write_stats_.write_no_lock_call << "\n"
+ << "schedule_write_no_lock_call: "
+ << write_stats_.schedule_write_no_lock_call << "\n"
+ << "os_write_call: " << write_stats_.os_write_call << "\n"
+ << "os_write_pending: " << write_stats_.os_write_pending << "\n"
+ << "os_write_failure: " << write_stats_.os_write_failure << "\n"
+ << "task_posted_by_schedule_write: "
+ << write_stats_.task_posted_by_schedule_write << "\n"
+ << "write_completion: " << write_stats_.write_completion << "\n"
+ << "write_completion_failure: "
+ << write_stats_.write_completion_failure << "\n";
}
bool RawChannelWin::RawChannelIOHandler::pending_read() const {
- DCHECK(owner_);
- DCHECK_EQ(base::MessageLoop::current(), owner_->message_loop_for_io());
+ CHECK(owner_);
+ CHECK_EQ(base::MessageLoop::current(), owner_->message_loop_for_io());
return pending_read_;
}
base::MessageLoopForIO::IOContext*
RawChannelWin::RawChannelIOHandler::read_context() {
- DCHECK(owner_);
- DCHECK_EQ(base::MessageLoop::current(), owner_->message_loop_for_io());
+ CHECK(owner_);
+ CHECK_EQ(base::MessageLoop::current(), owner_->message_loop_for_io());
return &read_context_;
}
void RawChannelWin::RawChannelIOHandler::OnPendingReadStarted() {
- DCHECK(owner_);
- DCHECK_EQ(base::MessageLoop::current(), owner_->message_loop_for_io());
- DCHECK(!pending_read_);
+ CHECK(owner_);
+ CHECK_EQ(base::MessageLoop::current(), owner_->message_loop_for_io());
+ CHECK(!pending_read_);
pending_read_ = true;
}
bool RawChannelWin::RawChannelIOHandler::pending_write_no_lock() const {
- DCHECK(owner_);
+ CHECK(owner_);
owner_->write_lock().AssertAcquired();
return pending_write_;
}
base::MessageLoopForIO::IOContext*
RawChannelWin::RawChannelIOHandler::write_context_no_lock() {
- DCHECK(owner_);
+ CHECK(owner_);
owner_->write_lock().AssertAcquired();
return &write_context_;
}
void RawChannelWin::RawChannelIOHandler::OnPendingWriteStartedNoLock() {
- DCHECK(owner_);
+ CHECK(owner_);
owner_->write_lock().AssertAcquired();
- DCHECK(!pending_write_);
+ CHECK(!pending_write_);
pending_write_ = true;
}
+RawChannelWin::RawChannelIOHandler::WriteStats*
+RawChannelWin::RawChannelIOHandler::write_stats_no_lock() {
+ CHECK(owner_);
+ owner_->write_lock().AssertAcquired();
+ return &write_stats_;
+}
+
void RawChannelWin::RawChannelIOHandler::OnIOCompleted(
base::MessageLoopForIO::IOContext* context,
DWORD bytes_transferred,
DWORD error) {
- DCHECK(!owner_ ||
- base::MessageLoop::current() == owner_->message_loop_for_io());
+ CHECK(!owner_ ||
+ base::MessageLoop::current() == owner_->message_loop_for_io());
{
// Suppress self-destruction inside |OnReadCompleted()|, etc. (in case they
@@ -269,8 +316,8 @@ void RawChannelWin::RawChannelIOHandler::OnIOCompleted(
void RawChannelWin::RawChannelIOHandler::DetachFromOwnerNoLock(
scoped_ptr<ReadBuffer> read_buffer,
scoped_ptr<WriteBuffer> write_buffer) {
- DCHECK(owner_);
- DCHECK_EQ(base::MessageLoop::current(), owner_->message_loop_for_io());
+ CHECK(owner_);
+ CHECK_EQ(base::MessageLoop::current(), owner_->message_loop_for_io());
owner_->write_lock().AssertAcquired();
// If read/write is pending, we have to retain the corresponding buffer.
@@ -294,9 +341,9 @@ bool RawChannelWin::RawChannelIOHandler::ShouldSelfDestruct() const {
void RawChannelWin::RawChannelIOHandler::OnReadCompleted(DWORD bytes_read,
DWORD error) {
- DCHECK(!owner_ ||
- base::MessageLoop::current() == owner_->message_loop_for_io());
- DCHECK(suppress_self_destruct_);
+ CHECK(!owner_ ||
+ base::MessageLoop::current() == owner_->message_loop_for_io());
+ CHECK(suppress_self_destruct_);
CHECK(pending_read_);
pending_read_ = false;
@@ -304,24 +351,33 @@ void RawChannelWin::RawChannelIOHandler::OnReadCompleted(DWORD bytes_read,
return;
if (error != ERROR_SUCCESS) {
- DCHECK_EQ(bytes_read, 0u);
+ CHECK_EQ(bytes_read, 0u);
LOG_IF(ERROR, error != ERROR_BROKEN_PIPE)
<< "ReadFile: " << logging::SystemErrorCodeToString(error);
owner_->OnReadCompleted(false, 0);
} else {
- DCHECK_GT(bytes_read, 0u);
+ CHECK_GT(bytes_read, 0u);
owner_->OnReadCompleted(true, bytes_read);
}
}
void RawChannelWin::RawChannelIOHandler::OnWriteCompleted(DWORD bytes_written,
DWORD error) {
- DCHECK(!owner_ ||
- base::MessageLoop::current() == owner_->message_loop_for_io());
- DCHECK(suppress_self_destruct_);
+ CHECK(!owner_ ||
+ base::MessageLoop::current() == owner_->message_loop_for_io());
+ CHECK(suppress_self_destruct_);
+
+ WriteStats stack_copy;
+ base::debug::Alias(&stack_copy);
if (!owner_) {
// No lock needed.
+
+ write_stats_.write_completion++;
+ if (error != ERROR_SUCCESS)
+ write_stats_.write_completion_failure++;
+ stack_copy = write_stats_;
+
CHECK(pending_write_);
pending_write_ = false;
return;
@@ -329,6 +385,12 @@ void RawChannelWin::RawChannelIOHandler::OnWriteCompleted(DWORD bytes_written,
{
base::AutoLock locker(owner_->write_lock());
+
+ write_stats_.write_completion++;
+ if (error != ERROR_SUCCESS)
+ write_stats_.write_completion_failure++;
+ stack_copy = write_stats_;
+
CHECK(pending_write_);
pending_write_ = false;
}
@@ -346,11 +408,11 @@ RawChannelWin::RawChannelWin(embedder::ScopedPlatformHandle handle)
io_handler_(NULL),
skip_completion_port_on_success_(
g_vista_or_higher_functions.Get().is_vista_or_higher()) {
- DCHECK(handle_.is_valid());
+ CHECK(handle_.is_valid());
}
RawChannelWin::~RawChannelWin() {
- DCHECK(!io_handler_);
+ CHECK(!io_handler_);
}
size_t RawChannelWin::GetSerializedPlatformHandleSize() const {
@@ -359,9 +421,9 @@ size_t RawChannelWin::GetSerializedPlatformHandleSize() const {
}
RawChannel::IOResult RawChannelWin::Read(size_t* bytes_read) {
- DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io());
- DCHECK(io_handler_);
- DCHECK(!io_handler_->pending_read());
+ CHECK_EQ(base::MessageLoop::current(), message_loop_for_io());
+ CHECK(io_handler_);
+ CHECK(!io_handler_->pending_read());
char* buffer = NULL;
size_t bytes_to_read = 0;
@@ -374,7 +436,7 @@ RawChannel::IOResult RawChannelWin::Read(size_t* bytes_read) {
&bytes_read_dword,
&io_handler_->read_context()->overlapped);
if (!result) {
- DCHECK_EQ(bytes_read_dword, 0u);
+ CHECK_EQ(bytes_read_dword, 0u);
DWORD error = GetLastError();
if (error != ERROR_IO_PENDING) {
LOG_IF(ERROR, error != ERROR_BROKEN_PIPE)
@@ -402,14 +464,14 @@ RawChannel::IOResult RawChannelWin::Read(size_t* bytes_read) {
}
RawChannel::IOResult RawChannelWin::ScheduleRead() {
- DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io());
- DCHECK(io_handler_);
- DCHECK(!io_handler_->pending_read());
+ CHECK_EQ(base::MessageLoop::current(), message_loop_for_io());
+ CHECK(io_handler_);
+ CHECK(!io_handler_->pending_read());
size_t bytes_read = 0;
IOResult io_result = Read(&bytes_read);
if (io_result == IO_SUCCEEDED) {
- DCHECK(skip_completion_port_on_success_);
+ CHECK(skip_completion_port_on_success_);
// We have finished reading successfully. Queue a notification manually.
io_handler_->OnPendingReadStarted();
@@ -441,8 +503,15 @@ RawChannel::IOResult RawChannelWin::WriteNoLock(
size_t* bytes_written) {
write_lock().AssertAcquired();
- DCHECK(io_handler_);
- DCHECK(!io_handler_->pending_write_no_lock());
+ RawChannelIOHandler::WriteStats stack_copy(
+ *io_handler_->write_stats_no_lock());
+ base::debug::Alias(&stack_copy);
+
+ io_handler_->write_stats_no_lock()->write_no_lock_call++;
+ stack_copy.write_no_lock_call++;
+
+ CHECK(io_handler_);
+ CHECK(!io_handler_->pending_write_no_lock());
if (write_buffer_no_lock()->HavePlatformHandlesToSend()) {
// TODO(vtl): Implement.
@@ -451,7 +520,10 @@ RawChannel::IOResult RawChannelWin::WriteNoLock(
std::vector<WriteBuffer::Buffer> buffers;
write_buffer_no_lock()->GetBuffers(&buffers);
- DCHECK(!buffers.empty());
+ CHECK(!buffers.empty());
+
+ io_handler_->write_stats_no_lock()->os_write_call++;
+ stack_copy.os_write_call++;
// TODO(yzshen): Handle multi-segment writes more efficiently.
DWORD bytes_written_dword = 0;
@@ -460,9 +532,18 @@ RawChannel::IOResult RawChannelWin::WriteNoLock(
static_cast<DWORD>(buffers[0].size),
&bytes_written_dword,
&io_handler_->write_context_no_lock()->overlapped);
- if (!result && GetLastError() != ERROR_IO_PENDING) {
- PLOG(ERROR) << "WriteFile";
- return IO_FAILED;
+
+ if (!result) {
+ if (GetLastError() == ERROR_IO_PENDING) {
+ io_handler_->write_stats_no_lock()->os_write_pending++;
+ stack_copy.os_write_pending++;
+ } else {
+ io_handler_->write_stats_no_lock()->os_write_failure++;
+ stack_copy.os_write_failure++;
+
+ PLOG(ERROR) << "WriteFile";
+ return IO_FAILED;
+ }
}
if (result && skip_completion_port_on_success_) {
@@ -487,18 +568,29 @@ RawChannel::IOResult RawChannelWin::WriteNoLock(
RawChannel::IOResult RawChannelWin::ScheduleWriteNoLock() {
write_lock().AssertAcquired();
- DCHECK(io_handler_);
- DCHECK(!io_handler_->pending_write_no_lock());
+ RawChannelIOHandler::WriteStats stack_copy(
+ *io_handler_->write_stats_no_lock());
+ base::debug::Alias(&stack_copy);
+
+ io_handler_->write_stats_no_lock()->schedule_write_no_lock_call++;
+ stack_copy.schedule_write_no_lock_call++;
+
+ CHECK(io_handler_);
+ CHECK(!io_handler_->pending_write_no_lock());
// TODO(vtl): Do something with |platform_handles_written|.
size_t platform_handles_written = 0;
size_t bytes_written = 0;
IOResult io_result = WriteNoLock(&platform_handles_written, &bytes_written);
if (io_result == IO_SUCCEEDED) {
- DCHECK(skip_completion_port_on_success_);
+ CHECK(skip_completion_port_on_success_);
// We have finished writing successfully. Queue a notification manually.
io_handler_->OnPendingWriteStartedNoLock();
+
+ io_handler_->write_stats_no_lock()->task_posted_by_schedule_write++;
+ stack_copy.task_posted_by_schedule_write++;
+
// |io_handler_| won't go away before that task is run, so it is safe to use
// |base::Unretained()|.
message_loop_for_io()->PostTask(
@@ -515,16 +607,16 @@ RawChannel::IOResult RawChannelWin::ScheduleWriteNoLock() {
}
bool RawChannelWin::OnInit() {
- DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io());
+ CHECK_EQ(base::MessageLoop::current(), message_loop_for_io());
- DCHECK(handle_.is_valid());
+ CHECK(handle_.is_valid());
if (skip_completion_port_on_success_ &&
!g_vista_or_higher_functions.Get().SetFileCompletionNotificationModes(
handle_.get().handle, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
return false;
}
- DCHECK(!io_handler_);
+ CHECK(!io_handler_);
io_handler_ = new RawChannelIOHandler(this, handle_.Pass());
return true;
@@ -532,8 +624,8 @@ bool RawChannelWin::OnInit() {
void RawChannelWin::OnShutdownNoLock(scoped_ptr<ReadBuffer> read_buffer,
scoped_ptr<WriteBuffer> write_buffer) {
- DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io());
- DCHECK(io_handler_);
+ CHECK_EQ(base::MessageLoop::current(), message_loop_for_io());
+ CHECK(io_handler_);
write_lock().AssertAcquired();