Chromium Embedded Framework (CEF)  145.0.1+g472e75d+chromium-145.0.7632.5
cef_weak_ptr.h File Reference

Weak pointers are pointers to an object that do not affect its lifetime, and which may be invalidated (i.e. More...

#include <cstddef>
#include <concepts>
#include <type_traits>
#include <utility>
#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::WeakPtrFactoryBase
 
class  base::WeakPtr< T >
 The WeakPtr class holds a weak reference to |T*|. More...
 
class  base::WeakPtrFactory< T >
 A class may be composed of a WeakPtrFactory and thereby control how it exposes weak pointers to itself. 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)
 

Detailed Description

Weak pointers are pointers to an object that do not affect its lifetime, and which 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) {
     // Move WeakPtr when possible to avoid atomic refcounting churn on its
     // internal state.
     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 thread 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, 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 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.