Skip to content

Commit

Permalink
pw_async2: Add EnqueueHeapFunc
Browse files Browse the repository at this point in the history
This function is designed to allow for easy
transition from heap-allocated callback-based APIs or uses of
the deprecated pw::async HeapDispatcher.

Change-Id: I067c938b4f8ea931bad4e7c71e6869e4a707a150
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/242035
Commit-Queue: Taylor Cramer <[email protected]>
Reviewed-by: Aaron Green <[email protected]>
Lint: Lint 🤖 <[email protected]>
  • Loading branch information
cramertj authored and CQ Bot Account committed Oct 16, 2024
1 parent cbbb308 commit 068949b
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ _doxygen_input_files = [ # keep-sorted: start
"$dir_pw_async2/public/pw_async2/coro_or_else_task.h",
"$dir_pw_async2/public/pw_async2/dispatcher.h",
"$dir_pw_async2/public/pw_async2/dispatcher_base.h",
"$dir_pw_async2/public/pw_async2/enqueue_heap_func.h",
"$dir_pw_async2/public/pw_async2/once_sender.h",
"$dir_pw_async2/public/pw_async2/pend_func_task.h",
"$dir_pw_async2/public/pw_async2/pendable_as_task.h",
Expand Down
23 changes: 23 additions & 0 deletions pw_async2/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,29 @@ pw_cc_test(
],
)

cc_library(
name = "enqueue_heap_func",
hdrs = [
"public/pw_async2/enqueue_heap_func.h",
],
includes = ["public"],
deps = [
":dispatcher",
],
)

pw_cc_test(
name = "enqueue_heap_func_test",
srcs = [
"enqueue_heap_func_test.cc",
],
deps = [
":dispatcher",
":enqueue_heap_func",
"//pw_unit_test",
],
)

sphinx_docs_library(
name = "docs",
srcs = [
Expand Down
16 changes: 16 additions & 0 deletions pw_async2/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -270,11 +270,27 @@ pw_test("simulated_time_provider_test") {
]
}

pw_source_set("enqueue_heap_func") {
public = [ "public/pw_async2/enqueue_heap_func.h" ]
public_configs = [ ":public_include_path" ]
public_deps = [ ":dispatcher" ]
}

pw_test("enqueue_heap_func_test") {
enable_if = pw_async2_DISPATCHER_BACKEND != ""
sources = [ "enqueue_heap_func_test.cc" ]
deps = [
":dispatcher",
":enqueue_heap_func",
]
}

pw_test_group("tests") {
tests = [
":allocate_task_test",
":dispatcher_test",
":dispatcher_thread_test",
":enqueue_heap_func_test",
":poll_test",
":pend_func_task_test",
":pendable_as_task_test",
Expand Down
17 changes: 17 additions & 0 deletions pw_async2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -261,5 +261,22 @@ if((NOT "${pw_chrono.system_clock_BACKEND}" STREQUAL "") AND
)
endif()

pw_add_library(pw_async2.enqueue_heap_func INTERFACE
HEADERS
public/pw_async2/enqueue_heap_func.h
PUBLIC_DEPS
pw_async2.dispatcher
)

pw_add_test(pw_async2.enqueue_heap_func_test
SOURCES
enqueue_heap_func_test.cc
PRIVATE_DEPS
pw_async2.dispatcher
pw_async2.enqueue_heap_func
GROUPS
modules
pw_async2
)

add_subdirectory(examples)
2 changes: 2 additions & 0 deletions pw_async2/docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ C++ API reference
-------------
C++ Utilities
-------------
.. doxygenfunction:: pw::async2::EnqueueHeapFunc

.. doxygenfunction:: pw::async2::AllocateTask(pw::allocator::Allocator& allocator, Pendable&& pendable)

.. doxygenfunction:: pw::async2::AllocateTask(pw::allocator::Allocator& allocator, Args&&... args)
Expand Down
37 changes: 37 additions & 0 deletions pw_async2/enqueue_heap_func_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2024 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.

#include "pw_async2/enqueue_heap_func.h"

#include "pw_async2/dispatcher_base.h"
#include "pw_status/status.h"
#include "pw_unit_test/framework.h"

namespace {

using ::pw::async2::Dispatcher;
using ::pw::async2::EnqueueHeapFunc;

TEST(Dispatcher, DispatcherRunsEnqueuedTasksOnce) {
Dispatcher dispatcher;
int ran = 0;
EnqueueHeapFunc(dispatcher, [&ran]() { ++ran; });
EXPECT_EQ(ran, 0);
EXPECT_TRUE(dispatcher.RunUntilStalled().IsReady());
EXPECT_EQ(ran, 1);
EXPECT_TRUE(dispatcher.RunUntilStalled().IsReady());
EXPECT_EQ(ran, 1);
}

} // namespace
51 changes: 51 additions & 0 deletions pw_async2/public/pw_async2/enqueue_heap_func.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2023 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 "pw_async2/dispatcher.h"

namespace pw::async2 {
namespace internal {

template <typename Func>
class RunHeapFuncTask : public Task {
public:
static Task& New(Func&& func) {
return *(new RunHeapFuncTask(std::forward<Func>(func)));
}

private:
RunHeapFuncTask(Func&& func) : func_(std::forward<Func>(func)) {}
Poll<> DoPend(Context&) final {
func_();
return Ready();
}
void DoDestroy() final { delete this; }
Func func_;
};

} // namespace internal

/// Heap-allocates space for ``func`` and enqueues it to run on ``dispatcher``.
///
/// ``func`` must be a no-argument callable that returns ``void``.
///
/// This function requires heap allocation using ``new`` be available.
template <typename Func>
void EnqueueHeapFunc(Dispatcher& dispatcher, Func&& func) {
return dispatcher.Post(
internal::RunHeapFuncTask<Func>::New(std::forward<Func>(func)));
}

} // namespace pw::async2

0 comments on commit 068949b

Please sign in to comment.