• 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 or
20 /// invokes the user-provided function on 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 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() override;
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>
Alarm(::grpc::CompletionQueue * cq,const T & deadline,void * tag)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   //
60   // USAGE NOTE: This is frequently used to inject arbitrary tags into \a cq by
61   // setting an immediate deadline. Such usage allows synchronizing an external
62   // event with an application's \a grpc::CompletionQueue::Next loop.
63   template <typename T>
Set(::grpc::CompletionQueue * cq,const T & deadline,void * tag)64   void Set(::grpc::CompletionQueue* cq, const T& deadline, void* tag) {
65     SetInternal(cq, ::grpc::TimePoint<T>(deadline).raw_time(), tag);
66   }
67 
68   /// Alarms aren't copyable.
69   Alarm(const Alarm&) = delete;
70   Alarm& operator=(const Alarm&) = delete;
71 
72   /// Alarms are movable.
Alarm(Alarm && rhs)73   Alarm(Alarm&& rhs) noexcept : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; }
74   Alarm& operator=(Alarm&& rhs) noexcept {
75     alarm_ = rhs.alarm_;
76     rhs.alarm_ = nullptr;
77     return *this;
78   }
79 
80   /// Cancel a completion queue alarm. Calling this function over an alarm that
81   /// has already fired has no effect.
82   void Cancel();
83 
84 #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
85   /// Set an alarm to invoke callback \a f. The argument to the callback
86   /// states whether the alarm expired at \a deadline (true) or was cancelled
87   /// (false)
88   template <typename T>
Set(const T & deadline,std::function<void (bool)> f)89   void Set(const T& deadline, std::function<void(bool)> f) {
90     SetInternal(::grpc::TimePoint<T>(deadline).raw_time(), std::move(f));
91   }
92 #endif
93 
94   /// NOTE: class experimental_type is not part of the public API of this class
95   /// TODO(vjpai): Move these contents to the public API of Alarm when
96   ///              they are no longer experimental
97   class experimental_type {
98    public:
experimental_type(Alarm * alarm)99     explicit experimental_type(Alarm* alarm) : alarm_(alarm) {}
100 
101     /// Set an alarm to invoke callback \a f. The argument to the callback
102     /// states whether the alarm expired at \a deadline (true) or was cancelled
103     /// (false)
104     template <typename T>
Set(const T & deadline,std::function<void (bool)> f)105     void Set(const T& deadline, std::function<void(bool)> f) {
106       alarm_->SetInternal(::grpc::TimePoint<T>(deadline).raw_time(),
107                           std::move(f));
108     }
109 
110    private:
111     Alarm* alarm_;
112   };
113 
114   /// NOTE: The function experimental() is not stable public API. It is a view
115   /// to the experimental components of this class. It may be changed or removed
116   /// at any time.
experimental()117   experimental_type experimental() { return experimental_type(this); }
118 
119  private:
120   void SetInternal(::grpc::CompletionQueue* cq, gpr_timespec deadline,
121                    void* tag);
122   void SetInternal(gpr_timespec deadline, std::function<void(bool)> f);
123 
124   ::grpc::internal::CompletionQueueTag* alarm_;
125 };
126 
127 }  // namespace grpc
128 
129 #endif  // GRPCPP_ALARM_H
130