15#ifndef THREAD_FIBER_CASES_H_ 
   16#define THREAD_FIBER_CASES_H_ 
   18#include "thread/boost_primitives.h" 
   23concept IsPointer = std::is_pointer_v<T>;
 
   26concept IsNonConstPointer =
 
   27    IsPointer<T> && !std::is_const_v<std::remove_pointer_t<T>>;
 
   30concept IsConstPointer =
 
   31    IsPointer<T> && std::is_const_v<std::remove_pointer_t<T>>;
 
   34  static constexpr int kNonePicked = -1;
 
   36  bool TryPick(
int case_index) ABSL_EXCLUSIVE_LOCKS_REQUIRED
 
   39    if (picked_case_index != kNonePicked) {
 
   43    picked_case_index = case_index;
 
   49  bool WaitForPickUntil(absl::Time deadline) ABSL_SHARED_LOCKS_REQUIRED
 
   52    while (picked_case_index == internal::Selector::kNonePicked) {
 
   53      if (cv.WaitWithDeadline(&mu, deadline) &&
 
   54          picked_case_index == internal::Selector::kNonePicked) {
 
   62  int picked_case_index{kNonePicked};
 
   64  act::concurrency::impl::Mutex mu;
 
   65  act::concurrency::impl::CondVar cv ABSL_GUARDED_BY(mu);
 
   80struct [[nodiscard]] Case {
 
   81  internal::Selectable* absl_nonnull selectable;
 
   82  absl::InlinedVector<void * absl_nullable, 2> arguments;
 
   84  Case(internal::Selectable* absl_nullable s = 
nullptr) : selectable(s) {}
 
   86  Case(internal::Selectable* absl_nullable s, internal::IsPointer 
auto... args)
 
   91  Case(
const Case&) = 
default;
 
   92  Case& operator=(
const Case&) = 
default;
 
   96  template <
typename... Args>
 
   97  Case(
bool, Args... args) = 
delete;
 
   99  void AddArgs(internal::IsNonConstPointer 
auto arg) {
 
  100    arguments.push_back(
static_cast<void*
>(arg));
 
  103  void AddArgs(internal::IsConstPointer 
auto arg) {
 
  104    arguments.push_back(
const_cast<void*
>(
static_cast<const void*
>(arg)));
 
  107  void AddArgs(internal::IsPointer 
auto... args) { (AddArgs(args), ...); }
 
  109  [[nodiscard]] 
void* absl_nonnull GetArgPtr(
int index)
 const {
 
  110    if (index < 0 || index >= arguments.size()) {
 
  111      LOG(FATAL) << 
"Case::GetArgOrDie: index out of bounds: " << index
 
  112                 << 
", arguments.size() = " << arguments.size();
 
  115    return arguments[index];
 
  118  template <
typename T>
 
  119  [[nodiscard]] T* absl_nonnull GetArgPtr(
int index)
 const {
 
  120    return static_cast<T*
>(GetArgPtr(index));
 
  123  [[nodiscard]] 
size_t GetNumArgs()
 const { 
return arguments.size(); }
 
 
  128typedef absl::InlinedVector<Case, 4> CaseArray;
 
  139struct CaseInSelectClause {
 
  140  const Case* absl_nonnull case_ptr;  
 
  142  internal::Selector* absl_nonnull
 
  144  CaseInSelectClause* absl_nullable
 
  146  CaseInSelectClause* absl_nullable next;
 
  148  [[nodiscard]] 
const Case* absl_nonnull GetCase()
 const { 
return case_ptr; }
 
  156  bool TryPick() ABSL_EXCLUSIVE_LOCKS_REQUIRED(selector->mu) {
 
  157    return selector->TryPick(index);
 
  160  bool Handle(
bool enqueue);
 
  164using CaseStateArray = absl::InlinedVector<CaseInSelectClause, 4>;
 
  172  virtual ~Selectable() = 
default;
 
  197  virtual bool Handle(CaseInSelectClause* absl_nonnull case_state,
 
  205  virtual void Unregister(CaseInSelectClause* absl_nonnull case_state) = 0;
 
  208inline bool CaseInSelectClause::Handle(
bool enqueue) {
 
  209  return GetCase()->selectable->Handle(
this, enqueue);
 
  212inline void CaseInSelectClause::Unregister() {
 
  213  GetCase()->selectable->Unregister(
this);
 
  218inline void PushBack(CaseInSelectClause* absl_nonnull* absl_nonnull head,
 
  219                     CaseInSelectClause* absl_nonnull element) {
 
  220  if (*head == 
nullptr) {
 
  222    element->next = element;
 
  223    element->prev = element;
 
  227    element->next = *head;
 
  228    element->prev = element->next->prev;
 
  229    element->prev->next = element;
 
  230    element->next->prev = element;
 
  234inline void UnlinkFromList(CaseInSelectClause* absl_nonnull* absl_nonnull head,
 
  235                           CaseInSelectClause* absl_nonnull element) {
 
  236  if (element->next == element) {
 
  241    element->next->prev = element->prev;
 
  242    element->prev->next = element->next;
 
  243    if (*head == element) {
 
  244      *head = element->next;
 
  249  element->prev = 
nullptr;
 
A Case represents a selectable case in a Select statement.
Definition cases.h:80