mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Fix deadlocks
This commit is contained in:
		
							parent
							
								
									7341fcb9bc
								
							
						
					
					
						commit
						5ca81f916e
					
				
					 1 changed files with 30 additions and 17 deletions
				
			
		| 
						 | 
				
			
			@ -5,6 +5,7 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
	"net"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/Arceliar/phony"
 | 
			
		||||
| 
						 | 
				
			
			@ -28,7 +29,7 @@ type Multicast struct {
 | 
			
		|||
	groupAddr       string
 | 
			
		||||
	listeners       map[string]*listenerInfo
 | 
			
		||||
	listenPort      uint16
 | 
			
		||||
	isOpen          bool
 | 
			
		||||
	isOpen          atomic.Value // bool
 | 
			
		||||
	announcer       *time.Timer
 | 
			
		||||
	platformhandler *time.Timer
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +49,7 @@ func (m *Multicast) Init(core *yggdrasil.Core, state *config.NodeState, log *log
 | 
			
		|||
	current := m.config.GetCurrent()
 | 
			
		||||
	m.listenPort = current.LinkLocalTCPPort
 | 
			
		||||
	m.groupAddr = "[ff02::114]:9001"
 | 
			
		||||
	m.isOpen.Store(false)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -59,15 +61,16 @@ func (m *Multicast) Start() error {
 | 
			
		|||
	phony.Block(m, func() {
 | 
			
		||||
		err = m._start()
 | 
			
		||||
	})
 | 
			
		||||
	m.log.Debugln("Started multicast module")
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Multicast) _start() error {
 | 
			
		||||
	if m.isOpen {
 | 
			
		||||
	if m.IsStarted() {
 | 
			
		||||
		return fmt.Errorf("multicast module is already started")
 | 
			
		||||
	}
 | 
			
		||||
	if len(m.config.GetCurrent().MulticastInterfaces) == 0 {
 | 
			
		||||
		return fmt.Errorf("no MulticastInterfaces configured")
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	m.log.Infoln("Starting multicast module")
 | 
			
		||||
	addr, err := net.ResolveUDPAddr("udp", m.groupAddr)
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +90,7 @@ func (m *Multicast) _start() error {
 | 
			
		|||
		// Windows can't set this flag, so we need to handle it in other ways
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.isOpen = true
 | 
			
		||||
	m.isOpen.Store(true)
 | 
			
		||||
	go m.listen()
 | 
			
		||||
	m.Act(m, m.multicastStarted)
 | 
			
		||||
	m.Act(m, m.announce)
 | 
			
		||||
| 
						 | 
				
			
			@ -97,21 +100,25 @@ func (m *Multicast) _start() error {
 | 
			
		|||
 | 
			
		||||
// IsStarted returns true if the module has been started.
 | 
			
		||||
func (m *Multicast) IsStarted() bool {
 | 
			
		||||
	var isOpen bool
 | 
			
		||||
	phony.Block(m, func() {
 | 
			
		||||
		isOpen = m.isOpen
 | 
			
		||||
	})
 | 
			
		||||
	return isOpen
 | 
			
		||||
	if m.isOpen.Load() == nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return m.isOpen.Load().(bool)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stop stops the multicast module.
 | 
			
		||||
func (m *Multicast) Stop() {
 | 
			
		||||
	m.Act(m, m._stop)
 | 
			
		||||
func (m *Multicast) Stop() error {
 | 
			
		||||
	var err error
 | 
			
		||||
	phony.Block(m, func() {
 | 
			
		||||
		err = m._stop()
 | 
			
		||||
	})
 | 
			
		||||
	m.log.Debugln("Stopped multicast module")
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Multicast) _stop() {
 | 
			
		||||
func (m *Multicast) _stop() error {
 | 
			
		||||
	m.log.Infoln("Stopping multicast module")
 | 
			
		||||
	m.isOpen = false
 | 
			
		||||
	m.isOpen.Store(false)
 | 
			
		||||
	if m.announcer != nil {
 | 
			
		||||
		m.announcer.Stop()
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -119,6 +126,7 @@ func (m *Multicast) _stop() {
 | 
			
		|||
		m.platformhandler.Stop()
 | 
			
		||||
	}
 | 
			
		||||
	m.sock.Close()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UpdateConfig updates the multicast module with the provided config.NodeConfig
 | 
			
		||||
| 
						 | 
				
			
			@ -129,17 +137,22 @@ func (m *Multicast) UpdateConfig(config *config.NodeConfig) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (m *Multicast) _updateConfig(config *config.NodeConfig) {
 | 
			
		||||
	m.log.Debugln("Reloading multicast configuration...")
 | 
			
		||||
	m.log.Infoln("Reloading multicast configuration...")
 | 
			
		||||
	if m.IsStarted() {
 | 
			
		||||
		if len(config.MulticastInterfaces) == 0 || config.LinkLocalTCPPort != m.listenPort {
 | 
			
		||||
			m.Stop()
 | 
			
		||||
			if err := m._stop(); err != nil {
 | 
			
		||||
				m.log.Errorln("Error stopping multicast module:", err)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	m.config.Replace(*config)
 | 
			
		||||
	m.listenPort = config.LinkLocalTCPPort
 | 
			
		||||
	if !m.IsStarted() && len(config.MulticastInterfaces) > 0 {
 | 
			
		||||
		m.Start()
 | 
			
		||||
		if err := m._start(); err != nil {
 | 
			
		||||
			m.log.Errorln("Error starting multicast module:", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	m.log.Debugln("Reloaded multicast configuration successfully")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetInterfaces returns the currently known/enabled multicast interfaces. It is
 | 
			
		||||
| 
						 | 
				
			
			@ -312,7 +325,7 @@ func (m *Multicast) listen() {
 | 
			
		|||
	for {
 | 
			
		||||
		nBytes, rcm, fromAddr, err := m.sock.ReadFrom(bs)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if !m.isOpen {
 | 
			
		||||
			if !m.IsStarted() {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			panic(err)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue