blob: 12a1f2ae6daa7ed9fae3a8c68660f9ad040bea40 [file] [log] [blame]
// Copyright 2015 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 CancellableTaskFactory_h
#define CancellableTaskFactory_h
#include "platform/PlatformExport.h"
#include "platform/heap/Handle.h"
#include "public/platform/WebTaskRunner.h"
#include "wtf/Allocator.h"
#include "wtf/Functional.h"
#include "wtf/Noncopyable.h"
#include "wtf/PtrUtil.h"
#include "wtf/WeakPtr.h"
#include <memory>
#include <type_traits>
namespace blink {
class TraceLocation;
class PLATFORM_EXPORT CancellableTaskFactory {
WTF_MAKE_NONCOPYABLE(CancellableTaskFactory);
USING_FAST_MALLOC(CancellableTaskFactory);
public:
// A pair of mutually exclusive factory methods are provided for constructing
// a CancellableTaskFactory, one for when a Oilpan heap object owns a
// CancellableTaskFactory, and one when that owning object isn't controlled
// by Oilpan.
//
// In the Oilpan case, as WTF::Closure objects are off-heap, we have to construct the
// closure in such a manner that it doesn't end up referring back to the owning heap
// object with a strong Persistent<> GC root reference. If we do, this will create
// a heap <-> off-heap cycle and leak, the owning object can never be GCed.
// Instead, the closure will keep an off-heap persistent reference of the weak
// variety, which will refer back to the owner heap object safely (but weakly.)
//
template<typename T>
static std::unique_ptr<CancellableTaskFactory> create(T* thisObject, void (T::*method)(), typename std::enable_if<IsGarbageCollectedType<T>::value>::type* = nullptr)
{
return wrapUnique(new CancellableTaskFactory(WTF::bind(method, wrapWeakPersistent(thisObject))));
}
template<typename T>
static std::unique_ptr<CancellableTaskFactory> create(T* thisObject, void (T::*method)(), typename std::enable_if<!IsGarbageCollectedType<T>::value>::type* = nullptr)
{
return wrapUnique(new CancellableTaskFactory(WTF::bind(method, WTF::unretained(thisObject))));
}
bool isPending() const
{
return m_weakPtrFactory.hasWeakPtrs();
}
void cancel();
// Returns a task that can be disabled by calling cancel(). The user takes
// ownership of the task. Creating a new task cancels any previous ones.
WebTaskRunner::Task* cancelAndCreate();
protected:
// Only intended used by unit tests wanting to stack allocate and/or pass in a closure value.
// Please use the create() factory method elsewhere.
explicit CancellableTaskFactory(std::unique_ptr<WTF::Closure> closure)
: m_closure(std::move(closure))
, m_weakPtrFactory(this)
{
}
private:
class CancellableTask : public WebTaskRunner::Task {
USING_FAST_MALLOC(CancellableTask);
WTF_MAKE_NONCOPYABLE(CancellableTask);
public:
explicit CancellableTask(WeakPtr<CancellableTaskFactory> weakPtr)
: m_weakPtr(weakPtr) {}
~CancellableTask() override {}
void run() override;
private:
WeakPtr<CancellableTaskFactory> m_weakPtr;
};
std::unique_ptr<WTF::Closure> m_closure;
WeakPtrFactory<CancellableTaskFactory> m_weakPtrFactory;
};
} // namespace blink
#endif // CancellableTaskFactory_h