From 98c68ccd0df3e976c3b7992968852e6ae0b9595c Mon Sep 17 00:00:00 2001 From: Přemysl Eric Janouch Date: Sat, 9 Nov 2024 10:27:24 +0100 Subject: WIP: xA: make sending work somehow --- xA/xA.go | 54 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/xA/xA.go b/xA/xA.go index 3934849..b9f79ec 100644 --- a/xA/xA.go +++ b/xA/xA.go @@ -15,6 +15,7 @@ import ( "net" "os" "slices" + "sync" "time" "fyne.io/fyne/v2" @@ -167,6 +168,9 @@ var ( backendAddress string backendContext context.Context backendCancel context.CancelFunc + backendConn net.Conn + + backendLock sync.Mutex // Connection state: @@ -231,20 +235,27 @@ func relayReadMessage(r io.Reader) (m RelayEventMessage, ok bool) { return m, true } -func relayWriteMessage(conn net.Conn, data RelayCommandData) bool { +func relaySend(data RelayCommandData, callback callback) bool { + backendLock.Lock() + defer backendLock.Unlock() + m := RelayCommandMessage{ CommandSeq: commandSeq, Data: data, } + if callback != nil { + commandCallbacks[m.CommandSeq] = callback + } commandSeq++ + // TODO(p): Handle errors better. b, ok := m.AppendTo(make([]byte, 4)) if !ok { log.Println("Command serialization failed") return false } binary.BigEndian.PutUint32(b[:4], uint32(len(b)-4)) - if _, err := conn.Write(b); err != nil { + if _, err := backendConn.Write(b); err != nil { log.Println("Command send failed: " + err.Error()) return false } @@ -255,15 +266,6 @@ func relayWriteMessage(conn net.Conn, data RelayCommandData) bool { return true } -func relaySend(data RelayCommandData, callback callback) { - if callback != nil { - commandCallbacks[commandSeq] = callback - } - - // TODO(p): Get the net.Conn from somewhere. - //relayWriteMessage(nil, data) -} - // --- Buffers ----------------------------------------------------------------- func bufferByName(name string) *buffer { @@ -619,7 +621,9 @@ func relayProcessBufferLine(b *buffer, m *RelayEventDataBufferLine) { func relayProcessCallbacks( commandSeq uint32, err string, response *RelayResponseData) { if handler, ok := commandCallbacks[commandSeq]; !ok { - // TODO(p): Warn about an unawaited response. + if *debug { + log.Printf("unawaited response: %+v\n", *response) + } } else { delete(commandCallbacks, commandSeq) if handler != nil { @@ -833,27 +837,25 @@ func relayRun() { backendContext, backendCancel = context.WithCancel(context.Background()) defer backendCancel() - conn, err := net.Dial("tcp", backendAddress) + var err error + backendLock.Lock() + backendConn, err = net.Dial("tcp", backendAddress) + backendLock.Unlock() if err != nil { log.Println("Connection failed: " + err.Error()) // TODO(p): Display errors to the user. return } - defer conn.Close() - - // TODO(p): How to send messages? - // - It would probably make the most sense to have either a chan - // (which makes code synchronize), or a locked slice. - // - But I also need to wake the sender up somehow, - // so maybe use a channel after all. - // - Or maybe use a channel just for the signalling. - // - Sending (semi-)synchronously is also an option, perhaps. - // TODO(p): Handle any errors here. - _ = relayWriteMessage(conn, RelayCommandData{ + defer backendConn.Close() + + // TODO(p): Figure out locking. + // - Messages are currently sent (semi-)synchronously, directly. + // - Is the net.Conn actually async-safe? + relaySend(RelayCommandData{ Variant: &RelayCommandDataHello{Version: RelayVersion}, - }) + }, nil) - relayMessages := relayMakeReceiver(backendContext, conn) + relayMessages := relayMakeReceiver(backendContext, backendConn) for { select { case m, ok := <-relayMessages: -- cgit v1.2.3-70-g09d2