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_SEQUENCE_H_ 6 #define BASE_MEMORY_REF_COUNTED_DELETE_ON_SEQUENCE_H_ 7 8 #include <utility> 9 10 #include "base/location.h" 11 #include "base/logging.h" 12 #include "base/macros.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/sequenced_task_runner.h" 15 16 namespace base { 17 18 // RefCountedDeleteOnSequence is similar to RefCountedThreadSafe, and ensures 19 // that the object will be deleted on a specified sequence. 20 // 21 // Sample usage: 22 // class Foo : public RefCountedDeleteOnSequence<Foo> { 23 // 24 // Foo(scoped_refptr<SequencedTaskRunner> task_runner) 25 // : RefCountedDeleteOnSequence<Foo>(std::move(task_runner)) {} 26 // ... 27 // private: 28 // friend class RefCountedDeleteOnSequence<Foo>; 29 // friend class DeleteHelper<Foo>; 30 // 31 // ~Foo(); 32 // }; 33 template <class T> 34 class RefCountedDeleteOnSequence : public subtle::RefCountedThreadSafeBase { 35 public: 36 static constexpr subtle::StartRefCountFromZeroTag kRefCountPreference = 37 subtle::kStartRefCountFromZeroTag; 38 39 // A SequencedTaskRunner for the current sequence can be acquired by calling 40 // SequencedTaskRunnerHandle::Get(). RefCountedDeleteOnSequence(scoped_refptr<SequencedTaskRunner> owning_task_runner)41 RefCountedDeleteOnSequence( 42 scoped_refptr<SequencedTaskRunner> owning_task_runner) 43 : subtle::RefCountedThreadSafeBase(T::kRefCountPreference), 44 owning_task_runner_(std::move(owning_task_runner)) { 45 DCHECK(owning_task_runner_); 46 } 47 AddRef()48 void AddRef() const { subtle::RefCountedThreadSafeBase::AddRef(); } 49 Release()50 void Release() const { 51 if (subtle::RefCountedThreadSafeBase::Release()) 52 DestructOnSequence(); 53 } 54 55 protected: 56 friend class DeleteHelper<RefCountedDeleteOnSequence>; 57 ~RefCountedDeleteOnSequence() = default; 58 owning_task_runner()59 SequencedTaskRunner* owning_task_runner() { 60 return owning_task_runner_.get(); 61 } owning_task_runner()62 const SequencedTaskRunner* owning_task_runner() const { 63 return owning_task_runner_.get(); 64 } 65 66 private: DestructOnSequence()67 void DestructOnSequence() const { 68 const T* t = static_cast<const T*>(this); 69 if (owning_task_runner_->RunsTasksInCurrentSequence()) 70 delete t; 71 else 72 owning_task_runner_->DeleteSoon(FROM_HERE, t); 73 } 74 75 const scoped_refptr<SequencedTaskRunner> owning_task_runner_; 76 77 DISALLOW_COPY_AND_ASSIGN(RefCountedDeleteOnSequence); 78 }; 79 80 } // namespace base 81 82 #endif // BASE_MEMORY_REF_COUNTED_DELETE_ON_SEQUENCE_H_ 83