@@ -49,12 +49,6 @@ class TimerState {
49
49
void Cancel () { grpc_timer_cancel (&timer_); }
50
50
51
51
private:
52
- ~TimerState () {
53
- grpc_deadline_state* deadline_state =
54
- static_cast <grpc_deadline_state*>(elem_->call_data );
55
- GRPC_CALL_STACK_UNREF (deadline_state->call_stack , " DeadlineTimerState" );
56
- }
57
-
58
52
// The on_complete callback used when sending a cancel_error batch down the
59
53
// filter stack. Yields the call combiner when the batch returns.
60
54
static void YieldCallCombiner (void * arg, grpc_error* /* ignored*/ ) {
@@ -63,8 +57,7 @@ class TimerState {
63
57
static_cast <grpc_deadline_state*>(self->elem_ ->call_data );
64
58
GRPC_CALL_COMBINER_STOP (deadline_state->call_combiner ,
65
59
" got on_complete from cancel_stream batch" );
66
- // Allocated on call arena, so not deleting, but do want to call the dtor.
67
- self->~TimerState ();
60
+ GRPC_CALL_STACK_UNREF (deadline_state->call_stack , " DeadlineTimerState" );
68
61
}
69
62
70
63
// This is called via the call combiner, so access to deadline_state is
@@ -94,11 +87,17 @@ class TimerState {
94
87
error,
95
88
" deadline exceeded -- sending cancel_stream op" );
96
89
} else {
97
- // Allocated on call arena, so not deleting, but do want to call the dtor.
98
- self->~TimerState ();
90
+ GRPC_CALL_STACK_UNREF (deadline_state->call_stack , " DeadlineTimerState" );
99
91
}
100
92
}
101
93
94
+ // NOTE: This object's dtor is never called, so do not add any data
95
+ // members that require destruction!
96
+ // TODO(roth): We should ideally call this object's dtor somewhere,
97
+ // but that would require adding more synchronization, because we'd
98
+ // need to call the dtor only after both (a) the timer callback
99
+ // finishes and (b) the filter sees the call completion and attempts
100
+ // to cancel the timer.
102
101
grpc_call_element* elem_;
103
102
grpc_timer timer_;
104
103
grpc_closure closure_;
0 commit comments