github.com/mailru/activerecord@v1.12.2/pkg/iproto/util/time/timer.go (about)

     1  package time
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  )
     7  
     8  var timerPool sync.Pool
     9  
    10  func AcquireTimer(d time.Duration) *time.Timer {
    11  	v := timerPool.Get()
    12  	if v == nil {
    13  		return time.NewTimer(d)
    14  	}
    15  
    16  	tm := v.(*time.Timer)
    17  	if tm.Reset(d) {
    18  		panic("Received an active timer from the pool!")
    19  	}
    20  
    21  	return tm
    22  }
    23  
    24  func ReleaseTimer(tm *time.Timer) {
    25  	if !tm.Stop() {
    26  		// Timer is already stopped and possibly filled or will be filled with time in timer.C.
    27  		// We could not guarantee that timer.C will not be filled even after timer.Stop().
    28  		//
    29  		// It is a known "bug" in golang:
    30  		// See https://groups.google.com/forum/#!topic/golang-nuts/-8O3AknKpwk
    31  		//
    32  		// The tip from manual to read from timer.C possibly blocks caller if caller has already done <-timer.C.
    33  		// Non-blocking read from timer.C with select does not help either because send is done concurrently
    34  		// from another goroutine.
    35  		return
    36  	}
    37  
    38  	timerPool.Put(tm)
    39  }