xref: /aosp_15_r20/external/cronet/base/functional/disallow_unretained.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2022 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_FUNCTIONAL_DISALLOW_UNRETAINED_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_FUNCTIONAL_DISALLOW_UNRETAINED_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker // IMPORTANT: this is currently experimental. Use with caution, as the
9*6777b538SAndroid Build Coastguard Worker // interaction with various base APIs is still unstable and subject to change.
10*6777b538SAndroid Build Coastguard Worker //
11*6777b538SAndroid Build Coastguard Worker // Types can opt to forbid use of `Unretained()`, et cetera by using this macro
12*6777b538SAndroid Build Coastguard Worker // to annotate their class definition:
13*6777b538SAndroid Build Coastguard Worker //
14*6777b538SAndroid Build Coastguard Worker // class Dangerous {
15*6777b538SAndroid Build Coastguard Worker //   DISALLOW_UNRETAINED();
16*6777b538SAndroid Build Coastguard Worker //  public:
17*6777b538SAndroid Build Coastguard Worker //
18*6777b538SAndroid Build Coastguard Worker //   ...
19*6777b538SAndroid Build Coastguard Worker //
20*6777b538SAndroid Build Coastguard Worker //   void PostAsyncWork() {
21*6777b538SAndroid Build Coastguard Worker //     // Will not compile.
22*6777b538SAndroid Build Coastguard Worker //     task_runner_->PostTask(
23*6777b538SAndroid Build Coastguard Worker //         FROM_HERE,
24*6777b538SAndroid Build Coastguard Worker //         base::BindOnce(&Dangerous::OnAsyncWorkDone, base::Unretained(this)));
25*6777b538SAndroid Build Coastguard Worker //   }
26*6777b538SAndroid Build Coastguard Worker //
27*6777b538SAndroid Build Coastguard Worker //   void OnAsyncWorkDone() {
28*6777b538SAndroid Build Coastguard Worker //     ...
29*6777b538SAndroid Build Coastguard Worker //   }
30*6777b538SAndroid Build Coastguard Worker // };
31*6777b538SAndroid Build Coastguard Worker //
32*6777b538SAndroid Build Coastguard Worker // A type that disallows use of base::Unretained() can still be used with
33*6777b538SAndroid Build Coastguard Worker // callback:
34*6777b538SAndroid Build Coastguard Worker //
35*6777b538SAndroid Build Coastguard Worker // - If a type is only used on one sequence (e.g. `content::RenderFrameHostImpl`
36*6777b538SAndroid Build Coastguard Worker //   may only be used on the UI thread), embed a `base::WeakPtrFactory<T>` and
37*6777b538SAndroid Build Coastguard Worker //   either use:
38*6777b538SAndroid Build Coastguard Worker //
39*6777b538SAndroid Build Coastguard Worker //   - `GetSafeRef()` to bind a `SafeRef<T>` if `this` must *always* still be
40*6777b538SAndroid Build Coastguard Worker //     alive when the callback is invoked, e.g. binding Mojo reply callbacks
41*6777b538SAndroid Build Coastguard Worker //     when making Mojo calls through a `mojo::Remote` owned by `this`.
42*6777b538SAndroid Build Coastguard Worker //
43*6777b538SAndroid Build Coastguard Worker //   - `GetWeakPtr()` to bind a `WeakPtr<T>` if the lifetimes are unclear, e.g.
44*6777b538SAndroid Build Coastguard Worker //     a task posted to main UI task runner, and a strong lifetime assertion is
45*6777b538SAndroid Build Coastguard Worker //     not possible.
46*6777b538SAndroid Build Coastguard Worker //
47*6777b538SAndroid Build Coastguard Worker //   - Note 1: use `WeakPtr<T>` only when appropriate. `WeakPtr<T>` makes it
48*6777b538SAndroid Build Coastguard Worker //     harder to reason about lifetimes; while it is necessary and appropriate
49*6777b538SAndroid Build Coastguard Worker //     in many places, using it unnecessarily makes it hard to understand when
50*6777b538SAndroid Build Coastguard Worker //     one object is guaranteed to outlive another.
51*6777b538SAndroid Build Coastguard Worker //
52*6777b538SAndroid Build Coastguard Worker //   - Note 2: whether `GetSafeRef()` or `GetWeakPtr()` is used, include
53*6777b538SAndroid Build Coastguard Worker //     comments to explain the assumptions behind the selection. Though these
54*6777b538SAndroid Build Coastguard Worker //     comments may become inaccurate over time, they are still valuable
55*6777b538SAndroid Build Coastguard Worker //     to helping when reading unfamiliar code.
56*6777b538SAndroid Build Coastguard Worker //
57*6777b538SAndroid Build Coastguard Worker // - If a type is used on multiple sequences, make it refcounted and either bind
58*6777b538SAndroid Build Coastguard Worker //   a `scoped_refptr<t>` or use `base::RetainedRef()`.
59*6777b538SAndroid Build Coastguard Worker //
60*6777b538SAndroid Build Coastguard Worker // - Consider if callbacks are needed at all; using abstractions like
61*6777b538SAndroid Build Coastguard Worker //   `base::SequenceBound<T>` make it much easier to manage cross-sequence
62*6777b538SAndroid Build Coastguard Worker //   lifetimes and avoid the need to write `base::Unretained()` at all.
63*6777b538SAndroid Build Coastguard Worker #define DISALLOW_UNRETAINED()                                        \
64*6777b538SAndroid Build Coastguard Worker  public:                                                             \
65*6777b538SAndroid Build Coastguard Worker   using DisallowBaseUnretainedMarker [[maybe_unused]] = void;        \
66*6777b538SAndroid Build Coastguard Worker                                                                      \
67*6777b538SAndroid Build Coastguard Worker  private:                                                            \
68*6777b538SAndroid Build Coastguard Worker   /* No-op statement so use of this macro can be followed by `;`. */ \
69*6777b538SAndroid Build Coastguard Worker   static_assert(true)
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker #endif  // BASE_FUNCTIONAL_DISALLOW_UNRETAINED_H_
72