Closing channels on timer Stop()

2,147 views
Skip to first unread message

Vadik Vygonets

unread,
Dec 15, 2011, 2:01:38 AM12/15/11
to golang-nuts
Hey Goers,

When a time.Timer is stopped, it doesn't close the channel, which, as
far as I understand, means that the routine waiting on the channel
will hang forever. (Correct me if I'm wrong.) So to kill it, I
create another channel and do:

for {
select {
case <-s.ticker.C:
f()
case <-s.headShot:
return
}
}

Why is that? Closing the channel seems like such a natural thing to
do that if it weren't done, the authors probably had a very good
reason. (And the tests expect this behaviour, too.)

While we're at the subject, can we have a version of NewTicker() that
sets r.when and r.period to different values? (At the moment I solve
this with a Timer that runs a Ticker when it expires.)

(No, I'm not writing cron.)

Thanks,
Vadik.

Ian Lance Taylor

unread,
Dec 15, 2011, 2:24:13 AM12/15/11
to Vadik Vygonets, golang-nuts
Vadik Vygonets <uni...@gmail.com> writes:

> When a time.Timer is stopped, it doesn't close the channel, which, as
> far as I understand, means that the routine waiting on the channel
> will hang forever.

The usual idiom would be to use a select statement waiting for either a
Timer channel or some other channel. If data arrives on the other
channel, you no longer care about the Timer, so you stop it. I'm not
sure when you would use a Timer that you stop while some goroutine is
waiting on it.

Ian

Vadik Vygonets

unread,
Dec 15, 2011, 2:28:26 AM12/15/11
to golang-nuts
On Dec 15, 8:24 am, Ian Lance Taylor <i...@google.com> wrote:
> The usual idiom would be to use a select statement waiting for either a
> Timer channel or some other channel.  If data arrives on the other
> channel, you no longer care about the Timer, so you stop it.

So I should stop it from within the switch? Got it, thanks.

> I'm not
> sure when you would use a Timer that you stop while some goroutine is
> waiting on it.

It's a periodic schedule that I may want to cancel at some point.

Thanks for the explanation,
Vadik.

Ian Lance Taylor

unread,
Dec 15, 2011, 1:01:50 PM12/15/11
to Vadik Vygonets, golang-nuts
Vadik Vygonets <uni...@gmail.com> writes:

I suppose I don't see anything wrong with having a Timer, or especially
a Ticker, close the channel when the Stop method is called. Could you
file an issue for that? Thanks.

Ian

Andrew Gerrand

unread,
Dec 15, 2011, 8:01:39 PM12/15/11
to golan...@googlegroups.com, Vadik Vygonets


On Friday, December 16, 2011 5:01:50 AM UTC+11, Ian Lance Taylor wrote:
Vadik Vygonets <uni...@gmail.com> writes:

> On Dec 15, 8:24 am, Ian Lance Taylor <i....@google.com> wrote:
>
>> I'm not
>> sure when you would use a Timer that you stop while some goroutine is
>> waiting on it.
>
> It's a periodic schedule that I may want to cancel at some point.

I suppose I don't see anything wrong with having a Timer, or especially
a Ticker, close the channel when the Stop method is called.  Could you
file an issue for that?  Thanks. 

The one downside I can see is that currently you can do
  t.Stop()
  close(t.C)
to get the behavior discussed in this thread.

If the Stop method closed the channel, you couldn't then (for example) hand the t.C channel off to something else to send "fake" ticks. It limits possibilities.

Andrew 

Andrew Gerrand

unread,
Dec 15, 2011, 8:02:44 PM12/15/11
to golan...@googlegroups.com, Vadik Vygonets
Oh, I see that Ticker.C is a receive-only channel, so all the statements I made in the previous post are false.

Andrew

Vadik Vygonets

unread,
Dec 16, 2011, 12:01:44 AM12/16/11
to golang-nuts
On Dec 15, 7:01 pm, Ian Lance Taylor <i...@google.com> wrote:
> I suppose I don't see anything wrong with having a Timer, or especially
> a Ticker, close the channel when the Stop method is called.  Could you
> file an issue for that?  Thanks.

http://codereview.appspot.com/5491059

Though now I'm having doubts: it changes the behaviour too much.

Vadik.

roger peppe

unread,
Dec 16, 2011, 5:31:46 AM12/16/11
to golan...@googlegroups.com, Vadik Vygonets
On 16 December 2011 01:01, Andrew Gerrand <a...@golang.org> wrote:
> The one downside I can see is that currently you can do
>   t.Stop()
>   close(t.C)
> to get the behavior discussed in this thread.

two reasons you can't do that:

- t.C is a receive-only channel, which means you can't close it.

- even if you could, the Stop is not synchronous, so you might
get a panic when the ticker tries to send to the channel after
you've closed it.

i'd like it if Ticker closed the channel on Stop.

Vadik Vygonets

unread,
Dec 16, 2011, 11:33:28 AM12/16/11
to golang-nuts
On Dec 16, 11:31 am, roger peppe <rogpe...@gmail.com> wrote:
> i'd like it if Ticker closed the channel on Stop.

Not gonna happen, please see the issue for details.

Vadik.

Mike

unread,
Aug 6, 2012, 12:38:48 AM8/6/12
to golan...@googlegroups.com
I just ran into this issue myself. Can this behavior be explicitly documented in the time package?
Reply all
Reply to author
Forward
0 new messages