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