Chromium Embedded Framework (CEF)
115.2.0+g096e3eb+chromium-115.0.5790.13
|
Weak pointers are pointers to an object that do not affect its lifetime. More...
#include <cstddef>
#include <type_traits>
#include "include/base/cef_atomic_flag.h"
#include "include/base/cef_logging.h"
#include "include/base/cef_ref_counted.h"
#include "include/base/cef_thread_checker.h"
Classes | |
class | base::cef_internal::WeakReference |
class | base::cef_internal::WeakReference::Flag |
class | base::cef_internal::WeakReferenceOwner |
class | base::cef_internal::WeakPtrBase |
class | base::cef_internal::SupportsWeakPtrBase |
class | base::WeakPtr< T > |
The WeakPtr class holds a weak reference to |T*|. More... | |
class | base::cef_internal::WeakPtrFactoryBase |
class | base::WeakPtrFactory< T > |
A class may be composed of a WeakPtrFactory and thereby control how it exposes weak pointers to itself. More... | |
class | base::SupportsWeakPtr< T > |
A class may extend from SupportsWeakPtr to let others take weak pointers to it. More... | |
Namespaces | |
base | |
base::cef_internal | |
Functions | |
template<class T > | |
bool | base::operator!= (const WeakPtr< T > &weak_ptr, std::nullptr_t) |
Allow callers to compare WeakPtrs against nullptr to test validity. More... | |
template<class T > | |
bool | base::operator!= (std::nullptr_t, const WeakPtr< T > &weak_ptr) |
template<class T > | |
bool | base::operator== (const WeakPtr< T > &weak_ptr, std::nullptr_t) |
template<class T > | |
bool | base::operator== (std::nullptr_t, const WeakPtr< T > &weak_ptr) |
template<typename Derived > | |
WeakPtr< Derived > | base::AsWeakPtr (Derived *t) |
Helper function that uses type deduction to safely return a WeakPtr<Derived> when Derived doesn't directly extend SupportsWeakPtr<Derived>, instead it extends a Base that extends SupportsWeakPtr<Base>. More... | |
Weak pointers are pointers to an object that do not affect its lifetime.
They may be invalidated (i.e. reset to nullptr) by the object, or its owner, at any time, most commonly when the object is about to be deleted.
Weak pointers are useful when an object needs to be accessed safely by one or more objects other than its owner, and those callers can cope with the object vanishing and e.g. tasks posted to it being silently dropped. Reference-counting such an object would complicate the ownership graph and make it harder to reason about the object's lifetime.
EXAMPLE:
class Controller { public: void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); } void WorkComplete(const Result& result) { ... } private: // Member variables should appear before the WeakPtrFactory, to ensure // that any WeakPtrs to Controller are invalidated before its members // variable's destructors are executed, rendering them invalid. WeakPtrFactory<Controller> weak_factory_{this}; }; class Worker { public: static void StartNew(WeakPtr<Controller> controller) { Worker* worker = new Worker(std::move(controller)); // Kick off asynchronous processing... } private: Worker(WeakPtr<Controller> controller) : controller_(std::move(controller)) {} void DidCompleteAsynchronousProcessing(const Result& result) { if (controller_) controller_->WorkComplete(result); } WeakPtr<Controller> controller_; };
With this implementation a caller may use SpawnWorker() to dispatch multiple Workers and subsequently delete the Controller, without waiting for all Workers to have completed.
IMPORTANT: Thread-safety
Weak pointers may be passed safely between threads, but must always be dereferenced and invalidated on the same ThreaddTaskRunner otherwise checking the pointer would be racey.
To ensure correct use, the first time a WeakPtr issued by a WeakPtrFactory is dereferenced, the factory and its WeakPtrs become bound to the calling thread or current ThreaddWorkerPool token, and cannot be dereferenced or invalidated on any other task runner. Bound WeakPtrs can still be handed off to other task runners, e.g. to use to post tasks back to object on the bound thread.
If all WeakPtr objects are destroyed or invalidated then the factory is unbound from the ThreadedTaskRunner/Thread. The WeakPtrFactory may then be destroyed, or new WeakPtr objects may be used, from a different thread.
Thus, at least one WeakPtr object must exist and have been dereferenced on the correct thread to enforce that other WeakPtr objects will enforce they are used on the desired thread.