aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/grpc++
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2017-09-08 14:39:15 -0700
committerGravatar Craig Tiller <ctiller@google.com>2017-09-08 14:39:15 -0700
commit55863ff5272bf9c7e08a96ab0f4e50f0aafe6b0a (patch)
tree8817ebd963c501b006d74ac392f25f8a31ecb412 /include/grpc++
parent073a88f4dddf102ecaa46f2d74fd85bdf5be9594 (diff)
parent729448f2edbfb2b8088141dd5141ba0d09cc9eb8 (diff)
Merge github.com:grpc/grpc into write_completion
Diffstat (limited to 'include/grpc++')
-rw-r--r--include/grpc++/alarm.h36
-rw-r--r--include/grpc++/server_builder.h7
2 files changed, 32 insertions, 11 deletions
diff --git a/include/grpc++/alarm.h b/include/grpc++/alarm.h
index ed8dacbc94..2d88d868e5 100644
--- a/include/grpc++/alarm.h
+++ b/include/grpc++/alarm.h
@@ -37,20 +37,33 @@ class CompletionQueue;
/// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h).
class Alarm : private GrpcLibraryCodegen {
public:
- /// Create a completion queue alarm instance associated to \a cq.
- ///
- /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel),
- /// an event with tag \a tag will be added to \a cq. If the alarm expired, the
- /// event's success bit will be true, false otherwise (ie, upon cancellation).
+ /// Create an unset completion queue alarm
+ Alarm() : tag_(nullptr), alarm_(grpc_alarm_create(nullptr)) {}
+
+ /// DEPRECATED: Create and set a completion queue alarm instance associated to
+ /// \a cq.
+ /// This form is deprecated because it is inherently racy.
/// \internal We rely on the presence of \a cq for grpc initialization. If \a
/// cq were ever to be removed, a reference to a static
/// internal::GrpcLibraryInitializer instance would need to be introduced
/// here. \endinternal.
template <typename T>
Alarm(CompletionQueue* cq, const T& deadline, void* tag)
- : tag_(tag),
- alarm_(grpc_alarm_create(cq->cq(), TimePoint<T>(deadline).raw_time(),
- static_cast<void*>(&tag_))) {}
+ : tag_(tag), alarm_(grpc_alarm_create(nullptr)) {
+ grpc_alarm_set(alarm_, cq->cq(), TimePoint<T>(deadline).raw_time(),
+ static_cast<void*>(&tag_), nullptr);
+ }
+
+ /// Trigger an alarm instance on completion queue \a cq at the specified time.
+ /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel),
+ /// an event with tag \a tag will be added to \a cq. If the alarm expired, the
+ /// event's success bit will be true, false otherwise (ie, upon cancellation).
+ template <typename T>
+ void Set(CompletionQueue* cq, const T& deadline, void* tag) {
+ tag_.Set(tag);
+ grpc_alarm_set(alarm_, cq->cq(), TimePoint<T>(deadline).raw_time(),
+ static_cast<void*>(&tag_), nullptr);
+ }
/// Alarms aren't copyable.
Alarm(const Alarm&) = delete;
@@ -69,17 +82,20 @@ class Alarm : private GrpcLibraryCodegen {
/// Destroy the given completion queue alarm, cancelling it in the process.
~Alarm() {
- if (alarm_ != nullptr) grpc_alarm_destroy(alarm_);
+ if (alarm_ != nullptr) grpc_alarm_destroy(alarm_, nullptr);
}
/// Cancel a completion queue alarm. Calling this function over an alarm that
/// has already fired has no effect.
- void Cancel() { grpc_alarm_cancel(alarm_); }
+ void Cancel() {
+ if (alarm_ != nullptr) grpc_alarm_cancel(alarm_, nullptr);
+ }
private:
class AlarmEntry : public CompletionQueueTag {
public:
AlarmEntry(void* tag) : tag_(tag) {}
+ void Set(void* tag) { tag_ = tag; }
bool FinalizeResult(void** tag, bool* status) override {
*tag = tag_;
return true;
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index eafd63619d..21ae70d13a 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -151,7 +151,8 @@ class ServerBuilder {
/// Add a completion queue for handling asynchronous services.
///
/// Caller is required to shutdown the server prior to shutting down the
- /// returned completion queue. A typical usage scenario:
+ /// returned completion queue. Caller is also required to drain the
+ /// completion queue after shutting it down. A typical usage scenario:
///
/// // While building the server:
/// ServerBuilder builder;
@@ -162,6 +163,10 @@ class ServerBuilder {
/// // While shutting down the server;
/// server_->Shutdown();
/// cq_->Shutdown(); // Always *after* the associated server's Shutdown()!
+ /// // Drain the cq_ that was created
+ /// void* ignored_tag;
+ /// bool ignored_ok;
+ /// while (cq_->Next(&ignored_tag, &ignored_ok)) { }
///
/// \param is_frequently_polled This is an optional parameter to inform gRPC
/// library about whether this completion queue would be frequently polled