• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 upon
20 /// expiry or cancellation.
21 #ifndef GRPCPP_ALARM_H
22 #define GRPCPP_ALARM_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 {
34 
35 /// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h).
36 class Alarm : private GrpcLibraryCodegen {
37  public:
38   /// Create an unset completion queue alarm
39   Alarm();
40 
41   /// Destroy the given completion queue alarm, cancelling it in the process.
42   ~Alarm();
43 
44   /// DEPRECATED: Create and set a completion queue alarm instance associated to
45   /// \a cq.
46   /// This form is deprecated because it is inherently racy.
47   /// \internal We rely on the presence of \a cq for grpc initialization. If \a
48   /// cq were ever to be removed, a reference to a static
49   /// internal::GrpcLibraryInitializer instance would need to be introduced
50   /// here. \endinternal.
51   template <typename T>
Alarm(CompletionQueue * cq,const T & deadline,void * tag)52   Alarm(CompletionQueue* cq, const T& deadline, void* tag) : Alarm() {
53     SetInternal(cq, TimePoint<T>(deadline).raw_time(), tag);
54   }
55 
56   /// Trigger an alarm instance on completion queue \a cq at the specified time.
57   /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel),
58   /// an event with tag \a tag will be added to \a cq. If the alarm expired, the
59   /// event's success bit will be true, false otherwise (ie, upon cancellation).
60   template <typename T>
Set(CompletionQueue * cq,const T & deadline,void * tag)61   void Set(CompletionQueue* cq, const T& deadline, void* tag) {
62     SetInternal(cq, TimePoint<T>(deadline).raw_time(), tag);
63   }
64 
65   /// Alarms aren't copyable.
66   Alarm(const Alarm&) = delete;
67   Alarm& operator=(const Alarm&) = delete;
68 
69   /// Alarms are movable.
Alarm(Alarm && rhs)70   Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; }
71   Alarm& operator=(Alarm&& rhs) {
72     alarm_ = rhs.alarm_;
73     rhs.alarm_ = nullptr;
74     return *this;
75   }
76 
77   /// Cancel a completion queue alarm. Calling this function over an alarm that
78   /// has already fired has no effect.
79   void Cancel();
80 
81   /// NOTE: class experimental_type is not part of the public API of this class
82   /// TODO(vjpai): Move these contents to the public API of Alarm when
83   ///              they are no longer experimental
84   class experimental_type {
85    public:
experimental_type(Alarm * alarm)86     explicit experimental_type(Alarm* alarm) : alarm_(alarm) {}
87 
88     /// Set an alarm to invoke callback \a f. The argument to the callback
89     /// states whether the alarm expired at \a deadline (true) or was cancelled
90     /// (false)
91     template <typename T>
Set(const T & deadline,std::function<void (bool)> f)92     void Set(const T& deadline, std::function<void(bool)> f) {
93       alarm_->SetInternal(TimePoint<T>(deadline).raw_time(), std::move(f));
94     }
95 
96    private:
97     Alarm* alarm_;
98   };
99 
100   /// NOTE: The function experimental() is not stable public API. It is a view
101   /// to the experimental components of this class. It may be changed or removed
102   /// at any time.
experimental()103   experimental_type experimental() { return experimental_type(this); }
104 
105  private:
106   void SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag);
107   void SetInternal(gpr_timespec deadline, std::function<void(bool)> f);
108 
109   internal::CompletionQueueTag* alarm_;
110 };
111 
112 }  // namespace grpc
113 
114 #endif  // GRPCPP_ALARM_H
115