1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_MEMORY_REF_COUNTED_DELETE_ON_MESSAGE_LOOP_H_ 6 #define BASE_MEMORY_REF_COUNTED_DELETE_ON_MESSAGE_LOOP_H_ 7 8 #include "base/location.h" 9 #include "base/logging.h" 10 #include "base/macros.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/single_thread_task_runner.h" 13 14 namespace base { 15 16 // RefCountedDeleteOnMessageLoop is similar to RefCountedThreadSafe, and ensures 17 // that the object will be deleted on a specified message loop. 18 // 19 // Sample usage: 20 // class Foo : public RefCountedDeleteOnMessageLoop<Foo> { 21 // 22 // Foo(const scoped_refptr<SingleThreadTaskRunner>& loop) 23 // : RefCountedDeleteOnMessageLoop<Foo>(loop) { 24 // ... 25 // } 26 // ... 27 // private: 28 // friend class RefCountedDeleteOnMessageLoop<Foo>; 29 // friend class DeleteHelper<Foo>; 30 // 31 // ~Foo(); 32 // }; 33 34 // TODO(skyostil): Rename this to RefCountedDeleteOnTaskRunner. 35 template <class T> 36 class RefCountedDeleteOnMessageLoop : public subtle::RefCountedThreadSafeBase { 37 public: 38 // This constructor will accept a MessageL00pProxy object, but new code should 39 // prefer a SingleThreadTaskRunner. A SingleThreadTaskRunner for the 40 // MessageLoop on the current thread can be acquired by calling 41 // MessageLoop::current()->task_runner(). RefCountedDeleteOnMessageLoop(const scoped_refptr<SingleThreadTaskRunner> & task_runner)42 RefCountedDeleteOnMessageLoop( 43 const scoped_refptr<SingleThreadTaskRunner>& task_runner) 44 : task_runner_(task_runner) { 45 DCHECK(task_runner_); 46 } 47 AddRef()48 void AddRef() const { 49 subtle::RefCountedThreadSafeBase::AddRef(); 50 } 51 Release()52 void Release() const { 53 if (subtle::RefCountedThreadSafeBase::Release()) 54 DestructOnMessageLoop(); 55 } 56 57 protected: 58 friend class DeleteHelper<RefCountedDeleteOnMessageLoop>; ~RefCountedDeleteOnMessageLoop()59 ~RefCountedDeleteOnMessageLoop() {} 60 DestructOnMessageLoop()61 void DestructOnMessageLoop() const { 62 const T* t = static_cast<const T*>(this); 63 if (task_runner_->BelongsToCurrentThread()) 64 delete t; 65 else 66 task_runner_->DeleteSoon(FROM_HERE, t); 67 } 68 69 scoped_refptr<SingleThreadTaskRunner> task_runner_; 70 71 private: 72 DISALLOW_COPY_AND_ASSIGN(RefCountedDeleteOnMessageLoop); 73 }; 74 75 } // namespace base 76 77 #endif // BASE_MEMORY_REF_COUNTED_DELETE_ON_MESSAGE_LOOP_H_ 78