github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/dnet/deadline.go (about)

     1  // atomicDeadline is substantially based on pipeDeadline from Go 1.17.1 net/pipe.go.
     2  //
     3  // Copyright 2021 Datawire. All rights reserved.
     4  //
     5  // Copyright 2010 The Go Authors. All rights reserved.
     6  // Use of this source code is governed by a BSD-style
     7  // license that can be found in the LICENSE file.
     8  
     9  package dnet
    10  
    11  import (
    12  	"sync"
    13  	"sync/atomic"
    14  	"time"
    15  )
    16  
    17  type atomicDeadline struct {
    18  	// cbMu and timerMu must not be held at the same time.
    19  
    20  	// config
    21  
    22  	cbMu sync.Locker // must be held to call cb
    23  	cb   func()
    24  
    25  	// state
    26  
    27  	timerMu sync.Mutex // Guards timer
    28  	timer   *time.Timer
    29  
    30  	canceled int32 // atomic
    31  }
    32  
    33  func (d *atomicDeadline) set(t time.Time) {
    34  	d.timerMu.Lock()
    35  
    36  	if d.timer != nil {
    37  		d.timer.Stop()
    38  		d.timer = nil
    39  	}
    40  
    41  	if t.IsZero() {
    42  		// Time is zero, then there is no deadline.
    43  		d.timerMu.Unlock()
    44  		d.cbMu.Lock()
    45  		atomic.StoreInt32(&d.canceled, 0)
    46  		d.cbMu.Unlock()
    47  	} else if dur := time.Until(t); dur > 0 {
    48  		// Time is in the future, set up a timer to cancel in the future.
    49  		d.timer = time.AfterFunc(dur, func() {
    50  			d.cbMu.Lock()
    51  			atomic.StoreInt32(&d.canceled, 1)
    52  			d.cb()
    53  			d.cbMu.Unlock()
    54  		})
    55  		d.timerMu.Unlock()
    56  	} else {
    57  		// time is in the past, so cancel immediately.
    58  		d.timerMu.Unlock()
    59  		d.cbMu.Lock()
    60  		atomic.StoreInt32(&d.canceled, 1)
    61  		d.cb()
    62  		d.cbMu.Unlock()
    63  	}
    64  }
    65  
    66  func (d *atomicDeadline) isCanceled() bool {
    67  	return atomic.LoadInt32(&d.canceled) != 0
    68  }