From 938e92387ae1aa3f771ed219ee65b2dbc34b6738 Mon Sep 17 00:00:00 2001 From: xengineering Date: Mon, 3 Jul 2023 13:58:58 +0200 Subject: Fix race condition on struct Limox To make message passing to the XMPP session channel non-blocking short living Goroutines are used. Before this commit they were executing closures which capture l as xengineering.eu/limox.Limox pointer and used it to get the channel where the message should be passed to. While channels are safe with respect to race conditions, structs are not. Thus the member access of the Limox struct was a race condition in certain side cases like bad network connection where those Goroutines lived for a longer time. The solution is to make a copy of the l.sessionIn channel and use this copy in the closures. This is valid since channels do not need pointers to them and furthermore are thread safe. --- limox.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/limox.go b/limox.go index 87e20de..5bb2d57 100644 --- a/limox.go +++ b/limox.go @@ -80,6 +80,7 @@ func (l *Limox) run() error { } func (l *Limox) buttonCallback() { + c := l.sessionIn switch l.State { case Disconnected: jid := l.JidEditor.Text() @@ -89,10 +90,10 @@ func (l *Limox) buttonCallback() { l.sessionIn = xmpp.StartSession(l.sessionOut, jid, pwd) l.State = Connecting case Connecting: - go func() { l.sessionIn <- xmpp.SessionShouldDisconnect{} }() + go func() { c <- xmpp.SessionShouldDisconnect{} }() l.State = Disconnected case Connected: - go func() { l.sessionIn <- xmpp.SessionShouldDisconnect{} }() + go func() { c <- xmpp.SessionShouldDisconnect{} }() l.State = Disconnected } } -- cgit v1.2.3-70-g09d2