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
33namespace grpc_impl {
34
35class 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