mirror of
https://github.com/luxfi/node.git
synced 2026-10-30 15:24:05 +00:00
The module already called itself github.com/luxfi/node while containing no node in Go: cmd/luxd was twenty-one lines that printed the size of a few types, and the Go column of the matrix measured a VM plugin. A repo that fetches the thing it claims to be has not replaced it, so the Go sources move in — 1515 files, the daemon and everything under it — and the build reaches outside this module for nothing. Rust and C++ sit beside it unchanged and are still measured against it by the differential. That is the point of one repo: the reference implementation and the two ports are the same checkout, so parity is a thing you can run rather than a thing you assert. Verified: builds, and the closure carries no lux-private — checked at build time rather than believed. The daemon starts twelve chains on a local network (P X C Q Z A B G K M F, plus D through its plugin) and reports healthy.
109 lines
2.0 KiB
Go
109 lines
2.0 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package timer
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// Timer wraps a timer object. This allows a user to specify a handler. Once
|
|
// specifying the handler, the dispatch thread can be called. The dispatcher
|
|
// will only return after calling Stop. SetTimeoutIn will result in calling the
|
|
// handler in the specified amount of time.
|
|
type Timer struct {
|
|
handler func()
|
|
timeout chan struct{}
|
|
|
|
lock sync.Mutex
|
|
wg sync.WaitGroup
|
|
finished, shouldExecute bool
|
|
duration time.Duration
|
|
}
|
|
|
|
// NewTimer creates a new timer object
|
|
func NewTimer(handler func()) *Timer {
|
|
timer := &Timer{
|
|
handler: handler,
|
|
timeout: make(chan struct{}, 1),
|
|
}
|
|
timer.wg.Add(1)
|
|
|
|
return timer
|
|
}
|
|
|
|
// SetTimeoutIn will set the timer to fire the handler in [duration]
|
|
func (t *Timer) SetTimeoutIn(duration time.Duration) {
|
|
t.lock.Lock()
|
|
defer t.lock.Unlock()
|
|
|
|
t.duration = duration
|
|
t.shouldExecute = true
|
|
t.reset()
|
|
}
|
|
|
|
// Cancel the currently scheduled event
|
|
func (t *Timer) Cancel() {
|
|
t.lock.Lock()
|
|
defer t.lock.Unlock()
|
|
|
|
t.shouldExecute = false
|
|
t.reset()
|
|
}
|
|
|
|
// Stop this timer from executing any more.
|
|
func (t *Timer) Stop() {
|
|
t.lock.Lock()
|
|
if !t.finished {
|
|
defer t.wg.Wait()
|
|
}
|
|
defer t.lock.Unlock()
|
|
|
|
t.finished = true
|
|
t.reset()
|
|
}
|
|
|
|
func (t *Timer) Dispatch() {
|
|
t.lock.Lock()
|
|
defer t.lock.Unlock()
|
|
defer t.wg.Done()
|
|
|
|
timer := time.NewTimer(0)
|
|
cleared := false
|
|
reset := false
|
|
for !t.finished { // t.finished needs to be thread safe
|
|
if !reset && !timer.Stop() && !cleared {
|
|
<-timer.C
|
|
}
|
|
|
|
if cleared && t.shouldExecute {
|
|
t.lock.Unlock()
|
|
t.handler()
|
|
} else {
|
|
t.lock.Unlock()
|
|
}
|
|
|
|
cleared = false
|
|
reset = false
|
|
select {
|
|
case <-t.timeout:
|
|
t.lock.Lock()
|
|
if t.shouldExecute {
|
|
timer.Reset(t.duration)
|
|
}
|
|
reset = true
|
|
case <-timer.C:
|
|
t.lock.Lock()
|
|
cleared = true
|
|
}
|
|
}
|
|
}
|
|
|
|
func (t *Timer) reset() {
|
|
select {
|
|
case t.timeout <- struct{}{}:
|
|
default:
|
|
}
|
|
}
|