cmd/syncthing, lib/events, lib/sync: Add timeout to REST event API, remove Ping (fixes #3933)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3941
This commit is contained in:
@@ -227,3 +227,70 @@ func goid() int {
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// TimeoutCond is a variant on Cond. It has roughly the same semantics regarding 'L' - it must be held
|
||||
// both when broadcasting and when calling TimeoutCondWaiter.Wait()
|
||||
// Call Broadcast() to broadcast to all waiters on the TimeoutCond. Call SetupWait to create a
|
||||
// TimeoutCondWaiter configured with the given timeout, which can then be used to listen for
|
||||
// broadcasts.
|
||||
type TimeoutCond struct {
|
||||
L sync.Locker
|
||||
ch chan struct{}
|
||||
}
|
||||
|
||||
// TimeoutCondWaiter is a type allowing a consumer to wait on a TimeoutCond with a timeout. Wait() may be called multiple times,
|
||||
// and will return true every time that the TimeoutCond is broadcast to. Once the configured timeout
|
||||
// expires, Wait() will return false.
|
||||
// Call Stop() to release resources once this TimeoutCondWaiter is no longer needed.
|
||||
type TimeoutCondWaiter struct {
|
||||
c *TimeoutCond
|
||||
timer *time.Timer
|
||||
}
|
||||
|
||||
func NewTimeoutCond(l sync.Locker) *TimeoutCond {
|
||||
return &TimeoutCond{
|
||||
L: l,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *TimeoutCond) Broadcast() {
|
||||
// ch.L must be locked when calling this function
|
||||
|
||||
if c.ch != nil {
|
||||
close(c.ch)
|
||||
c.ch = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *TimeoutCond) SetupWait(timeout time.Duration) *TimeoutCondWaiter {
|
||||
timer := time.NewTimer(timeout)
|
||||
|
||||
return &TimeoutCondWaiter{
|
||||
c: c,
|
||||
timer: timer,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *TimeoutCondWaiter) Wait() bool {
|
||||
// ch.L must be locked when calling this function
|
||||
|
||||
// Ensure that the channel exists, since we're going to be waiting on it
|
||||
if w.c.ch == nil {
|
||||
w.c.ch = make(chan struct{})
|
||||
}
|
||||
ch := w.c.ch
|
||||
|
||||
w.c.L.Unlock()
|
||||
defer w.c.L.Lock()
|
||||
|
||||
select {
|
||||
case <-w.timer.C:
|
||||
return false
|
||||
case <-ch:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (w *TimeoutCondWaiter) Stop() {
|
||||
w.timer.Stop()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user