mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 14:26:09 +03:00
91 lines
2.6 KiB
C++
91 lines
2.6 KiB
C++
// Copyright 2013 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef BASE_MEMORY_REF_COUNTED_DELETE_ON_SEQUENCE_H_
|
|
#define BASE_MEMORY_REF_COUNTED_DELETE_ON_SEQUENCE_H_
|
|
|
|
#include <utility>
|
|
|
|
#include "base/location.h"
|
|
#include "base/logging.h"
|
|
#include "base/macros.h"
|
|
#include "base/memory/ref_counted.h"
|
|
#include "base/sequenced_task_runner.h"
|
|
|
|
namespace base {
|
|
|
|
// RefCountedDeleteOnSequence is similar to RefCountedThreadSafe, and ensures
|
|
// that the object will be deleted on a specified sequence.
|
|
//
|
|
// Sample usage:
|
|
// class Foo : public RefCountedDeleteOnSequence<Foo> {
|
|
//
|
|
// Foo(scoped_refptr<SequencedTaskRunner> task_runner)
|
|
// : RefCountedDeleteOnSequence<Foo>(std::move(task_runner)) {}
|
|
// ...
|
|
// private:
|
|
// friend class RefCountedDeleteOnSequence<Foo>;
|
|
// friend class DeleteHelper<Foo>;
|
|
//
|
|
// ~Foo();
|
|
// };
|
|
template <class T>
|
|
class RefCountedDeleteOnSequence : public subtle::RefCountedThreadSafeBase {
|
|
public:
|
|
static constexpr subtle::StartRefCountFromZeroTag kRefCountPreference =
|
|
subtle::kStartRefCountFromZeroTag;
|
|
|
|
// A SequencedTaskRunner for the current sequence can be acquired by calling
|
|
// SequencedTaskRunnerHandle::Get().
|
|
RefCountedDeleteOnSequence(
|
|
scoped_refptr<SequencedTaskRunner> owning_task_runner)
|
|
: subtle::RefCountedThreadSafeBase(T::kRefCountPreference),
|
|
owning_task_runner_(std::move(owning_task_runner)) {
|
|
DCHECK(owning_task_runner_);
|
|
}
|
|
|
|
void AddRef() const { AddRefImpl(T::kRefCountPreference); }
|
|
|
|
void Release() const {
|
|
if (subtle::RefCountedThreadSafeBase::Release())
|
|
DestructOnSequence();
|
|
}
|
|
|
|
protected:
|
|
friend class DeleteHelper<RefCountedDeleteOnSequence>;
|
|
~RefCountedDeleteOnSequence() = default;
|
|
|
|
SequencedTaskRunner* owning_task_runner() {
|
|
return owning_task_runner_.get();
|
|
}
|
|
const SequencedTaskRunner* owning_task_runner() const {
|
|
return owning_task_runner_.get();
|
|
}
|
|
|
|
private:
|
|
void DestructOnSequence() const {
|
|
const T* t = static_cast<const T*>(this);
|
|
if (owning_task_runner_->RunsTasksInCurrentSequence())
|
|
delete t;
|
|
else
|
|
owning_task_runner_->DeleteSoon(FROM_HERE, t);
|
|
}
|
|
|
|
void AddRefImpl(subtle::StartRefCountFromZeroTag) const {
|
|
subtle::RefCountedThreadSafeBase::AddRef();
|
|
}
|
|
|
|
void AddRefImpl(subtle::StartRefCountFromOneTag) const {
|
|
subtle::RefCountedThreadSafeBase::AddRefWithCheck();
|
|
}
|
|
|
|
const scoped_refptr<SequencedTaskRunner> owning_task_runner_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(RefCountedDeleteOnSequence);
|
|
};
|
|
|
|
} // namespace base
|
|
|
|
#endif // BASE_MEMORY_REF_COUNTED_DELETE_ON_SEQUENCE_H_
|