mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-26 21:51:27 +02:00
protofsm: add thread-safe IsRunning method to StateMachine
This commit introduces a new `IsRunning()` method to the `StateMachine`. This method allows callers to safely query whether the state machine is currently active after it has been started and before it has been stopped. To ensure thread-safety, the internal `running` status flag is implemented using `atomic.Bool` (from `sync/atomic`). Without atomic operations, concurrent accesses to a simple boolean flag from different goroutines (e.g., one goroutine calling `IsRunning()` while another executes `Start()` or `Stop()`) could lead to stale reads or data races.
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
@@ -150,8 +151,14 @@ type StateMachine[Event any, Env Environment] struct {
|
||||
gm fn.GoroutineManager
|
||||
quit chan struct{}
|
||||
|
||||
// startOnce and stopOnce are used to ensure that the state machine is
|
||||
// only started and stopped once.
|
||||
startOnce sync.Once
|
||||
stopOnce sync.Once
|
||||
|
||||
// running is a flag that indicates if the state machine is currently
|
||||
// running.
|
||||
running atomic.Bool
|
||||
}
|
||||
|
||||
// ErrorReporter is an interface that's used to report errors that occur during
|
||||
@@ -221,6 +228,8 @@ func (s *StateMachine[Event, Env]) Start(ctx context.Context) {
|
||||
_ = s.gm.Go(ctx, func(ctx context.Context) {
|
||||
s.driveMachine(ctx)
|
||||
})
|
||||
|
||||
s.running.Store(true)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -230,6 +239,8 @@ func (s *StateMachine[Event, Env]) Stop() {
|
||||
s.stopOnce.Do(func() {
|
||||
close(s.quit)
|
||||
s.gm.Stop()
|
||||
|
||||
s.running.Store(false)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -333,6 +344,11 @@ func (s *StateMachine[Event, Env]) RemoveStateSub(sub StateSubscriber[
|
||||
_ = s.newStateEvents.RemoveSubscriber(sub)
|
||||
}
|
||||
|
||||
// IsRunning returns true if the state machine is currently running.
|
||||
func (s *StateMachine[Event, Env]) IsRunning() bool {
|
||||
return s.running.Load()
|
||||
}
|
||||
|
||||
// executeDaemonEvent executes a daemon event, which is a special type of event
|
||||
// that can be emitted as part of the state transition function of the state
|
||||
// machine. An error is returned if the type of event is unknown.
|
||||
|
Reference in New Issue
Block a user