summaryrefslogtreecommitdiffstats
path: root/src/core/locked_ptr.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/locked_ptr.h')
-rw-r--r--src/core/locked_ptr.h301
1 files changed, 0 insertions, 301 deletions
diff --git a/src/core/locked_ptr.h b/src/core/locked_ptr.h
deleted file mode 100644
index 46d89819b..000000000
--- a/src/core/locked_ptr.h
+++ /dev/null
@@ -1,301 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef LOCKED_PTR_H
-#define LOCKED_PTR_H
-
-#include <base/bind_internal.h>
-
-#include <QtCore/qreadwritelock.h>
-
-namespace base {
-
-struct LockedPtrCore
-{
- LockedPtrCore(uintptr_t data) : data(data) {}
-
- std::atomic<size_t> refCount{1};
- // Atomic so that WeakLockedPtr::get can still read it.
- std::atomic<uintptr_t> data;
- QReadWriteLock lock{QReadWriteLock::Recursive};
-};
-
-enum class LockedPtrMode { Weak, Shared, Exclusive };
-
-template<class T, LockedPtrMode mode> class LockedPtr;
-
-// A WeakLockedPtr<T> is something like shared_ptr<T*>. The T* value can only be
-// accessed by atomic read.
-template<class T> using WeakLockedPtr = LockedPtr<T, LockedPtrMode::Weak>;
-
-// A SharedLockedPtr<T> is like WeakLockedPtr<T>, but the T* value is prevented
-// from changing for the lifetime of the SharedLockedPtr by holding a
-// shared-exclusive mutex in shared mode.
-template<class T> using SharedLockedPtr = LockedPtr<T, LockedPtrMode::Shared>;
-
-// An ExclusiveLockedPtr<T> is like SharedLockedPtr<T>, but the mutex is held in
-// exclusive mode. Only in this mode can the T* value be changed.
-template<class T> using ExclusiveLockedPtr = LockedPtr<T, LockedPtrMode::Exclusive>;
-
-template<class T, LockedPtrMode mode>
-class LockedPtr
-{
- template<class T1>
- static constexpr bool canConstructFrom =
- std::is_same<T, T1>::value ||
- std::is_same<T, const T1>::value;
-
-public:
- constexpr LockedPtr() {}
- constexpr LockedPtr(std::nullptr_t) {}
-
- LockedPtr(const LockedPtr &that)
- {
- m_core = that.m_core;
- lock();
- }
-
- LockedPtr &operator=(const LockedPtr &that)
- {
- unlock();
- m_core = that.m_core;
- lock();
- }
-
- LockedPtr(LockedPtr &&that)
- {
- m_core = that.m_core;
- that.m_core = nullptr;
- }
-
- LockedPtr &operator=(LockedPtr &&that)
- {
- unlock();
- m_core = that.m_core;
- that.m_core = nullptr;
- }
-
- template<class T1, LockedPtrMode mode1,
- class Enable = std::enable_if_t<canConstructFrom<T1>>>
- LockedPtr(const LockedPtr<T1, mode1> &that)
- {
- m_core = that.m_core;
- lock();
- }
-
- template<class T1, LockedPtrMode mode1,
- class Enable = std::enable_if_t<canConstructFrom<T1>>>
- LockedPtr &operator=(const LockedPtr<T1, mode1> &that)
- {
- unlock();
- m_core = that.m_core;
- lock();
- }
-
- template<class T1,
- class Enable = std::enable_if_t<canConstructFrom<T1>>>
- LockedPtr(LockedPtr<T1, mode> &&that)
- {
- m_core = that.m_core;
- that.m_core = nullptr;
- }
-
- template<class T1,
- class Enable = std::enable_if_t<canConstructFrom<T1>>>
- LockedPtr &operator=(LockedPtr<T1, mode> &&that)
- {
- unlock();
- m_core = that.m_core;
- that.m_core = nullptr;
- }
-
- ~LockedPtr()
- {
- unlock();
- }
-
- T *get() const
- {
- if (m_core) {
- if (mode == LockedPtrMode::Weak)
- return reinterpret_cast<T *>(m_core->data.load(std::memory_order_acquire));
- else
- return reinterpret_cast<T *>(m_core->data.load(std::memory_order_relaxed));
- }
- return nullptr;
- }
-
- void set(T *value)
- {
- static_assert(mode == LockedPtrMode::Exclusive, "");
- DCHECK(m_core);
- m_core->data.store(reinterpret_cast<uintptr_t>(value), std::memory_order_release);
- }
-
- T &operator*() const { return *get(); }
- T *operator->() const { return get(); }
- explicit operator bool() const { return get(); }
-
- bool MaybeValid() const { return m_core; }
-
- static LockedPtr create(T *value)
- {
- return new LockedPtrCore(reinterpret_cast<uintptr_t>(value));
- }
-
-private:
- template<class T1, LockedPtrMode mode1> friend class LockedPtr;
-
- LockedPtr(LockedPtrCore *core)
- : m_core(core)
- {}
-
- void lock()
- {
- if (m_core) {
- ++m_core->refCount;
-
- if (mode == LockedPtrMode::Shared)
- m_core->lock.lockForRead();
- else if (mode == LockedPtrMode::Exclusive)
- m_core->lock.lockForWrite();
- }
- }
-
- void unlock()
- {
- if (m_core) {
- if (mode != LockedPtrMode::Weak)
- m_core->lock.unlock();
-
- if (--m_core->refCount == 0)
- delete m_core;
- }
- }
-
- LockedPtrCore *m_core = nullptr;
-};
-
-// This makes Bind check the pointer before calling the functor.
-template<class T>
-struct IsWeakReceiver<WeakLockedPtr<T>> : std::true_type {};
-
-// By converting the WeakLockedPtr into a SharedLockedPtr we prevent the
-// pointed-to object from being destroyed during the base::Callback::Run call.
-//
-// Unwrap() is called before checking the pointer, so there's no race condition.
-template<class T>
-struct BindUnwrapTraits<WeakLockedPtr<T>>
-{
- static SharedLockedPtr<T> Unwrap(const WeakLockedPtr<T> &o)
- {
- return o;
- }
-};
-
-// Like base::WeakPtrFactory, but InvalidateWeakPtrs *waits* until all currently
-// executing base::Callbacks are finished. Queued up base::Callbacks are still
-// canceled, exactly like with WeakPtrFactory.
-//
-// Consider, for example, the function
-//
-// void fun()
-// {
-// MyClass *myClass = new MyClass;
-// myClass->scheduleDoStuff();
-// delete myClass; // ???
-// }
-//
-// where
-//
-// class MyClass
-// {
-// public:
-// void scheduleDoStuff()
-// {
-// content::BrowserThread::PostTask(
-// content::BrowserThread::IO, FROM_HERE,
-// base::BindOnce(&MyClass::doStuff, m_weakPtrFactory.GetWeakPtr()));
-// }
-// void doStuff();
-// private:
-// //base::WeakPtrFactory m_weakPtrFactory{this};
-// base::LockedPtrFactory m_weakPtrFactory{this};
-// };
-//
-// What happens if the 'delete myClass' line is executed concurrently with
-// MyClass::doStuff?
-//
-// With WeakPtrs we get a segfault or perhaps memory corruption.
-//
-// With LockedPtrs we get no crash and no corruption: LockedPtrFactory's
-// destructor will wait until doStuff is done before continuing.
-template<class T>
-class LockedPtrFactory
-{
-public:
- explicit LockedPtrFactory(T *value)
- : m_ptr(WeakLockedPtr<T>::create(value))
- {}
-
- ~LockedPtrFactory()
- {
- InvalidateWeakPtrs();
- }
-
- WeakLockedPtr<T> GetWeakPtr() { return m_ptr; }
- WeakLockedPtr<const T> GetWeakPtr() const { return m_ptr; }
- SharedLockedPtr<T> GetSharedPtr() { return m_ptr; }
- SharedLockedPtr<const T> GetSharedPtr() const { return m_ptr; }
- ExclusiveLockedPtr<T> GetExclusivePtr() { return m_ptr; }
- ExclusiveLockedPtr<const T> GetExclusivePtr() const { return m_ptr; }
-
- void InvalidateWeakPtrs()
- {
- if (ExclusiveLockedPtr<T> ptr = m_ptr)
- ptr.set(nullptr);
- }
-
-private:
- WeakLockedPtr<T> m_ptr;
-};
-
-} // namespace base
-
-#endif // !LOCKED_PTR_H