• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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 <vector>
17 
18 #include "pw_assert/assert.h"
19 #include "pw_async2/dispatcher_base.h"
20 
21 namespace pw::async2 {
22 
23 class Dispatcher final : public DispatcherImpl<Dispatcher> {
24  public:
Dispatcher()25   Dispatcher() { PW_ASSERT_OK(NativeInit()); }
26   Dispatcher(Dispatcher&) = delete;
27   Dispatcher(Dispatcher&&) = delete;
28   Dispatcher& operator=(Dispatcher&) = delete;
29   Dispatcher& operator=(Dispatcher&&) = delete;
~Dispatcher()30   ~Dispatcher() final { Deregister(); }
31 
32   Status NativeInit();
33 
34   enum FileDescriptorType {
35     kReadable = 1 << 0,
36     kWritable = 1 << 1,
37     kReadWrite = kReadable | kWritable,
38   };
39 
40   Status NativeRegisterFileDescriptor(int fd, FileDescriptorType type);
41   Status NativeUnregisterFileDescriptor(int fd);
42 
NativeAddReadWakerForFileDescriptor(int fd,Waker && waker)43   void NativeAddReadWakerForFileDescriptor(int fd, Waker&& waker) {
44     NativeAddWakerForFileDescriptor(
45         fd, FileDescriptorType::kReadable, std::move(waker));
46   }
47 
NativeAddWriteWakerForFileDescriptor(int fd,Waker && waker)48   void NativeAddWriteWakerForFileDescriptor(int fd, Waker&& waker) {
49     NativeAddWakerForFileDescriptor(
50         fd, FileDescriptorType::kWritable, std::move(waker));
51   }
52 
53  private:
54   static constexpr size_t kMaxEventsToProcessAtOnce = 5;
55 
56   struct FdWaker {
57     int fd;
58     FileDescriptorType type;
59     Waker waker;
60   };
61 
62   void DoWake() final;
63   Poll<> DoRunUntilStalled(Task* task);
64   void DoRunToCompletion(Task* task);
65   friend class DispatcherImpl<Dispatcher>;
66 
67   Status NativeWaitForWake();
68   void NativeFindAndWakeFileDescriptor(int fd, FileDescriptorType type);
69 
NativeAddWakerForFileDescriptor(int fd,FileDescriptorType type,Waker && waker)70   void NativeAddWakerForFileDescriptor(int fd,
71                                        FileDescriptorType type,
72                                        Waker&& waker) {
73     fd_wakers_.push_back({fd, type, std::move(waker)});
74   }
75 
76   int epoll_fd_;
77   int notify_fd_;
78   int wait_fd_;
79 
80   std::vector<FdWaker> fd_wakers_;
81 };
82 
83 }  // namespace pw::async2
84