Add thread checks to the IPC channel.
Almost every method of the IPC channel must be invoked from a single thread. This adds the corresponding DCHECKS, and should confirm bug 6489 as a cause of flakiness on the UI tests. BUG: 6489. Review URL: http://codereview.chromium.org/19617 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8837 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@@ -32,7 +32,6 @@ class NonThreadSafe {
|
|||||||
NonThreadSafe();
|
NonThreadSafe();
|
||||||
~NonThreadSafe();
|
~NonThreadSafe();
|
||||||
|
|
||||||
protected:
|
|
||||||
bool CalledOnValidThread() const;
|
bool CalledOnValidThread() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -45,7 +44,6 @@ class NonThreadSafe {
|
|||||||
NonThreadSafe() {}
|
NonThreadSafe() {}
|
||||||
~NonThreadSafe() {}
|
~NonThreadSafe() {}
|
||||||
|
|
||||||
protected:
|
|
||||||
bool CalledOnValidThread() const {
|
bool CalledOnValidThread() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
|
#include "base/non_thread_safe.h"
|
||||||
#include "base/win_util.h"
|
#include "base/win_util.h"
|
||||||
#include "chrome/common/chrome_counters.h"
|
#include "chrome/common/chrome_counters.h"
|
||||||
#include "chrome/common/ipc_logging.h"
|
#include "chrome/common/ipc_logging.h"
|
||||||
@@ -46,6 +47,10 @@ Channel::ChannelImpl::ChannelImpl(const std::wstring& channel_id, Mode mode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Channel::ChannelImpl::Close() {
|
void Channel::ChannelImpl::Close() {
|
||||||
|
if (thread_check_.get()) {
|
||||||
|
DCHECK(thread_check_->CalledOnValidThread());
|
||||||
|
}
|
||||||
|
|
||||||
bool waited = false;
|
bool waited = false;
|
||||||
if (input_state_.is_pending || output_state_.is_pending) {
|
if (input_state_.is_pending || output_state_.is_pending) {
|
||||||
CancelIo(pipe_);
|
CancelIo(pipe_);
|
||||||
@@ -77,6 +82,7 @@ void Channel::ChannelImpl::Close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Channel::ChannelImpl::Send(Message* message) {
|
bool Channel::ChannelImpl::Send(Message* message) {
|
||||||
|
DCHECK(thread_check_->CalledOnValidThread());
|
||||||
chrome::Counters::ipc_send_counter().Increment();
|
chrome::Counters::ipc_send_counter().Increment();
|
||||||
#ifdef IPC_MESSAGE_DEBUG_EXTRA
|
#ifdef IPC_MESSAGE_DEBUG_EXTRA
|
||||||
DLOG(INFO) << "sending message @" << message << " on channel @" << this
|
DLOG(INFO) << "sending message @" << message << " on channel @" << this
|
||||||
@@ -167,6 +173,9 @@ bool Channel::ChannelImpl::CreatePipe(const std::wstring& channel_id,
|
|||||||
bool Channel::ChannelImpl::Connect() {
|
bool Channel::ChannelImpl::Connect() {
|
||||||
DLOG(WARNING) << "Connect called twice";
|
DLOG(WARNING) << "Connect called twice";
|
||||||
|
|
||||||
|
if (!thread_check_.get())
|
||||||
|
thread_check_.reset(new NonThreadSafe());
|
||||||
|
|
||||||
if (pipe_ == INVALID_HANDLE_VALUE)
|
if (pipe_ == INVALID_HANDLE_VALUE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -190,6 +199,7 @@ bool Channel::ChannelImpl::Connect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Channel::ChannelImpl::ProcessConnection() {
|
bool Channel::ChannelImpl::ProcessConnection() {
|
||||||
|
DCHECK(thread_check_->CalledOnValidThread());
|
||||||
if (input_state_.is_pending)
|
if (input_state_.is_pending)
|
||||||
input_state_.is_pending = false;
|
input_state_.is_pending = false;
|
||||||
|
|
||||||
@@ -225,6 +235,7 @@ bool Channel::ChannelImpl::ProcessConnection() {
|
|||||||
bool Channel::ChannelImpl::ProcessIncomingMessages(
|
bool Channel::ChannelImpl::ProcessIncomingMessages(
|
||||||
MessageLoopForIO::IOContext* context,
|
MessageLoopForIO::IOContext* context,
|
||||||
DWORD bytes_read) {
|
DWORD bytes_read) {
|
||||||
|
DCHECK(thread_check_->CalledOnValidThread());
|
||||||
if (input_state_.is_pending) {
|
if (input_state_.is_pending) {
|
||||||
input_state_.is_pending = false;
|
input_state_.is_pending = false;
|
||||||
DCHECK(context);
|
DCHECK(context);
|
||||||
@@ -313,6 +324,7 @@ bool Channel::ChannelImpl::ProcessOutgoingMessages(
|
|||||||
DWORD bytes_written) {
|
DWORD bytes_written) {
|
||||||
DCHECK(!waiting_connect_); // Why are we trying to send messages if there's
|
DCHECK(!waiting_connect_); // Why are we trying to send messages if there's
|
||||||
// no connection?
|
// no connection?
|
||||||
|
DCHECK(thread_check_->CalledOnValidThread());
|
||||||
|
|
||||||
if (output_state_.is_pending) {
|
if (output_state_.is_pending) {
|
||||||
DCHECK(context);
|
DCHECK(context);
|
||||||
@@ -370,6 +382,7 @@ bool Channel::ChannelImpl::ProcessOutgoingMessages(
|
|||||||
void Channel::ChannelImpl::OnIOCompleted(MessageLoopForIO::IOContext* context,
|
void Channel::ChannelImpl::OnIOCompleted(MessageLoopForIO::IOContext* context,
|
||||||
DWORD bytes_transfered, DWORD error) {
|
DWORD bytes_transfered, DWORD error) {
|
||||||
bool ok;
|
bool ok;
|
||||||
|
DCHECK(thread_check_->CalledOnValidThread());
|
||||||
if (context == &input_state_.context) {
|
if (context == &input_state_.context) {
|
||||||
if (waiting_connect_) {
|
if (waiting_connect_) {
|
||||||
if (!ProcessConnection())
|
if (!ProcessConnection())
|
||||||
|
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include "base/message_loop.h"
|
#include "base/message_loop.h"
|
||||||
|
|
||||||
|
class NonThreadSafe;
|
||||||
|
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
|
|
||||||
class Channel::ChannelImpl : public MessageLoopForIO::IOHandler {
|
class Channel::ChannelImpl : public MessageLoopForIO::IOHandler {
|
||||||
@@ -73,6 +75,8 @@ class Channel::ChannelImpl : public MessageLoopForIO::IOHandler {
|
|||||||
|
|
||||||
ScopedRunnableMethodFactory<ChannelImpl> factory_;
|
ScopedRunnableMethodFactory<ChannelImpl> factory_;
|
||||||
|
|
||||||
|
scoped_ptr<NonThreadSafe> thread_check_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(ChannelImpl);
|
DISALLOW_COPY_AND_ASSIGN(ChannelImpl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user