| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package bundler |
| 6 |
| 7 import ( |
| 8 "sync" |
| 9 "time" |
| 10 |
| 11 "github.com/luci/luci-go/common/clock" |
| 12 ) |
| 13 |
| 14 type timeoutCond struct { |
| 15 *sync.Cond |
| 16 |
| 17 clock clock.Clock |
| 18 } |
| 19 |
| 20 func newTimeoutCond(c clock.Clock, l sync.Locker) *timeoutCond { |
| 21 return &timeoutCond{ |
| 22 Cond: sync.NewCond(l), |
| 23 clock: c, |
| 24 } |
| 25 } |
| 26 |
| 27 func (c *timeoutCond) waitTimeout(d time.Duration) (timeout bool) { |
| 28 if d <= 0 { |
| 29 // We've already expired, so don't bother waiting. |
| 30 return |
| 31 } |
| 32 |
| 33 // Kick off a timer to Broadcast when it has completed. |
| 34 doneC := make(chan struct{}) |
| 35 finishedC := make(chan bool) |
| 36 defer func() { |
| 37 close(doneC) |
| 38 timeout = <-finishedC |
| 39 }() |
| 40 |
| 41 go func() { |
| 42 timerExpired := false |
| 43 defer func() { |
| 44 finishedC <- timerExpired |
| 45 }() |
| 46 |
| 47 t := c.clock.NewTimer() |
| 48 defer t.Stop() |
| 49 t.Reset(d) |
| 50 |
| 51 // Quickly own our lock. This ensures that we have entered our W
ait() |
| 52 // method, which in turn ensures that our Broadcast will wake it
if |
| 53 // necessary. |
| 54 func() { |
| 55 c.L.Lock() |
| 56 defer c.L.Unlock() |
| 57 }() |
| 58 |
| 59 select { |
| 60 case <-doneC: |
| 61 break |
| 62 |
| 63 case <-t.GetC(): |
| 64 timerExpired = true |
| 65 c.Broadcast() |
| 66 } |
| 67 }() |
| 68 |
| 69 // Wait on our Cond. This will be released when either something else |
| 70 // Broadcasts. That "something else" may be our timer expiring. |
| 71 c.Wait() |
| 72 return |
| 73 } |
| OLD | NEW |