diff options
author | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-26 17:24:10 +0000 |
---|---|---|
committer | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-26 17:24:10 +0000 |
commit | bfbaf508a72edf6815e7859035a3f962318ac12e (patch) | |
tree | 5243696d92306af613e9482c55f79d4701853ff2 /chrome_frame/chrome_frame_delegate.h | |
parent | d07a5dffebfe3c4f7ffaa2f47fbb7e2219cbed3b (diff) | |
download | chromium_src-bfbaf508a72edf6815e7859035a3f962318ac12e.zip chromium_src-bfbaf508a72edf6815e7859035a3f962318ac12e.tar.gz chromium_src-bfbaf508a72edf6815e7859035a3f962318ac12e.tar.bz2 |
Destroy pending tasks marshaled through windows messages avoiding possible crashes when object is destroyed and there is tasks in the queue.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/661145
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40125 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/chrome_frame_delegate.h')
-rw-r--r-- | chrome_frame/chrome_frame_delegate.h | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/chrome_frame/chrome_frame_delegate.h b/chrome_frame/chrome_frame_delegate.h index 11eaa30..93d4645 100644 --- a/chrome_frame/chrome_frame_delegate.h +++ b/chrome_frame/chrome_frame_delegate.h @@ -7,7 +7,9 @@ #include <atlbase.h> #include <atlwin.h> +#include <queue> +#include "base/lock.h" #include "chrome/test/automation/automation_messages.h" #include "ipc/ipc_message.h" @@ -125,15 +127,35 @@ class TaskMarshaller { template <class T> class TaskMarshallerThroughWindowsMessages : public TaskMarshaller { public: + TaskMarshallerThroughWindowsMessages() {} virtual void PostTask(const tracked_objects::Location& from_here, Task* task) { task->SetBirthPlace(from_here); T* this_ptr = static_cast<T*>(this); if (this_ptr->IsWindow()) { this_ptr->AddRef(); + PushTask(task); this_ptr->PostMessage(MSG_EXECUTE_TASK, reinterpret_cast<WPARAM>(task)); } else { DLOG(INFO) << "Dropping MSG_EXECUTE_TASK message for destroyed window."; + delete task; + } + } + + + protected: + ~TaskMarshallerThroughWindowsMessages() { + DeleteAllPendingTasks(); + } + + void DeleteAllPendingTasks() { + AutoLock lock(lock_); + DLOG_IF(INFO, !pending_tasks_.empty()) << "Destroying " << + pending_tasks_.size() << " pending tasks"; + while (!pending_tasks_.empty()) { + Task* task = pending_tasks_.front(); + pending_tasks_.pop(); + delete task; } } @@ -146,12 +168,27 @@ template <class T> class TaskMarshallerThroughWindowsMessages inline LRESULT ExecuteTask(UINT, WPARAM wparam, LPARAM, BOOL& handled) { // NOLINT Task* task = reinterpret_cast<Task*>(wparam); + PopTask(task); task->Run(); delete task; T* this_ptr = static_cast<T*>(this); this_ptr->Release(); return 0; } + + inline void PushTask(Task* task) { + AutoLock lock(lock_); + pending_tasks_.push(task); + } + + inline void PopTask(Task* task) { + AutoLock lock(lock_); + DCHECK_EQ(task, pending_tasks_.front()); + pending_tasks_.pop(); + } + + Lock lock_; + std::queue<Task*> pending_tasks_; }; #endif // CHROME_FRAME_CHROME_FRAME_DELEGATE_H_ |