1 // Copyright 2022 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_PROMISE_SLEEP_H 16 #define GRPC_SRC_CORE_LIB_PROMISE_SLEEP_H 17 18 #include <grpc/support/port_platform.h> 19 20 #include <atomic> 21 #include <utility> 22 23 #include "absl/status/status.h" 24 25 #include <grpc/event_engine/event_engine.h> 26 27 #include "src/core/lib/gprpp/time.h" 28 #include "src/core/lib/promise/activity.h" 29 #include "src/core/lib/promise/poll.h" 30 31 namespace grpc_core { 32 33 // Promise that sleeps until a deadline and then finishes. 34 class Sleep final { 35 public: 36 explicit Sleep(Timestamp deadline); 37 ~Sleep(); 38 39 Sleep(const Sleep&) = delete; 40 Sleep& operator=(const Sleep&) = delete; Sleep(Sleep && other)41 Sleep(Sleep&& other) noexcept 42 : deadline_(other.deadline_), 43 closure_(std::exchange(other.closure_, nullptr)) {} 44 Sleep& operator=(Sleep&& other) noexcept { 45 deadline_ = other.deadline_; 46 std::swap(closure_, other.closure_); 47 return *this; 48 }; 49 50 Poll<absl::Status> operator()(); 51 52 private: 53 class ActiveClosure final 54 : public grpc_event_engine::experimental::EventEngine::Closure { 55 public: 56 explicit ActiveClosure(Timestamp deadline); 57 58 void Run() override; 59 // After calling Cancel, it's no longer safe to access this object. 60 void Cancel(); 61 62 bool HasRun() const; 63 64 private: 65 bool Unref(); 66 67 Waker waker_; 68 // One ref dropped by Run(), the other by Cancel(). 69 std::atomic<int> refs_{2}; 70 grpc_event_engine::experimental::EventEngine::TaskHandle timer_handle_; 71 }; 72 73 Timestamp deadline_; 74 ActiveClosure* closure_{nullptr}; 75 }; 76 77 } // namespace grpc_core 78 79 #endif // GRPC_SRC_CORE_LIB_PROMISE_SLEEP_H 80