1 // Copyright 2022 The gRPC Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://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,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_EVENT_POLLER_H
16 #define GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_EVENT_POLLER_H
17 #include <grpc/support/port_platform.h>
18 
19 #include <string>
20 
21 #include "absl/functional/any_invocable.h"
22 #include "absl/status/status.h"
23 #include "absl/strings/string_view.h"
24 
25 #include <grpc/event_engine/event_engine.h>
26 
27 #include "src/core/lib/event_engine/poller.h"
28 #include "src/core/lib/event_engine/posix_engine/posix_engine_closure.h"
29 
30 namespace grpc_event_engine {
31 namespace experimental {
32 
33 class Scheduler {
34  public:
35   virtual void Run(experimental::EventEngine::Closure* closure) = 0;
36   virtual void Run(absl::AnyInvocable<void()>) = 0;
37   virtual ~Scheduler() = default;
38 };
39 
40 class PosixEventPoller;
41 
42 class EventHandle {
43  public:
44   virtual int WrappedFd() = 0;
45   // Delete the handle and optionally close the underlying file descriptor if
46   // release_fd != nullptr. The on_done closure is scheduled to be invoked
47   // after the operation is complete. After this operation, NotifyXXX and SetXXX
48   // operations cannot be performed on the handle. In general, this method
49   // should only be called after ShutdownHandle and after all existing NotifyXXX
50   // closures have run and there is no waiting NotifyXXX closure.
51   virtual void OrphanHandle(PosixEngineClosure* on_done, int* release_fd,
52                             absl::string_view reason) = 0;
53   // Shutdown a handle. If there is an attempt to call NotifyXXX operations
54   // after Shutdown handle, those closures will be run immediately with the
55   // absl::Status provided here being passed to the callbacks enclosed within
56   // the PosixEngineClosure object.
57   virtual void ShutdownHandle(absl::Status why) = 0;
58   // Schedule on_read to be invoked when the underlying file descriptor
59   // becomes readable. When the on_read closure is run, it may check
60   // if the handle is shutdown using the IsHandleShutdown method and take
61   // appropriate actions (for instance it should not try to invoke another
62   // recursive NotifyOnRead if the handle is shutdown).
63   virtual void NotifyOnRead(PosixEngineClosure* on_read) = 0;
64   // Schedule on_write to be invoked when the underlying file descriptor
65   // becomes writable. When the on_write closure is run, it may check
66   // if the handle is shutdown using the IsHandleShutdown method and take
67   // appropriate actions (for instance it should not try to invoke another
68   // recursive NotifyOnWrite if the handle is shutdown).
69   virtual void NotifyOnWrite(PosixEngineClosure* on_write) = 0;
70   // Schedule on_error to be invoked when the underlying file descriptor
71   // encounters errors. When the on_error closure is run, it may check
72   // if the handle is shutdown using the IsHandleShutdown method and take
73   // appropriate actions (for instance it should not try to invoke another
74   // recursive NotifyOnError if the handle is shutdown).
75   virtual void NotifyOnError(PosixEngineClosure* on_error) = 0;
76   // Force set a readable event on the underlying file descriptor.
77   virtual void SetReadable() = 0;
78   // Force set a writable event on the underlying file descriptor.
79   virtual void SetWritable() = 0;
80   // Force set a error event on the underlying file descriptor.
81   virtual void SetHasError() = 0;
82   // Returns true if the handle has been shutdown.
83   virtual bool IsHandleShutdown() = 0;
84   // Returns the poller which was used to create this handle.
85   virtual PosixEventPoller* Poller() = 0;
86   virtual ~EventHandle() = default;
87 };
88 
89 class PosixEventPoller : public grpc_event_engine::experimental::Poller {
90  public:
91   // Return an opaque handle to perform actions on the provided file descriptor.
92   virtual EventHandle* CreateHandle(int fd, absl::string_view name,
93                                     bool track_err) = 0;
94   virtual bool CanTrackErrors() const = 0;
95   virtual std::string Name() = 0;
96   // Shuts down and deletes the poller. It is legal to call this function
97   // only when no other poller method is in progress. For instance, it is
98   // not safe to call this method, while a thread is blocked on Work(...).
99   // A graceful way to terminate the poller could be to:
100   // 1. First orphan all created handles.
101   // 2. Send a Kick() to the thread executing Work(...) and wait for the
102   //    thread to return.
103   // 3. Call Shutdown() on the poller.
104   virtual void Shutdown() = 0;
105   ~PosixEventPoller() override = default;
106 };
107 
108 }  // namespace experimental
109 }  // namespace grpc_event_engine
110 
111 #endif  // GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_EVENT_POLLER_H
112