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

Side by Side Diff: base/task.h

Issue 7210053: Implementation of PostTaskAndReply() in MessageLoopProxy and BrowserThread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: missed something small Created 9 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_TASK_H_ 5 #ifndef BASE_TASK_H_
6 #define BASE_TASK_H_ 6 #define BASE_TASK_H_
7 #pragma once 7 #pragma once
8 8
9 #include "base/base_api.h" 9 #include "base/base_api.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/debug/alias.h" 11 #include "base/debug/alias.h"
12 #include "base/memory/raw_scoped_refptr_mismatch_checker.h" 12 #include "base/memory/raw_scoped_refptr_mismatch_checker.h"
13 #include "base/memory/weak_ptr.h" 13 #include "base/memory/weak_ptr.h"
14 #include "base/tracked.h" 14 #include "base/tracked.h"
15 #include "base/tuple.h" 15 #include "base/tuple.h"
16 16
17 class MessageLoop;
18
17 namespace base { 19 namespace base {
18 const size_t kDeadTask = 0xDEAD7A53; 20 const size_t kDeadTask = 0xDEAD7A53;
21 class MessageLoopProxy;
19 } 22 }
20 23
21 // Task ------------------------------------------------------------------------ 24 // Task ------------------------------------------------------------------------
22 // 25 //
23 // A task is a generic runnable thingy, usually used for running code on a 26 // A task is a generic runnable thingy, usually used for running code on a
24 // different thread or for scheduling future tasks off of the message loop. 27 // different thread or for scheduling future tasks off of the message loop.
25 28
26 class BASE_API Task : public tracked_objects::Tracked { 29 class BASE_API Task : public tracked_objects::Tracked {
27 public: 30 public:
28 Task(); 31 Task();
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 Task* Release(); 563 Task* Release();
561 564
562 private: 565 private:
563 Task* task_; 566 Task* task_;
564 567
565 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedTaskRunner); 568 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedTaskRunner);
566 }; 569 };
567 570
568 namespace internal { 571 namespace internal {
569 572
570 class PostTaskAndReplyRelay { 573 // This relay class remembers the MessageLoop that it was created on, and
574 // ensures that both the |task| and |reply| Closures are deleted on this same
575 // thread.
576 //
577 // If this is not possible because the originating MessageLoop is no longer
578 // available, the the |task| and |reply| Closures are leaked. Leaking is
579 // considered preferable to having a thread-safetey violations caused by
580 // invoking the Closure destructor on the wrong thread.
581 class PostTaskAndReplyRelay :
582 public RefCountedThreadSafe<PostTaskAndReplyRelay, ManualDestruction> {
571 public: 583 public:
572 PostTaskAndReplyRelay(const Closure& task, const Closure& reply); 584 PostTaskAndReplyRelay(const tracked_objects::Location& from_here,
585 const Closure& task, const Closure& reply);
573 586
574 ~PostTaskAndReplyRelay(); 587 ~PostTaskAndReplyRelay();
575 588
576 void Run(); 589 void Run();
577 590
578 private: 591 private:
592 // An alternate implementation would just call "delete this;" inside
593 // RunReplyAndSelfDestruct() instead of using refcounts with
594 // ManualDestruction. While this works mostly, it misses the case where the
595 // target MessageLoop is in shutdown, but the origin MessageLoop is not.
willchan no longer on Chromium 2011/07/06 22:10:26 I think this is unnecessarily complicated and this
awong 2011/08/15 22:07:55 Okay, went back to simple delete.
596 //
597 // Using a refcount allows us to still properly delete the relay object even
598 // if PostTaskAndReplyRelay::Run() is never executed.
599 friend class base::ManualDestruction;
600 static void DoManualDestruction(const PostTaskAndReplyRelay* obj);
601
579 void RunReplyAndSelfDestruct(); 602 void RunReplyAndSelfDestruct();
580 603
581 base::Closure task_; 604 tracked_objects::Location from_here_;
582 base::Closure reply_; 605 scoped_refptr<MessageLoopProxy> origin_loop_;
606 Closure task_;
607 Closure reply_;
583 }; 608 };
609
584 } // namespace internal 610 } // namespace internal
585 611
586 template <typename MessageLoopType, typename ResponseType> 612 void PostTaskAndReply(MessageLoop* loop,
587 void PostTaskAndReply(MessageLoopType loop, const Closure& task, 613 const tracked_objects::Location& from_here,
588 const Closure& reply) { 614 const Closure& task,
589 PostTaskAndReplyRelay* relay = new PostTaskAndReplyRelay(task, reply); 615 const Closure& reply);
590 loop.PostTask(&PostTaskAndReplyRelay::Run, base::Unretained(relay));
591 }
592
593 template <typename MessageLoopType, typename ResponseType>
594 void PostTaskAndReply<MessageLoopType, ResponseType>(
595 MessageLoopType* loop, const Closure& task, const Closure& reply) {
596 PostTaskAndReplyRelay* relay = new PostTaskAndReplyRelay(task, reply);
597 loop->PostTask(&PostTaskAndReplyRelay::Run, base::Unretained(relay));
598 }
599
600 } // namespace base 616 } // namespace base
601 617
602 #endif // BASE_TASK_H_ 618 #endif // BASE_TASK_H_
OLDNEW
« no previous file with comments | « base/memory/ref_counted.h ('k') | base/task.cc » ('j') | base/task.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698