David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 1 | /* |
| 2 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 3 | * Copyright 2015 gRPC authors. |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 4 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 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 |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 8 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 10 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 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. |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 16 | * |
| 17 | */ |
Yash Tibrewal | 15ce142 | 2017-09-25 17:46:32 -0700 | [diff] [blame] | 18 | #include <grpc/support/port_platform.h> |
| 19 | |
| 20 | #include <inttypes.h> |
| 21 | |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 22 | #include "src/core/lib/surface/alarm_internal.h" |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 23 | |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 24 | #include <grpc/grpc.h> |
| 25 | #include <grpc/support/alloc.h> |
yang-g | 0eaf7de | 2017-07-05 16:50:51 -0700 | [diff] [blame] | 26 | #include <grpc/support/log.h> |
Craig Tiller | 9533d04 | 2016-03-25 17:11:06 -0700 | [diff] [blame] | 27 | #include "src/core/lib/iomgr/timer.h" |
| 28 | #include "src/core/lib/surface/completion_queue.h" |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 29 | |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 30 | #ifndef NDEBUG |
Sree Kuchibhotla | 59beeff | 2017-07-25 14:08:33 -0700 | [diff] [blame] | 31 | grpc_tracer_flag grpc_trace_alarm_refcount = |
| 32 | GRPC_TRACER_INITIALIZER(false, "alarm_refcount"); |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 33 | #endif |
| 34 | |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 35 | struct grpc_alarm { |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 36 | gpr_refcount refs; |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 37 | grpc_timer alarm; |
Masood Malekghassemi | b5b4372 | 2017-01-05 15:07:26 -0800 | [diff] [blame] | 38 | grpc_closure on_alarm; |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 39 | grpc_cq_completion completion; |
| 40 | /** completion queue where events about this alarm will be posted */ |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 41 | grpc_completion_queue* cq; |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 42 | /** user supplied tag */ |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 43 | void* tag; |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 44 | }; |
| 45 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 46 | static void alarm_ref(grpc_alarm* alarm) { gpr_ref(&alarm->refs); } |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 47 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 48 | static void alarm_unref(grpc_alarm* alarm) { |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 49 | if (gpr_unref(&alarm->refs)) { |
| 50 | grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame] | 51 | if (alarm->cq != nullptr) { |
Vijay Pai | 58c33ba | 2017-09-01 14:08:42 -0700 | [diff] [blame] | 52 | GRPC_CQ_INTERNAL_UNREF(&exec_ctx, alarm->cq, "alarm"); |
| 53 | } |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 54 | grpc_exec_ctx_finish(&exec_ctx); |
| 55 | gpr_free(alarm); |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | #ifndef NDEBUG |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 60 | static void alarm_ref_dbg(grpc_alarm* alarm, const char* reason, |
| 61 | const char* file, int line) { |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 62 | if (GRPC_TRACER_ON(grpc_trace_alarm_refcount)) { |
| 63 | gpr_atm val = gpr_atm_no_barrier_load(&alarm->refs.count); |
| 64 | gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, |
| 65 | "Alarm:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", alarm, val, |
| 66 | val + 1, reason); |
| 67 | } |
| 68 | |
| 69 | alarm_ref(alarm); |
| 70 | } |
| 71 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 72 | static void alarm_unref_dbg(grpc_alarm* alarm, const char* reason, |
| 73 | const char* file, int line) { |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 74 | if (GRPC_TRACER_ON(grpc_trace_alarm_refcount)) { |
| 75 | gpr_atm val = gpr_atm_no_barrier_load(&alarm->refs.count); |
| 76 | gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, |
| 77 | "Alarm:%p Unref %" PRIdPTR " -> %" PRIdPTR " %s", alarm, val, |
| 78 | val - 1, reason); |
| 79 | } |
| 80 | |
| 81 | alarm_unref(alarm); |
| 82 | } |
| 83 | #endif |
| 84 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 85 | static void alarm_end_completion(grpc_exec_ctx* exec_ctx, void* arg, |
| 86 | grpc_cq_completion* c) { |
| 87 | grpc_alarm* alarm = (grpc_alarm*)arg; |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 88 | GRPC_ALARM_UNREF(alarm, "dequeue-end-op"); |
| 89 | } |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 90 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 91 | static void alarm_cb(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) { |
| 92 | grpc_alarm* alarm = (grpc_alarm*)arg; |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 93 | |
| 94 | /* We are queuing an op on completion queue. This means, the alarm's structure |
| 95 | cannot be destroyed until the op is dequeued. Adding an extra ref |
| 96 | here and unref'ing when the op is dequeued will achieve this */ |
| 97 | GRPC_ALARM_REF(alarm, "queue-end-op"); |
| 98 | grpc_cq_end_op(exec_ctx, alarm->cq, alarm->tag, error, alarm_end_completion, |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 99 | (void*)alarm, &alarm->completion); |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 100 | } |
| 101 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 102 | grpc_alarm* grpc_alarm_create(void* reserved) { |
| 103 | grpc_alarm* alarm = (grpc_alarm*)gpr_malloc(sizeof(grpc_alarm)); |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 104 | |
| 105 | #ifndef NDEBUG |
| 106 | if (GRPC_TRACER_ON(grpc_trace_alarm_refcount)) { |
| 107 | gpr_log(GPR_DEBUG, "Alarm:%p created (ref: 1)", alarm); |
| 108 | } |
| 109 | #endif |
| 110 | |
Vijay Pai | 58c33ba | 2017-09-01 14:08:42 -0700 | [diff] [blame] | 111 | gpr_ref_init(&alarm->refs, 1); |
| 112 | grpc_timer_init_unset(&alarm->alarm); |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame] | 113 | alarm->cq = nullptr; |
Vijay Pai | 58c33ba | 2017-09-01 14:08:42 -0700 | [diff] [blame] | 114 | GRPC_CLOSURE_INIT(&alarm->on_alarm, alarm_cb, alarm, |
| 115 | grpc_schedule_on_exec_ctx); |
| 116 | return alarm; |
| 117 | } |
| 118 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 119 | void grpc_alarm_set(grpc_alarm* alarm, grpc_completion_queue* cq, |
| 120 | gpr_timespec deadline, void* tag, void* reserved) { |
Vijay Pai | 58c33ba | 2017-09-01 14:08:42 -0700 | [diff] [blame] | 121 | grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
| 122 | |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 123 | GRPC_CQ_INTERNAL_REF(cq, "alarm"); |
| 124 | alarm->cq = cq; |
| 125 | alarm->tag = tag; |
| 126 | |
yang-g | 7d6b914 | 2017-07-13 11:48:56 -0700 | [diff] [blame] | 127 | GPR_ASSERT(grpc_cq_begin_op(cq, tag)); |
Craig Tiller | 9a8c3f3 | 2017-07-21 13:14:14 -0700 | [diff] [blame] | 128 | grpc_timer_init(&exec_ctx, &alarm->alarm, |
| 129 | grpc_timespec_to_millis_round_up(deadline), &alarm->on_alarm); |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 130 | grpc_exec_ctx_finish(&exec_ctx); |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 131 | } |
| 132 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 133 | void grpc_alarm_cancel(grpc_alarm* alarm, void* reserved) { |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 134 | grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
| 135 | grpc_timer_cancel(&exec_ctx, &alarm->alarm); |
| 136 | grpc_exec_ctx_finish(&exec_ctx); |
| 137 | } |
| 138 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 139 | void grpc_alarm_destroy(grpc_alarm* alarm, void* reserved) { |
Vijay Pai | 58c33ba | 2017-09-01 14:08:42 -0700 | [diff] [blame] | 140 | grpc_alarm_cancel(alarm, reserved); |
Sree Kuchibhotla | a8cf05c | 2017-06-22 15:08:55 -0700 | [diff] [blame] | 141 | GRPC_ALARM_UNREF(alarm, "alarm_destroy"); |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 142 | } |