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

Unified Diff: mojo/system/raw_channel_win.cc

Issue 256503005: Mojo: Handle "nested" Shutdown() in RawChannelWin. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/system/raw_channel_unittest.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/system/raw_channel_win.cc
diff --git a/mojo/system/raw_channel_win.cc b/mojo/system/raw_channel_win.cc
index f772287c9b98fdc2db30c39cb945afbe571043e2..8568e8e7317e3a000784d7b48173b2e44cc5a76b 100644
--- a/mojo/system/raw_channel_win.cc
+++ b/mojo/system/raw_channel_win.cc
@@ -6,12 +6,13 @@
#include <windows.h>
-#include "base/basictypes.h"
+#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/lock.h"
@@ -124,11 +125,11 @@ class RawChannelWin : public RawChannel {
// Must be called on the I/O thread.
bool ShouldSelfDestruct() const;
- // Must be called on the I/O thread. It could be called before or after
- // detached from the owner.
+ // Must be called on the I/O thread. It may be called before or after
+ // detaching from the owner.
void OnReadCompleted(DWORD bytes_read, DWORD error);
- // Must be called on the I/O thread. It could be called before or after
- // detached from the owner.
+ // Must be called on the I/O thread. It may be called before or after
+ // detaching from the owner.
void OnWriteCompleted(DWORD bytes_written, DWORD error);
embedder::ScopedPlatformHandle handle_;
@@ -141,6 +142,7 @@ class RawChannelWin : public RawChannel {
// The following members must be used on the I/O thread.
scoped_ptr<ReadBuffer> preserved_read_buffer_after_detach_;
scoped_ptr<WriteBuffer> preserved_write_buffer_after_detach_;
+ bool suppress_self_destruct_;
bool pending_read_;
base::MessageLoopForIO::IOContext read_context_;
@@ -178,6 +180,7 @@ RawChannelWin::RawChannelIOHandler::RawChannelIOHandler(
RawChannelWin* owner,
embedder::ScopedPlatformHandle handle) : handle_(handle.Pass()),
owner_(owner),
+ suppress_self_destruct_(false),
pending_read_(false),
pending_write_(false) {
memset(&read_context_.overlapped, 0, sizeof(read_context_.overlapped));
@@ -239,12 +242,18 @@ void RawChannelWin::RawChannelIOHandler::OnIOCompleted(
DCHECK(!owner_ ||
base::MessageLoop::current() == owner_->message_loop_for_io());
- if (context == &read_context_)
- OnReadCompleted(bytes_transferred, error);
- else if (context == &write_context_)
- OnWriteCompleted(bytes_transferred, error);
- else
- NOTREACHED();
+ {
+ // Suppress self-destruction inside |OnReadCompleted()|, etc. (in case they
+ // result in a call to |Shutdown()|).
+ base::AutoReset<bool> resetter(&suppress_self_destruct_, true);
+
+ if (context == &read_context_)
+ OnReadCompleted(bytes_transferred, error);
+ else if (context == &write_context_)
+ OnWriteCompleted(bytes_transferred, error);
+ else
+ NOTREACHED();
+ }
if (ShouldSelfDestruct())
delete this;
@@ -269,7 +278,7 @@ void RawChannelWin::RawChannelIOHandler::DetachFromOwnerNoLock(
}
bool RawChannelWin::RawChannelIOHandler::ShouldSelfDestruct() const {
- if (owner_)
+ if (owner_ || suppress_self_destruct_)
return false;
// Note: Detached, hence no lock needed for |pending_write_|.
@@ -280,6 +289,7 @@ void RawChannelWin::RawChannelIOHandler::OnReadCompleted(DWORD bytes_read,
DWORD error) {
DCHECK(!owner_ ||
base::MessageLoop::current() == owner_->message_loop_for_io());
+ DCHECK(suppress_self_destruct_);
CHECK(pending_read_);
pending_read_ = false;
@@ -300,6 +310,7 @@ void RawChannelWin::RawChannelIOHandler::OnWriteCompleted(DWORD bytes_written,
DWORD error) {
DCHECK(!owner_ ||
base::MessageLoop::current() == owner_->message_loop_for_io());
+ DCHECK(suppress_self_destruct_);
if (!owner_) {
// No lock needed.
« no previous file with comments | « mojo/system/raw_channel_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698