Thanks to visit codestin.com
Credit goes to Github.com

Skip to content

No timeout in RTU Server causes some sort of deadlock #19

@thegreatco

Description

@thegreatco

I'm trying to test out the RTU Server.

If I specify a timeout, the server is unstable: it either times out before the client connects or closes if requests are not made often enough.

If I don't specify a timeout, the server seems to work great, but calling Close seems to block forever and I can't cleanly shut it down.

With timeout speciffied

package main

import (
	"os"
	"os/signal"
	"time"

	"github.com/goburrow/serial"
	"github.com/tbrandon/mbserver"
)

func main() {
	serv := mbserver.NewServer()
	err := serv.ListenRTU(&serial.Config{
		Address:  "/dev/ttyUSB0",
		BaudRate: 115200,
		DataBits: 8,
		StopBits: 1,
		Parity:   "N",
		Timeout:  10 * time.Second})
	if err != nil {
		panic(err)
	}
	println("Server is running...")
	defer func() {
		println("Stopping server...")
		serv.Close()
		println("Server stopped")
		os.Exit(0)
	}()
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	<-c
}

Output

$ go run main.go
Server is running...
2024/09/10 16:52:10 serial read error serial: timeout
^CStopping server...
Server stopped

Note that I was able to read/write several coils with no problem. But if I wait longer than the timeout period to issue another command, I get the serial read error, and all subsequent requests to the server fail. However, I am able to close the server down cleanly.

Without timeout

package main

import (
	"os"
	"os/signal"

	"github.com/goburrow/serial"
	"github.com/tbrandon/mbserver"
)

func main() {
	serv := mbserver.NewServer()
	err := serv.ListenRTU(&serial.Config{
		Address:  "/dev/ttyUSB0",
		BaudRate: 115200,
		DataBits: 8,
		StopBits: 1,
		Parity:   "N"})
	if err != nil {
		panic(err)
	}
	println("Server is running...")
	defer func() {
		println("Stopping server...")
		serv.Close()
		println("Server stopped")
		os.Exit(0)
	}()
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	<-c
}
$ go run main.go
Server is running...
^CStopping server...
signal: terminated

I am able to read/write many times, with large gaps in between with no issues. Note that the server only shuts down cleanly now when a kill <pid> is issued. The program hangs on serv.Close().

It seems there is some sort of deadlock here. I noticed in the docs a section on Race Conditions, however I'm not doing anything with goroutines here and the version with a timeout works just fine.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions