6#ifndef THREAD_FIBER_CASES_H_
7#define THREAD_FIBER_CASES_H_
14#include "absl/container/inlined_vector.h"
15#include "absl/time/time.h"
16#include "thread/boost_primitives.h"
22concept IsPointer = std::is_pointer_v<T>;
25concept IsNonConstPointer =
26 IsPointer<T> && !std::is_const_v<std::remove_pointer_t<T>>;
29concept IsConstPointer =
30 IsPointer<T> && std::is_const_v<std::remove_pointer_t<T>>;
33 static constexpr int kNonePicked = -1;
35 bool TryPick(
int index) {
36 if (picked_case_index != kNonePicked) {
39 picked_case_index = index;
45 bool WaitForPick(absl::Time deadline = absl::InfiniteFuture());
49 int picked_case_index = kNonePicked;
59 Case(internal::Selectable* selectable) : selectable(selectable) {}
61 Case(internal::Selectable* selectable, internal::IsPointer
auto... args)
62 : selectable(selectable) {
63 (arguments.push_back(
const_cast<void*
>(
static_cast<const void*
>(args))),
70 template <
typename... Args>
71 Case(
bool, Args...) =
delete;
75 arguments.push_back(
const_cast<void*
>(
static_cast<const void*
>(arg)));
80 arguments.push_back(
static_cast<void*
>(arg));
84 if (index < 0 ||
static_cast<std::size_t
>(index) >= arguments.size()) {
87 return arguments[
static_cast<std::size_t
>(index)];
92 return static_cast<T*
>(GetArgPtr(index));
95 std::size_t
GetNumArgs()
const {
return arguments.size(); }
101struct CaseInSelectClause {
102 const Case* case_ptr =
nullptr;
104 std::shared_ptr<Selector> selector;
105 CaseInSelectClause* prev =
nullptr;
106 CaseInSelectClause* next =
nullptr;
108 const Case* GetCase()
const {
return case_ptr; }
110 bool TryPick() {
return selector->TryPick(index); }
112 bool Handle(
bool enqueue);
120 virtual ~Selectable() =
default;
121 virtual bool Handle(CaseInSelectClause* case_state,
bool enqueue) = 0;
122 virtual void Unregister(CaseInSelectClause* case_state) = 0;
125inline bool CaseInSelectClause::Handle(
bool enqueue) {
126 return GetCase()->selectable->Handle(
this, enqueue);
129inline void CaseInSelectClause::Unregister() {
130 GetCase()->selectable->Unregister(
this);
133inline void PushBack(CaseInSelectClause** head, CaseInSelectClause* element) {
134 if (element->prev !=
nullptr) {
137 if (*head ==
nullptr) {
138 element->next = element;
139 element->prev = element;
143 element->next = *head;
144 element->prev = (*head)->prev;
145 element->prev->next = element;
146 element->next->prev = element;
150 CaseInSelectClause* element) {
151 if (element->prev ==
nullptr || *head ==
nullptr) {
154 if (element->next == element) {
157 element->next->prev = element->prev;
158 element->prev->next = element->next;
159 if (*head == element) {
160 *head = element->next;
163 element->prev =
nullptr;
164 element->next =
nullptr;
static bool reader selector mu
Definition channel_waiter_state.cc:61
void PushBack(CaseInSelectClause **head, CaseInSelectClause *element)
Definition cases.h:133
void UnlinkFromList(CaseInSelectClause **head, CaseInSelectClause *element)
Definition cases.h:149
absl::InlinedVector< CaseInSelectClause, 4 > CaseStateArray
Definition cases.h:116
absl::InlinedVector< Case, 4 > CaseArray
Definition cases.h:98
A Case represents a selectable case in a Select statement.
Definition cases.h:55
absl::InlinedVector< void *, 2 > arguments
Definition cases.h:57
void AddArg(T *arg)
Definition cases.h:79
Case(bool, Args...)=delete
T * GetArgPtr(int index) const
Definition cases.h:91
void * GetArgPtr(int index) const
Definition cases.h:83
Case(internal::Selectable *selectable)
Definition cases.h:59
internal::Selectable * selectable
Definition cases.h:56
Case(const Case &)=default
Case(internal::Selectable *selectable, internal::IsPointer auto... args)
Definition cases.h:61
Case & operator=(const Case &)=default
std::size_t GetNumArgs() const
Definition cases.h:95
void AddArg(const T *arg)
Definition cases.h:74