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(scoped_refptr<SingleThreadTaskRunner> loop) 23 // : RefCountedDeleteOnMessageLoop<Foo>(std::move(loop)) {} 24 // ... 25 // private: 26 // friend class RefCountedDeleteOnMessageLoop<Foo>; 27 // friend class DeleteHelper<Foo>; 28 // 29 // ~Foo(); 30 // }; 31 32 // TODO(skyostil): Rename this to RefCountedDeleteOnTaskRunner. 33 template <class T> 34 class RefCountedDeleteOnMessageLoop : public subtle::RefCountedThreadSafeBase { 35 public: 36 // This constructor will accept a MessageL00pProxy object, but new code should 37 // prefer a SingleThreadTaskRunner. A SingleThreadTaskRunner for the 38 // MessageLoop on the current thread can be acquired by calling 39 // MessageLoop::current()->task_runner(). RefCountedDeleteOnMessageLoop(scoped_refptr<SingleThreadTaskRunner> task_runner)40 RefCountedDeleteOnMessageLoop( 41 scoped_refptr<SingleThreadTaskRunner> task_runner) 42 : task_runner_(std::move(task_runner)) { 43 DCHECK(task_runner_); 44 } 45 AddRef()46 void AddRef() const { 47 subtle::RefCountedThreadSafeBase::AddRef(); 48 } 49 Release()50 void Release() const { 51 if (subtle::RefCountedThreadSafeBase::Release()) 52 DestructOnMessageLoop(); 53 } 54 55 protected: 56 friend class DeleteHelper<RefCountedDeleteOnMessageLoop>; ~RefCountedDeleteOnMessageLoop()57 ~RefCountedDeleteOnMessageLoop() {} 58 DestructOnMessageLoop()59 void DestructOnMessageLoop() const { 60 const T* t = static_cast<const T*>(this); 61 if (task_runner_->BelongsToCurrentThread()) 62 delete t; 63 else 64 task_runner_->DeleteSoon(FROM_HERE, t); 65 } 66 67 scoped_refptr<SingleThreadTaskRunner> task_runner_; 68 69 private: 70 DISALLOW_COPY_AND_ASSIGN(RefCountedDeleteOnMessageLoop); 71 }; 72 73 } // namespace base 74 75 #endif // BASE_MEMORY_REF_COUNTED_DELETE_ON_MESSAGE_LOOP_H_ 76