"Fossies" - the Fresh Open Source Software Archive

Member "gdrive-2.1.1/drive/timeout_reader.go" (28 May 2021, 2150 Bytes) of package /linux/misc/gdrive-2.1.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 package drive
    2 
    3 import (
    4     "golang.org/x/net/context"
    5     "io"
    6     "sync"
    7     "time"
    8 )
    9 
   10 const TimeoutTimerInterval = time.Second * 10
   11 
   12 type timeoutReaderWrapper func(io.Reader) io.Reader
   13 
   14 func getTimeoutReaderWrapperContext(timeout time.Duration) (timeoutReaderWrapper, context.Context) {
   15     ctx, cancel := context.WithCancel(context.TODO())
   16     wrapper := func(r io.Reader) io.Reader {
   17         // Return untouched reader if timeout is 0
   18         if timeout == 0 {
   19             return r
   20         }
   21 
   22         return getTimeoutReader(r, cancel, timeout)
   23     }
   24     return wrapper, ctx
   25 }
   26 
   27 func getTimeoutReaderContext(r io.Reader, timeout time.Duration) (io.Reader, context.Context) {
   28     ctx, cancel := context.WithCancel(context.TODO())
   29 
   30     // Return untouched reader if timeout is 0
   31     if timeout == 0 {
   32         return r, ctx
   33     }
   34 
   35     return getTimeoutReader(r, cancel, timeout), ctx
   36 }
   37 
   38 func getTimeoutReader(r io.Reader, cancel context.CancelFunc, timeout time.Duration) io.Reader {
   39     return &TimeoutReader{
   40         reader:         r,
   41         cancel:         cancel,
   42         mutex:          &sync.Mutex{},
   43         maxIdleTimeout: timeout,
   44     }
   45 }
   46 
   47 type TimeoutReader struct {
   48     reader         io.Reader
   49     cancel         context.CancelFunc
   50     lastActivity   time.Time
   51     timer          *time.Timer
   52     mutex          *sync.Mutex
   53     maxIdleTimeout time.Duration
   54     done           bool
   55 }
   56 
   57 func (self *TimeoutReader) Read(p []byte) (int, error) {
   58     if self.timer == nil {
   59         self.startTimer()
   60     }
   61 
   62     self.mutex.Lock()
   63 
   64     // Read
   65     n, err := self.reader.Read(p)
   66 
   67     self.lastActivity = time.Now()
   68     self.done = (err != nil)
   69 
   70     self.mutex.Unlock()
   71 
   72     if self.done {
   73         self.stopTimer()
   74     }
   75 
   76     return n, err
   77 }
   78 
   79 func (self *TimeoutReader) startTimer() {
   80     self.mutex.Lock()
   81     defer self.mutex.Unlock()
   82 
   83     if !self.done {
   84         self.timer = time.AfterFunc(TimeoutTimerInterval, self.timeout)
   85     }
   86 }
   87 
   88 func (self *TimeoutReader) stopTimer() {
   89     self.mutex.Lock()
   90     defer self.mutex.Unlock()
   91 
   92     if self.timer != nil {
   93         self.timer.Stop()
   94     }
   95 }
   96 
   97 func (self *TimeoutReader) timeout() {
   98     self.mutex.Lock()
   99 
  100     if self.done {
  101         self.mutex.Unlock()
  102         return
  103     }
  104 
  105     if time.Since(self.lastActivity) > self.maxIdleTimeout {
  106         self.cancel()
  107         self.mutex.Unlock()
  108         return
  109     }
  110 
  111     self.mutex.Unlock()
  112     self.startTimer()
  113 }