|
|
|
@ -34,7 +34,7 @@ |
|
|
|
|
namespace grpc { |
|
|
|
|
|
|
|
|
|
namespace internal { |
|
|
|
|
class AlarmImpl { |
|
|
|
|
class AlarmImpl : public CompletionQueueTag { |
|
|
|
|
public: |
|
|
|
|
AlarmImpl() : cq_(nullptr), tag_(nullptr) { |
|
|
|
|
gpr_ref_init(&refs_, 1); |
|
|
|
@ -45,10 +45,8 @@ class AlarmImpl { |
|
|
|
|
AlarmImpl* alarm = static_cast<AlarmImpl*>(arg); |
|
|
|
|
alarm->Ref(); |
|
|
|
|
grpc_cq_end_op( |
|
|
|
|
alarm->cq_, &alarm->tag_, error, |
|
|
|
|
alarm->cq_, alarm, error, |
|
|
|
|
[](void* arg, grpc_cq_completion* completion) { |
|
|
|
|
AlarmImpl* alarm = static_cast<AlarmImpl*>(arg); |
|
|
|
|
alarm->Unref(); |
|
|
|
|
}, |
|
|
|
|
arg, &alarm->completion_); |
|
|
|
|
}, |
|
|
|
@ -60,12 +58,17 @@ class AlarmImpl { |
|
|
|
|
GRPC_CQ_INTERNAL_UNREF(cq_, "alarm"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
bool FinalizeResult(void** tag, bool* status) override { |
|
|
|
|
*tag = tag_; |
|
|
|
|
Unref(); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
void Set(CompletionQueue* cq, gpr_timespec deadline, void* tag) { |
|
|
|
|
grpc_core::ExecCtx exec_ctx; |
|
|
|
|
GRPC_CQ_INTERNAL_REF(cq->cq(), "alarm"); |
|
|
|
|
cq_ = cq->cq(); |
|
|
|
|
tag_.Set(tag); |
|
|
|
|
GPR_ASSERT(grpc_cq_begin_op(cq_, &tag_)); |
|
|
|
|
tag_ = tag; |
|
|
|
|
GPR_ASSERT(grpc_cq_begin_op(cq_, this)); |
|
|
|
|
grpc_timer_init(&timer_, grpc_timespec_to_millis_round_up(deadline), |
|
|
|
|
&on_alarm_); |
|
|
|
|
} |
|
|
|
@ -77,21 +80,7 @@ class AlarmImpl { |
|
|
|
|
Cancel(); |
|
|
|
|
Unref(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
class AlarmEntry : public internal::CompletionQueueTag { |
|
|
|
|
public: |
|
|
|
|
AlarmEntry(void* tag) : tag_(tag) {} |
|
|
|
|
void Set(void* tag) { tag_ = tag; } |
|
|
|
|
bool FinalizeResult(void** tag, bool* status) override { |
|
|
|
|
*tag = tag_; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
void* tag_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
void Ref() { gpr_ref(&refs_); } |
|
|
|
|
void Unref() { |
|
|
|
|
if (gpr_unref(&refs_)) { |
|
|
|
@ -105,7 +94,7 @@ class AlarmImpl { |
|
|
|
|
grpc_cq_completion completion_; |
|
|
|
|
// completion queue where events about this alarm will be posted
|
|
|
|
|
grpc_completion_queue* cq_; |
|
|
|
|
AlarmEntry tag_; |
|
|
|
|
void* tag_; |
|
|
|
|
}; |
|
|
|
|
} // namespace internal
|
|
|
|
|
|
|
|
|
@ -116,14 +105,19 @@ Alarm::Alarm() : alarm_(new internal::AlarmImpl()) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Alarm::SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag) { |
|
|
|
|
alarm_->Set(cq, deadline, tag); |
|
|
|
|
// Note that we know that alarm_ is actually an internal::AlarmImpl
|
|
|
|
|
// but we declared it as the base pointer to avoid a forward declaration
|
|
|
|
|
// or exposing core data structures in the C++ public headers.
|
|
|
|
|
// Thus it is safe to use a static_cast to the subclass here, and the
|
|
|
|
|
// C++ style guide allows us to do so in this case
|
|
|
|
|
static_cast<internal::AlarmImpl*>(alarm_)->Set(cq, deadline, tag); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Alarm::~Alarm() { |
|
|
|
|
if (alarm_ != nullptr) { |
|
|
|
|
alarm_->Destroy(); |
|
|
|
|
static_cast<internal::AlarmImpl*>(alarm_)->Destroy(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Alarm::Cancel() { alarm_->Cancel(); } |
|
|
|
|
void Alarm::Cancel() { static_cast<internal::AlarmImpl*>(alarm_)->Cancel(); } |
|
|
|
|
} // namespace grpc
|
|
|
|
|