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 <unordered_map> 17 18 #include "pw_assert/assert.h" 19 #include "pw_async2/dispatcher_base.h" 20 21 namespace pw::async2::backend { 22 23 class NativeDispatcher final : public NativeDispatcherBase { 24 public: NativeDispatcher()25 NativeDispatcher() { PW_ASSERT_OK(NativeInit()); } 26 27 Status NativeInit(); 28 29 enum FileDescriptorType { 30 kReadable = 1 << 0, 31 kWritable = 1 << 1, 32 kReadWrite = kReadable | kWritable, 33 }; 34 35 Status NativeRegisterFileDescriptor(int fd, FileDescriptorType type); 36 Status NativeUnregisterFileDescriptor(int fd); 37 NativeAddReadWakerForFileDescriptor(int fd)38 Waker& NativeAddReadWakerForFileDescriptor(int fd) { 39 return wakers_[fd].read; 40 } 41 NativeAddWriteWakerForFileDescriptor(int fd)42 Waker& NativeAddWriteWakerForFileDescriptor(int fd) { 43 return wakers_[fd].write; 44 } 45 46 private: 47 friend class ::pw::async2::Dispatcher; 48 49 static constexpr size_t kMaxEventsToProcessAtOnce = 5; 50 51 struct ReadWriteWaker { 52 Waker read; 53 Waker write; 54 }; 55 56 void DoWake() final; 57 Poll<> DoRunUntilStalled(Dispatcher&, Task* task); 58 void DoRunToCompletion(Dispatcher&, Task* task); 59 60 Status NativeWaitForWake(); 61 void NativeFindAndWakeFileDescriptor(int fd, FileDescriptorType type); 62 63 int epoll_fd_; 64 int notify_fd_; 65 int wait_fd_; 66 67 std::unordered_map<int, ReadWriteWaker> wakers_; 68 }; 69 70 } // namespace pw::async2::backend 71