github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/timer/timer-sync.go (about) 1 /* For license and copyright information please see the LEGAL file in the code repository */ 2 3 package timer 4 5 import ( 6 "github.com/GeniusesGroup/libgo/protocol" 7 ) 8 9 // After waits for the duration to elapse and then sends signal on the returned channel. 10 // The underlying Timer is not recovered by the garbage collector 11 // until the timer fires. If efficiency is a concern, copy the body 12 // instead and call timer.Stop() if the timer is no longer needed. 13 // It will **panic** if it can't start the timer due to any situation like not enough memory, ... 14 func After(d protocol.Duration) <-chan struct{} { 15 var timer Sync 16 timer.Init() 17 var err = timer.Start(d) 18 if err != nil { 19 panic(err) 20 } 21 return timer.Signal() 22 } 23 24 // NewAsync waits for the duration to elapse and then calls callback. 25 // If callback need blocking operation it must do its logic in new thread(goroutine). 26 // It returns a SyncTimer that can be used to cancel the call using its Stop method. 27 func NewSync(d protocol.Duration) (t *Sync, err protocol.Error) { 28 var timer Sync 29 timer.Init() 30 err = timer.Start(d) 31 t = &timer 32 return 33 } 34 35 // Sync Timer must be created with Init, After or AfterFunc. 36 type Sync struct { 37 Async 38 signal chan struct{} 39 } 40 41 func (t *Sync) Reinit() { t.Stop(); close(t.signal); t.Async.Reinit() } 42 func (t *Sync) Deinit() { t.Stop(); close(t.signal) } 43 44 //libgo:impl protocol.Timer 45 func (t *Sync) Init() { 46 // Give the channel a 1-element buffer. 47 // If the client falls behind while reading, we drop ticks 48 // on the floor until the client catches up. 49 t.signal = make(chan struct{}, 1) 50 t.Async.Init(t) 51 } 52 func (t *Sync) Signal() <-chan struct{} { return t.signal } 53 func (t *Sync) Start(d protocol.Duration) (err protocol.Error) { return t.Async.Start(d) } 54 func (t *Sync) Stop() (alreadyStopped bool) { return t.Async.Stop() } 55 func (t *Sync) Reset(d protocol.Duration) (alreadyActivated bool) { return t.Modify(d) } 56 57 // TimerHandler or NotifyChannel does a non-blocking send the signal on t.signal 58 func (t *Sync) TimerHandler() { 59 select { 60 case t.signal <- struct{}{}: 61 default: 62 } 63 }