This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 04a37a2d699525dff68fb426248e577d2fb3a730
Author: Sebastian Rühl <[email protected]>
AuthorDate: Mon Jul 6 11:37:56 2026 +0200

    fix(plc4go): serial transport deadline and connected-state follow-ups
    
    - Write: clear the write deadline when the context has none, so a lapsed
      deadline from a previous call no longer fails later writes with a
      spurious i/o timeout
    - IsConnected: key on the connected flag (like the TCP transport) instead
      of a lock-free read of the port field
---
 plc4go/spi/transports/serial/TransportInstance.go       |  4 +++-
 .../spi/transports/serial/TransportInstance_pty_test.go | 16 ++++++++++++++++
 plc4go/spi/transports/serial/TransportInstance_test.go  | 17 +++++++++++++++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/plc4go/spi/transports/serial/TransportInstance.go 
b/plc4go/spi/transports/serial/TransportInstance.go
index 5868efbc25..772ae3b9f4 100644
--- a/plc4go/spi/transports/serial/TransportInstance.go
+++ b/plc4go/spi/transports/serial/TransportInstance.go
@@ -113,7 +113,7 @@ func (m *TransportInstance) Close() error {
 }
 
 func (m *TransportInstance) IsConnected() bool {
-       return m.serialPort != nil
+       return m.connected.Load()
 }
 
 func (m *TransportInstance) Write(ctx context.Context, data []byte) error {
@@ -127,6 +127,8 @@ func (m *TransportInstance) Write(ctx context.Context, data 
[]byte) error {
                if err := m.serialPort.SetWriteDeadline(deadline); err != nil {
                        return errors.Wrap(err, "error setting write deadline")
                }
+       } else if err := m.serialPort.SetWriteDeadline(time.Time{}); err != nil 
{
+               return errors.Wrap(err, "error clearing write deadline")
        }
        num, err := m.serialPort.Write(data)
        if err != nil {
diff --git a/plc4go/spi/transports/serial/TransportInstance_pty_test.go 
b/plc4go/spi/transports/serial/TransportInstance_pty_test.go
index b33456eaa3..04b3255e9a 100644
--- a/plc4go/spi/transports/serial/TransportInstance_pty_test.go
+++ b/plc4go/spi/transports/serial/TransportInstance_pty_test.go
@@ -89,3 +89,19 @@ func TestTransportInstance_CloseIsIdempotentOnPTY(t 
*testing.T) {
        assert.False(t, instance.IsConnected())
        require.NoError(t, instance.Close(), "second close must be a no-op")
 }
+
+func TestTransportInstance_WriteDeadlineDoesNotStick(t *testing.T) {
+       _, slavePath := openPTY(t)
+       instance := NewTransportInstance(slavePath, 9600, 1, NewTransport())
+       require.NoError(t, instance.Connect(context.Background()))
+       t.Cleanup(func() { _ = instance.Close() })
+
+       shortCtx, cancel := context.WithTimeout(context.Background(), 
30*time.Millisecond)
+       defer cancel()
+       require.NoError(t, instance.Write(shortCtx, []byte{0x01}))
+
+       time.Sleep(60 * time.Millisecond) // let the first write's deadline 
lapse
+
+       // A deadline-less write must not inherit the lapsed deadline.
+       require.NoError(t, instance.Write(context.Background(), []byte{0x02}))
+}
diff --git a/plc4go/spi/transports/serial/TransportInstance_test.go 
b/plc4go/spi/transports/serial/TransportInstance_test.go
index e3f5f76145..6690958468 100644
--- a/plc4go/spi/transports/serial/TransportInstance_test.go
+++ b/plc4go/spi/transports/serial/TransportInstance_test.go
@@ -267,3 +267,20 @@ func TestTransportInstance_Write(t *testing.T) {
                })
        }
 }
+
+// stubPort is a minimal serialport.Port for white-box state tests.
+type stubPort struct{}
+
+func (stubPort) Read([]byte) (int, error)         { return 0, nil }
+func (stubPort) Write(p []byte) (int, error)      { return len(p), nil }
+func (stubPort) Close() error                     { return nil }
+func (stubPort) SetReadDeadline(time.Time) error  { return nil }
+func (stubPort) SetWriteDeadline(time.Time) error { return nil }
+
+func TestTransportInstance_IsConnected_keysOnConnectedFlag(t *testing.T) {
+       m := &TransportInstance{}
+       m.serialPort = stubPort{}
+       assert.False(t, m.IsConnected(), "a port that never connected must not 
report connected")
+       m.connected.Store(true)
+       assert.True(t, m.IsConnected())
+}

Reply via email to