diff --git a/src/core/channel/client_setup.c b/src/core/channel/client_setup.c index 8060b2a36d6..562f284928b 100644 --- a/src/core/channel/client_setup.c +++ b/src/core/channel/client_setup.c @@ -212,11 +212,11 @@ void grpc_client_setup_request_finish(grpc_client_setup_request *r, /* TODO(klempner): Replace these values with further consideration. 2x is probably too aggressive of a backoff. */ gpr_timespec max_backoff = gpr_time_from_minutes(2); + gpr_timespec deadline = + gpr_time_add(s->current_backoff_interval, gpr_now()); GPR_ASSERT(!s->in_alarm); s->in_alarm = 1; - grpc_alarm_init(&s->backoff_alarm, backoff_alarm_done, s); - grpc_alarm_add(&s->backoff_alarm, - gpr_time_add(s->current_backoff_interval, gpr_now())); + grpc_alarm_init(&s->backoff_alarm, deadline, backoff_alarm_done, s); s->current_backoff_interval = gpr_time_add(s->current_backoff_interval, s->current_backoff_interval); if (gpr_time_cmp(s->current_backoff_interval, max_backoff) > 0) { diff --git a/src/core/iomgr/alarm.h b/src/core/iomgr/alarm.h index 5bd00d97363..e09f165bcf2 100644 --- a/src/core/iomgr/alarm.h +++ b/src/core/iomgr/alarm.h @@ -50,9 +50,10 @@ typedef struct grpc_alarm grpc_alarm; canceled (CANCELLED). alarm_cb is guaranteed to be called exactly once, and application code should check the status to determine how it was invoked. The application callback is also responsible for maintaining - information about when to free up any user-level state. */ -void grpc_alarm_init(grpc_alarm *alarm, grpc_iomgr_cb_func alarm_cb, - void *alarm_cb_arg); + information about when to free up any user-level state. + Returns 1 on success, 0 on failure. */ +int grpc_alarm_init(grpc_alarm *alarm, gpr_timespec deadline, + grpc_iomgr_cb_func alarm_cb, void *alarm_cb_arg); /* Note that there is no alarm destroy function. This is because the alarm is a one-time occurrence with a guarantee that the callback will @@ -62,12 +63,6 @@ void grpc_alarm_init(grpc_alarm *alarm, grpc_iomgr_cb_func alarm_cb, the alarm, the user is responsible for determining when it is safe to destroy that state. */ -/* Schedule *alarm to expire at deadline. If *alarm is - re-added before expiration, the *delay is simply reset to the new value. - Return GRPC_EM_OK on success, or GRPC_EM_ERROR on failure. - Upon failure, caller should abort further operations on *alarm */ -int grpc_alarm_add(grpc_alarm *alarm, gpr_timespec deadline); - /* Cancel an *alarm. There are three cases: 1. We normally cancel the alarm diff --git a/src/core/iomgr/iomgr_libevent.c b/src/core/iomgr/iomgr_libevent.c index 4d2fe4c40a3..488452c3d79 100644 --- a/src/core/iomgr/iomgr_libevent.c +++ b/src/core/iomgr/iomgr_libevent.c @@ -361,29 +361,18 @@ static void libevent_alarm_cb(int fd, short what, void *arg /*=alarm*/) { } } -void grpc_alarm_init(grpc_alarm *alarm, grpc_iomgr_cb_func alarm_cb, - void *alarm_cb_arg) { +int grpc_alarm_init(grpc_alarm *alarm, gpr_timespec deadline, + grpc_iomgr_cb_func alarm_cb, void *alarm_cb_arg) { grpc_libevent_activation_data *adata = &alarm->task.activation[GRPC_EM_TA_ONLY]; + gpr_timespec delay_timespec = gpr_time_sub(deadline, gpr_now()); + struct timeval delay = gpr_timeval_from_timespec(delay_timespec); alarm->task.type = GRPC_EM_TASK_ALARM; gpr_atm_rel_store(&alarm->triggered, ALARM_TRIGGER_INIT); adata->cb = alarm_cb; adata->arg = alarm_cb_arg; adata->prev = NULL; adata->next = NULL; - adata->ev = NULL; -} - -int grpc_alarm_add(grpc_alarm *alarm, gpr_timespec deadline) { - grpc_libevent_activation_data *adata = - &alarm->task.activation[GRPC_EM_TA_ONLY]; - gpr_timespec delay_timespec = gpr_time_sub(deadline, gpr_now()); - struct timeval delay = gpr_timeval_from_timespec(delay_timespec); - if (adata->ev) { - event_free(adata->ev); - gpr_log(GPR_INFO, "Adding an alarm that already has an event."); - adata->ev = NULL; - } adata->ev = evtimer_new(g_event_base, libevent_alarm_cb, alarm); /* Set the trigger field to untriggered. Do this as the last store since it is a release of previous stores. */ diff --git a/src/core/surface/call.c b/src/core/surface/call.c index d9d157c5487..a9509ac6956 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -868,6 +868,5 @@ void grpc_call_set_deadline(grpc_call_element *elem, gpr_timespec deadline) { } grpc_call_internal_ref(call); call->have_alarm = 1; - grpc_alarm_init(&call->alarm, call_alarm, call); - grpc_alarm_add(&call->alarm, deadline); + grpc_alarm_init(&call->alarm, deadline, call_alarm, call); } diff --git a/test/core/iomgr/alarm_test.c b/test/core/iomgr/alarm_test.c index 0dcd21463df..afc0768d998 100644 --- a/test/core/iomgr/alarm_test.c +++ b/test/core/iomgr/alarm_test.c @@ -116,8 +116,7 @@ static void test_grpc_alarm() { gpr_cv_init(&arg.cv); gpr_event_init(&arg.fcb_arg); - grpc_alarm_init(&alarm, alarm_cb, &arg); - grpc_alarm_add(&alarm, gpr_time_add(tv0, gpr_now())); + grpc_alarm_init(&alarm, gpr_time_add(tv0, gpr_now()), alarm_cb, &arg); alarm_deadline = gpr_time_add(gpr_now(), tv1); gpr_mu_lock(&arg.mu); @@ -162,8 +161,8 @@ static void test_grpc_alarm() { gpr_cv_init(&arg2.cv); gpr_event_init(&arg2.fcb_arg); - grpc_alarm_init(&alarm_to_cancel, alarm_cb, &arg2); - grpc_alarm_add(&alarm_to_cancel, gpr_time_add(tv2, gpr_now())); + grpc_alarm_init(&alarm_to_cancel, gpr_time_add(tv2, gpr_now()), alarm_cb, + &arg2); grpc_alarm_cancel(&alarm_to_cancel); alarm_deadline = gpr_time_add(gpr_now(), tv1);