Skip to content

Commit a70101c

Browse files
wilhuffa-maurice
authored andcommitted
Avoid double deletion of internal objects during cleanup.
This has been observed during cleanup when a DocumentReferenceInternal is destroyed, its Future API can end up deleting orphaned Future APIs that contain Futures holding the containing `DocumentReference`. PiperOrigin-RevId: 320260380
1 parent 8714bed commit a70101c

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

firestore/src/common/cleanup.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,19 @@ struct CleanupFn {
4949
private:
5050
template <typename Object>
5151
static void DoCleanup(Object* obj) {
52-
delete obj->internal_;
52+
// Order is crucially important here: under rare conditions, during cleanup,
53+
// the destructor of the `internal_` object can trigger the deletion of the
54+
// containing object. For example, this can happen when the `internal_`
55+
// object destroys its Future API, which deletes a Future referring to the
56+
// public object containing this `internal_` object. See
57+
// http://go/paste/4669581387890688 for an example of what this looks like.
58+
//
59+
// By setting `internal_` to null before deleting it, the destructor of the
60+
// outer object is prevented from deleting `internal_` twice.
61+
auto internal = obj->internal_;
5362
obj->internal_ = nullptr;
63+
64+
delete internal;
5465
}
5566

5667
// `ListenerRegistration` objects differ from the common pattern.

0 commit comments

Comments
 (0)