FIX deadlock related to blocking channel sending
This commit is contained in:
parent
3051a1b5ea
commit
f575ab3cb4
2 changed files with 39 additions and 7 deletions
|
|
@ -24,6 +24,9 @@ type LuxNode struct {
|
||||||
state LuxNodeState
|
state LuxNodeState
|
||||||
stateLock deadlock.RWMutex
|
stateLock deadlock.RWMutex
|
||||||
|
|
||||||
|
subscribers []LuxNodeSubscriber
|
||||||
|
stopChan chan bool
|
||||||
|
|
||||||
genlist net.LuxNonceList
|
genlist net.LuxNonceList
|
||||||
|
|
||||||
dns *LuxDnsServer
|
dns *LuxDnsServer
|
||||||
|
|
@ -31,13 +34,15 @@ type LuxNode struct {
|
||||||
|
|
||||||
func NewLuxNode(nodeKey crypto.LuxKey, ks crypto.LuxKeyStore) LuxNode {
|
func NewLuxNode(nodeKey crypto.LuxKey, ks crypto.LuxKeyStore) LuxNode {
|
||||||
return LuxNode{
|
return LuxNode{
|
||||||
nodeId: &nodeKey.Id,
|
nodeId: &nodeKey.Id,
|
||||||
router: net.NewLuxRouter(nodeKey, ks),
|
router: net.NewLuxRouter(nodeKey, ks),
|
||||||
running: false,
|
running: false,
|
||||||
neighbors: make(map[proto.LuxID]*ipnet.UDPAddr),
|
neighbors: make(map[proto.LuxID]*ipnet.UDPAddr),
|
||||||
state: NewLuxNodeState(),
|
state: NewLuxNodeState(),
|
||||||
genlist: net.NewLuxNonceList(),
|
subscribers: make([]LuxNodeSubscriber, 0),
|
||||||
dns: nil,
|
stopChan: make(chan bool),
|
||||||
|
genlist: net.NewLuxNonceList(),
|
||||||
|
dns: nil,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,6 +90,10 @@ func (node *LuxNode) AddNeighbor(id proto.LuxID, udpAddr string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (node *LuxNode) AddSubscriber(subscriber LuxNodeSubscriber) {
|
||||||
|
node.subscribers = append(node.subscribers, subscriber)
|
||||||
|
}
|
||||||
|
|
||||||
func (node *LuxNode) AddDnsFrontend(udpListen string) error {
|
func (node *LuxNode) AddDnsFrontend(udpListen string) error {
|
||||||
if node.dns == nil {
|
if node.dns == nil {
|
||||||
node.dns = NewLuxDnsServer(node)
|
node.dns = NewLuxDnsServer(node)
|
||||||
|
|
@ -232,11 +241,27 @@ func nodeLoop(node *LuxNode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we need to read state from stateChan, or otherwise sending to it
|
||||||
|
// will block everything and cause deadlock
|
||||||
|
func subscriberLoop(node *LuxNode) {
|
||||||
|
for node.running {
|
||||||
|
select {
|
||||||
|
case <-node.stopChan:
|
||||||
|
return
|
||||||
|
case state := <-node.state.stateChan:
|
||||||
|
for _, subscriber := range node.subscribers {
|
||||||
|
subscriber.HandleStateUpdate(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (node *LuxNode) Start() {
|
func (node *LuxNode) Start() {
|
||||||
node.router.Start()
|
node.router.Start()
|
||||||
node.running = true
|
node.running = true
|
||||||
|
|
||||||
go nodeLoop(node)
|
go nodeLoop(node)
|
||||||
|
go subscriberLoop(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (node *LuxNode) Stop() {
|
func (node *LuxNode) Stop() {
|
||||||
|
|
@ -245,6 +270,8 @@ func (node *LuxNode) Stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
node.running = false
|
node.running = false
|
||||||
|
node.stopChan <- true
|
||||||
|
|
||||||
node.router.Stop()
|
node.router.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
5
node/lux_node_subscriber.go
Normal file
5
node/lux_node_subscriber.go
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
package node
|
||||||
|
|
||||||
|
type LuxNodeSubscriber interface {
|
||||||
|
HandleStateUpdate(state LuxHostState)
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue