diff options
author | jabdelmalek@google.com <jabdelmalek@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-12 18:48:00 +0000 |
---|---|---|
committer | jabdelmalek@google.com <jabdelmalek@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-12 18:48:00 +0000 |
commit | b4a718ef7d860ccea49e05fa2959790259c8f712 (patch) | |
tree | 987725d2d197fc9f7f5e13eff8d6a080cae81b85 /chrome/common | |
parent | 662581c711db6308a64be1ab1f1cc1eb68f31630 (diff) | |
download | chromium_src-b4a718ef7d860ccea49e05fa2959790259c8f712.zip chromium_src-b4a718ef7d860ccea49e05fa2959790259c8f712.tar.gz chromium_src-b4a718ef7d860ccea49e05fa2959790259c8f712.tar.bz2 |
Manually refcount ReceivedSyncMsgQueue so that we force it to be destructed on the listener thread.
BUG=1319842
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@733 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common')
-rw-r--r-- | chrome/common/ipc_sync_channel.cc | 22 | ||||
-rw-r--r-- | chrome/common/ipc_sync_channel.h | 4 |
2 files changed, 16 insertions, 10 deletions
diff --git a/chrome/common/ipc_sync_channel.cc b/chrome/common/ipc_sync_channel.cc index e01759a..e29d330 100644 --- a/chrome/common/ipc_sync_channel.cc +++ b/chrome/common/ipc_sync_channel.cc @@ -69,7 +69,10 @@ class SyncChannel::ReceivedSyncMsgQueue : } ~ReceivedSyncMsgQueue() { + DCHECK(ThreadLocalStorage::Get(g_tls_index)); + DCHECK(MessageLoop::current() == listener_message_loop_); CloseHandle(blocking_event_); + ThreadLocalStorage::Set(g_tls_index, NULL); } // Called on IPC thread when a synchronous message or reply arrives. @@ -182,6 +185,7 @@ class SyncChannel::ReceivedSyncMsgQueue : } HANDLE blocking_event() { return blocking_event_; } + MessageLoop* listener_message_loop() { return listener_message_loop_; } private: // Called on the ipc thread to check if we can unblock any current Send() @@ -247,24 +251,24 @@ SyncChannel::SyncContext::SyncContext( received_sync_msgs_ = static_cast<ReceivedSyncMsgQueue*>( ThreadLocalStorage::Get(g_tls_index)); - if (!received_sync_msgs_.get()) { + if (!received_sync_msgs_) { // Stash a pointer to the listener thread's ReceivedSyncMsgQueue, as we // need to be able to access it in the IPC thread. received_sync_msgs_ = new ReceivedSyncMsgQueue(); - // TODO(jcampan): http:///b/1319842 we are adding an extra-ref to keep this - // object around for the duration of the process. We used to remove it from - // the TLS when it was destroyed, but that was causing problems as we could - // be destroyed in a different thread then the thread we had been created - // on. This needs to be revisited at some point. - received_sync_msgs_->AddRef(); - - ThreadLocalStorage::Set(g_tls_index, received_sync_msgs_.get()); + ThreadLocalStorage::Set(g_tls_index, received_sync_msgs_); } + + // Addref manually so that we can ensure destruction on the listener thread + // (so that the TLS object is NULLd). + received_sync_msgs_->AddRef(); } SyncChannel::SyncContext::~SyncContext() { while (!deserializers_.empty()) PopDeserializer(true); + + received_sync_msgs_->listener_message_loop()->ReleaseSoon( + FROM_HERE, received_sync_msgs_); } // Adds information about an outgoing sync message to the context so that diff --git a/chrome/common/ipc_sync_channel.h b/chrome/common/ipc_sync_channel.h index bd473d4..fa3566e 100644 --- a/chrome/common/ipc_sync_channel.h +++ b/chrome/common/ipc_sync_channel.h @@ -128,7 +128,9 @@ class SyncChannel : public ChannelProxy { PendingSyncMessageQueue deserializers_; Lock deserializers_lock_; - scoped_refptr<ReceivedSyncMsgQueue> received_sync_msgs_; + // This can't be a scoped_refptr because it needs to be released on the + // listener thread. + ReceivedSyncMsgQueue* received_sync_msgs_; bool channel_closed_; bool reply_deserialize_result_; |