Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(400)

Side by Side Diff: common/clock/systemtimer.go

Issue 1679023005: Add Context cancellation to clock. (Closed) Base URL: https://github.com/luci/luci-go@master
Patch Set: Actually upload the patch. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « common/clock/systemclock_test.go ('k') | common/clock/systemtimer_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package clock 5 package clock
6 6
7 import ( 7 import (
8 "time" 8 "time"
9
10 "golang.org/x/net/context"
9 ) 11 )
10 12
11 type systemTimer struct { 13 type systemTimer struct {
12 » T *time.Timer // The underlying timer. Starts as nil, is initialized on Reset. 14 » // ctx is the underlying timer. It starts as nil, and is initialized on Reset.
15 » ctx context.Context
16
17 » // timerC is the timer channel.
18 » timerC chan TimerResult
19
20 » // timerStoppedC is a signal channel used by Stop to alert our monitor t hat
21 » // this timer has been manually canceled.
22 » timerStoppedC chan struct{}
23 » // timerMonitorResultC returns true if the timer monitor was prematurely
24 » // terminated, false if not. It is used by our timer monitor to indicate its
25 » // status when stopped.
26 » timerMonitorResultC chan bool
13 } 27 }
14 28
15 var _ Timer = (*systemTimer)(nil) 29 var _ Timer = (*systemTimer)(nil)
16 30
17 func (t *systemTimer) GetC() <-chan time.Time { 31 func newSystemTimer(ctx context.Context) Timer {
18 » if t.T == nil { 32 » return &systemTimer{
19 » » return nil 33 » » ctx: ctx,
34 » » timerC: make(chan TimerResult, 1),
20 } 35 }
21 return t.T.C
22 } 36 }
23 37
24 func (t *systemTimer) Reset(d time.Duration) bool { 38 func (t *systemTimer) GetC() <-chan TimerResult {
25 » if t.T == nil { 39 » return t.timerC
26 » » t.T = time.NewTimer(d) 40 }
27 » » return false 41
42 func (t *systemTimer) Reset(d time.Duration) (running bool) {
43 » running = t.Stop()
44
45 » // If our Context is already done, finish immediately.
46 » if err := t.ctx.Err(); err != nil {
47 » » t.timerC <- TimerResult{Time: time.Now(), Err: t.ctx.Err()}
48 » » return
28 } 49 }
29 » return t.T.Reset(d) 50
51 » // Start a monitor goroutine and our actual timer. Copy our channels, si nce
52 » // future stop/reset will change the systemTimer's values and our gorout ine
53 » // should only operate on this round's values.
54 » timerStoppedC := make(chan struct{})
55 » timerMonitorResultC := make(chan bool, 1)
56 » go func() {
57 » » interrupted := false
58 » » defer func() {
59 » » » timerMonitorResultC <- interrupted
60 » » }()
61
62 » » select {
63 » » case <-timerStoppedC:
64 » » » interrupted = true
65
66 » » case <-t.ctx.Done():
67 » » » t.timerC <- TimerResult{Time: time.Now(), Err: t.ctx.Err ()}
68 » » case now := <-time.After(d):
69 » » » t.timerC <- TimerResult{Time: now, Err: t.ctx.Err()}
70 » » }
71 » }()
72
73 » t.timerStoppedC = timerStoppedC
74 » t.timerMonitorResultC = timerMonitorResultC
75 » return
30 } 76 }
31 77
32 func (t *systemTimer) Stop() bool { 78 func (t *systemTimer) Stop() bool {
33 » if t.T == nil { 79 » if t.timerStoppedC == nil {
34 return false 80 return false
35 } 81 }
36 » return t.T.Stop() 82 » close(t.timerStoppedC)
83 » t.timerStoppedC = nil
84 » return <-t.timerMonitorResultC
37 } 85 }
OLDNEW
« no previous file with comments | « common/clock/systemclock_test.go ('k') | common/clock/systemtimer_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698