A premature waitgroup .Done resulted in reading from closed channel.
This caused a nil-pointer deref & crash.
Added additional debugging when closing routines.
// stop & wait for ongoing peer routines
- peer.routines.stop.Broadcast()
peer.routines.starting.Wait()
+ peer.routines.stop.Broadcast()
peer.routines.stopping.Wait()
// stop timers
logError := device.log.Error
logDebug := device.log.Debug
- func() {
- defer peer.routines.stopping.Done()
+ defer func() {
+ peer.routines.stopping.Done()
logDebug.Println(peer.String(), ": Routine, Sequential Receiver, Stopped")
}()
case <-peer.routines.stop.Wait():
return
- case elem := <-peer.queue.inbound:
+ case elem, ok := <-peer.queue.inbound:
+
+ if !ok {
+ return
+ }
// wait for decryption
*/
func (peer *Peer) RoutineSequentialSender() {
- defer peer.routines.stopping.Done()
-
device := peer.device
logDebug := device.log.Debug
logDebug.Println("Routine, sequential sender, started for", peer.String())
+ defer func() {
+ peer.routines.stopping.Done()
+ logDebug.Println(peer.String(), ": Routine, Sequential sender, Stopped")
+ }()
+
peer.routines.starting.Done()
for {
"Routine, sequential sender, stopped for", peer.String())
return
- case elem := <-peer.queue.outbound:
+ case elem, ok := <-peer.queue.outbound:
+
+ if !ok {
+ return
+ }
+
elem.mutex.Lock()
if elem.IsDropped() {
continue
func (peer *Peer) RoutineTimerHandler() {
- defer peer.routines.stopping.Done()
-
device := peer.device
logInfo := device.log.Info
logDebug := device.log.Debug
- logDebug.Println("Routine, timer handler, started for peer", peer.String())
+
+ defer func() {
+ logDebug.Println(peer.String(), ": Routine, Timer handler, Stopped")
+ peer.routines.stopping.Done()
+ }()
// reset all timers
peer.timer.keepalivePersistent.Reset(duration)
}
+ logDebug.Println("Routine, timer handler, started for peer", peer.String())
+
// signal synchronised setup complete
peer.routines.starting.Done()