C/C++ API Reference
Loading...
Searching...
No Matches
async_count_and_capacity.h
1// Copyright 2025 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include "pw_async2/context.h"
17#include "pw_async2/poll.h"
18#include "pw_async2/waker_queue.h"
19#include "pw_containers/internal/count_and_capacity.h"
20
21namespace pw::containers::internal {
22
34template <typename SizeType, size_t kMaxWakers = 1>
36 public:
37 using size_type = SizeType;
38
39 constexpr explicit AsyncCountAndCapacity(size_type capacity)
40 : count_and_capacity_(capacity) {}
42 *this = std::move(other);
43 }
44 constexpr AsyncCountAndCapacity& operator=(
45 AsyncCountAndCapacity&& other) noexcept {
46 count_and_capacity_ = std::move(other.count_and_capacity_);
47 pushes_reserved_ = std::exchange(other.pushes_reserved_, 0);
48 pop_reserved_ = std::exchange(other.pop_reserved_, false);
49 wakers_ = std::move(other.wakers_);
50 return *this;
51 }
52
53 constexpr size_type capacity() const noexcept {
54 return count_and_capacity_.capacity();
55 }
56 constexpr size_type count() const noexcept {
57 return count_and_capacity_.count();
58 }
59
60 constexpr void SetCount(size_type count) {
61 count_and_capacity_.SetCount(count);
62 wakers_.WakeAll();
63 }
64
65 // Called by GenericDeque::PushBack/PushFront
66 constexpr void IncrementCount(size_type n = 1) {
67 count_and_capacity_.IncrementCount(n);
68 pushes_reserved_ -= std::min(n, pushes_reserved_);
69 wakers_.WakeAll();
70 }
71
72 // Called by GenericDeque::PopBack/PopFront
73 constexpr void DecrementCount(size_type n = 1) {
74 count_and_capacity_.DecrementCount(n);
75 pop_reserved_ = false;
76 wakers_.WakeAll();
77 }
78
82 async2::Poll<> PendHasSpace(async2::Context& context, size_type num) {
83 PW_ASSERT(num <= capacity());
84 if (pushes_reserved_ == 0 && num <= capacity() - count()) {
85 pushes_reserved_ = num;
86 return async2::Ready();
87 }
89 context, wakers_, "waiting for space for items in container");
90 return async2::Pending();
91 }
92
95 if (!pop_reserved_ && count() != 0) {
96 pop_reserved_ = true;
97 return async2::Ready();
98 }
99 PW_ASYNC_STORE_WAKER(context, wakers_, "waiting for items in container");
100 return async2::Pending();
101 }
102
103 constexpr void SetCapacity(size_type capacity) {
104 count_and_capacity_.SetCapacity(capacity);
105 wakers_.WakeAll();
106 }
107
108 private:
109 CountAndCapacity<size_type> count_and_capacity_;
110 size_type pushes_reserved_ = 0;
111 bool pop_reserved_ = false;
113};
114
115} // namespace pw::containers::internal
Definition: context.h:55
Definition: poll.h:60
Definition: waker_queue.h:65
Definition: async_count_and_capacity.h:35
async2::Poll PendHasSpace(async2::Context &context, size_type num)
Definition: async_count_and_capacity.h:82
async2::Poll PendNotEmpty(async2::Context &context)
Waits until an item is available in the container.
Definition: async_count_and_capacity.h:94
constexpr PendingType Pending()
Returns a value indicating that an operation was not yet able to complete.
Definition: poll.h:271
#define PW_ASYNC_STORE_WAKER(context, waker_or_queue_out, wait_reason_string)
Definition: waker.h:60
constexpr Poll Ready()
Returns a value indicating completion.
Definition: poll.h:255