forked from grpc/grpc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RefCounted and friends] Fix type safety of ref-counted types.
Previously, `RefCountedPtr<>` and `WeakRefCountedPtr<>` incorrectly allowed implicit casting of any type to any other type. This hadn't caused a problem until recently, but now that it has, we need to fix it. I have fixed this by changing these smart pointer types to allow type conversions only when the type used is convertible to the type of the smart pointer. This means that if `Subclass` inherits from `Base`, then we can set a `RefCountedPtr<BaseClass>` to a value of type `RefCountedPtr<Subclass>`, but we cannot do the reverse. We had been (ab)using this bug to make it more convenient to deal with down-casting in subclasses of ref-counted types. For example, because `Resolver` inherits from `InternallyRefCounted<Resolver>`, calling `Ref()` on a subclass of `Resolver` will return `RefCountedPtr<Resolver>` rather than returning the subclass's type. The ability to implicitly convert to the subclass type made this a bit easier to deal with. Now that that ability is gone, we need a different way of dealing with that problem. I considered several ways of dealing with this, but none of them are quite as ergonomic as I would ideally like. For now, I've settled on requiring callers to explicitly down-cast as needed, although I have provided some utility functions to make this slightly easier: - `RefCounted<>`, `InternallyRefCounted<>`, and `DualRefCounted<>` all provide a templated `RefAsSubclass<>()` method that will return a new ref as a subclass. The type used with `RefAsSubclass()` must be a subclass of the type passed to `RefCounted<>`, `InternallyRefCounted<>`, or `DualRefCounted<>`. - In addition, `DualRefCounted<>` provides a templated `WeakRefAsSubclass<T>()` method. This is the same as `RefAsSubclass()`, except that it returns a weak ref instead of a strong ref. - In `RefCountedPtr<>`, I have added a new `Ref()` method that takes debug tracing parameters. This can be used instead of calling `Ref()` on the underlying object in cases where the caller already has a `RefCountedPtr<>` and is calling `Ref()` only to specify the debug tracing parameters. Using this method on `RefCountedPtr<>` is more ergonomic, because the smart pointer is already using the right subclass, so no down-casting is needed. - In `WeakRefCountedPtr<>`, I have added a new `WeakRef()` method that takes debug tracing parameters. This is the same as the new `Ref()` method on `RefCountedPtr<>`. - In both `RefCountedPtr<>` and `WeakRefCountedPtr<>`, I have added a templated `TakeAsSubclass<>()` method that takes the ref out of the smart pointer and returns a new smart pointer of the down-casted type. Just as with the `RefAsSubclass()` method above, the type used with `TakeAsSubclass()` must be a subclass of the type passed to `RefCountedPtr<>` or `WeakRefCountedPtr<>`. Note that I have *not* provided an `AsSubclass<>()` variant of the `RefIfNonZero()` methods. Those methods are used relatively rarely, so it's not as important for them to be quite so ergonomic. Callers of these methods that need to down-cast can use `RefIfNonZero().TakeAsSubclass<>()`. PiperOrigin-RevId: 592327447
- Loading branch information
1 parent
85cede5
commit 3e785d3
Showing
53 changed files
with
487 additions
and
295 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.