1 | /* |
2 | * |
3 | * Copyright 2015 gRPC authors. |
4 | * |
5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | * you may not use this file except in compliance with the License. |
7 | * You may obtain a copy of the License at |
8 | * |
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | * |
11 | * Unless required by applicable law or agreed to in writing, software |
12 | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | * See the License for the specific language governing permissions and |
15 | * limitations under the License. |
16 | * |
17 | */ |
18 | |
19 | /// An Alarm posts the user-provided tag to its associated completion queue or |
20 | /// invokes the user-provided function on expiry or cancellation. |
21 | #ifndef GRPCPP_ALARM_IMPL_H |
22 | #define GRPCPP_ALARM_IMPL_H |
23 | |
24 | #include <functional> |
25 | |
26 | #include <grpc/grpc.h> |
27 | #include <grpcpp/impl/codegen/completion_queue.h> |
28 | #include <grpcpp/impl/codegen/completion_queue_tag.h> |
29 | #include <grpcpp/impl/codegen/grpc_library.h> |
30 | #include <grpcpp/impl/codegen/time.h> |
31 | #include <grpcpp/impl/grpc_library.h> |
32 | |
33 | namespace grpc_impl { |
34 | |
35 | class Alarm : private ::grpc::GrpcLibraryCodegen { |
36 | public: |
37 | /// Create an unset completion queue alarm |
38 | Alarm(); |
39 | |
40 | /// Destroy the given completion queue alarm, cancelling it in the process. |
41 | ~Alarm(); |
42 | |
43 | /// DEPRECATED: Create and set a completion queue alarm instance associated to |
44 | /// \a cq. |
45 | /// This form is deprecated because it is inherently racy. |
46 | /// \internal We rely on the presence of \a cq for grpc initialization. If \a |
47 | /// cq were ever to be removed, a reference to a static |
48 | /// internal::GrpcLibraryInitializer instance would need to be introduced |
49 | /// here. \endinternal. |
50 | template <typename T> |
51 | Alarm(::grpc::CompletionQueue* cq, const T& deadline, void* tag) : Alarm() { |
52 | SetInternal(cq, ::grpc::TimePoint<T>(deadline).raw_time(), tag); |
53 | } |
54 | |
55 | /// Trigger an alarm instance on completion queue \a cq at the specified time. |
56 | /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel), |
57 | /// an event with tag \a tag will be added to \a cq. If the alarm expired, the |
58 | /// event's success bit will be true, false otherwise (ie, upon cancellation). |
59 | template <typename T> |
60 | void Set(::grpc::CompletionQueue* cq, const T& deadline, void* tag) { |
61 | SetInternal(cq, ::grpc::TimePoint<T>(deadline).raw_time(), tag); |
62 | } |
63 | |
64 | /// Alarms aren't copyable. |
65 | Alarm(const Alarm&) = delete; |
66 | Alarm& operator=(const Alarm&) = delete; |
67 | |
68 | /// Alarms are movable. |
69 | Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; } |
70 | Alarm& operator=(Alarm&& rhs) { |
71 | alarm_ = rhs.alarm_; |
72 | rhs.alarm_ = nullptr; |
73 | return *this; |
74 | } |
75 | |
76 | /// Cancel a completion queue alarm. Calling this function over an alarm that |
77 | /// has already fired has no effect. |
78 | void Cancel(); |
79 | |
80 | #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL |
81 | /// Set an alarm to invoke callback \a f. The argument to the callback |
82 | /// states whether the alarm expired at \a deadline (true) or was cancelled |
83 | /// (false) |
84 | template <typename T> |
85 | void Set(const T& deadline, std::function<void(bool)> f) { |
86 | SetInternal(::grpc::TimePoint<T>(deadline).raw_time(), std::move(f)); |
87 | } |
88 | #endif |
89 | |
90 | /// NOTE: class experimental_type is not part of the public API of this class |
91 | /// TODO(vjpai): Move these contents to the public API of Alarm when |
92 | /// they are no longer experimental |
93 | class experimental_type { |
94 | public: |
95 | explicit experimental_type(Alarm* alarm) : alarm_(alarm) {} |
96 | |
97 | /// Set an alarm to invoke callback \a f. The argument to the callback |
98 | /// states whether the alarm expired at \a deadline (true) or was cancelled |
99 | /// (false) |
100 | template <typename T> |
101 | void Set(const T& deadline, std::function<void(bool)> f) { |
102 | alarm_->SetInternal(::grpc::TimePoint<T>(deadline).raw_time(), |
103 | std::move(f)); |
104 | } |
105 | |
106 | private: |
107 | Alarm* alarm_; |
108 | }; |
109 | |
110 | /// NOTE: The function experimental() is not stable public API. It is a view |
111 | /// to the experimental components of this class. It may be changed or removed |
112 | /// at any time. |
113 | experimental_type experimental() { return experimental_type(this); } |
114 | |
115 | private: |
116 | void SetInternal(::grpc::CompletionQueue* cq, gpr_timespec deadline, |
117 | void* tag); |
118 | void SetInternal(gpr_timespec deadline, std::function<void(bool)> f); |
119 | |
120 | ::grpc::internal::CompletionQueueTag* alarm_; |
121 | }; |
122 | |
123 | } // namespace grpc_impl |
124 | |
125 | #endif // GRPCPP_ALARM_IMPL_H |
126 | |