-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pw_bluetooth: Specify the Deleter when using std::unique_ptr
In several cases we use std::unique_ptr<T> to return an object with RAII semantics, meaning that some action is needed by the backend to release the resource when the object goes out of scope. However, using using std::unique_ptr<T> with the default deleter forces the pw_bluetooth backend to use new/delete to allocate the T interface implementation. This patch introduces a RaiiPtr<Api, void (Api::*OnDestroy)()> template class as an alias of std::unique_ptr with a custom deleter that calls the Api::OnDestroy parametric method instead of calling "delete". This template class is used instead of the plain std::unique_ptr when returning objects from the pw_bluetooth API for the all the "Api" classes with only pure virtual methods. In all 5 cases where this pattern was used the abstract class has one more private pure virtual method (the one used as Api::OnDestroy parameter) which must be implemented by the backend. This allows a backend to manage the memory for the returned objects with something other than new/delete, for example it can return a RaiiPtr to a std::optional instance or to one of the existing pre-allocated objects and re-use them when needed. This is particularly useful in cases where there can only be a fixed small number of objects for the given type, like in the Scan or AdvertisingParameters case where there is only one object at a time. Bug: 250930246 Change-Id: I724ff5135e0f73f5fb74c7fc92abdffa6a9e2d2d Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/113210 Reviewed-by: Wyatt Hepler <hepler@google.com> Commit-Queue: Alex Deymo <deymo@google.com> Reviewed-by: Ben Lawson <benlawson@google.com>
- Loading branch information
Showing
9 changed files
with
158 additions
and
28 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright 2022 The Pigweed Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
// use this file except in compliance with the License. You may obtain a copy of | ||
// the License at | ||
// | ||
// https://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
// License for the specific language governing permissions and limitations under | ||
// the License. | ||
#pragma once | ||
|
||
#include <memory> | ||
#include <type_traits> | ||
|
||
namespace pw::bluetooth::internal { | ||
|
||
// Helper deleter struct to call the OnDestroy template parameter method when | ||
// RaiiPtr<Api, OnDestroy> is destroyed. | ||
template <class Api, void (Api::*OnDestroy)()> | ||
struct RaiiPtrDeleter { | ||
void operator()(Api* api) { (api->*OnDestroy)(); } | ||
}; | ||
|
||
// Smart pointer class to expose an API with RAII semantics that calls a | ||
// specific method of the API implementation when it is destroyed, instead of | ||
// calling delete on the API object like the default std::unique_ptr deleter | ||
// behavior. This allows to be used like if it was a std::unique_ptr<API> but | ||
// leaving the memory management implementation details up to the backend | ||
// implementing the API. | ||
// | ||
// Example usage: | ||
// class SomeApi { | ||
// public: | ||
// virtual ~SomeApi() = default; | ||
// | ||
// virtual void MethodOne() = 0; | ||
// virtual void MethodTwo(int) = 0; | ||
// | ||
// private: | ||
// // Method used to release the resource in the backend. | ||
// virtual void DeleteResource() = 0; | ||
// | ||
// public: | ||
// using Ptr = RaiiPtr<SomeApi, &SomeApi::DeleteResource>; | ||
// }; | ||
// | ||
// // The concrete backend implementation. | ||
// class BackendImplementation final : public SomeApi { | ||
// public: | ||
// void MethodOne() override { ... } | ||
// void MethodTwo(int) override { ... } | ||
// void DeleteResource() override { ... } | ||
// }; | ||
// | ||
// // Example using a static global resource object. GetResource should check | ||
// // whether the global resource is in use. | ||
// BackendImplementation backend_impl; | ||
// SomeApi::Ptr GetResource() { ...; return &backend_impl; } | ||
// | ||
template <class Api, void (Api::*OnDestroy)()> | ||
using RaiiPtr = std::unique_ptr<Api, RaiiPtrDeleter<Api, OnDestroy>>; | ||
|
||
} // namespace pw::bluetooth::internal |
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