Skip to content

Commit

Permalink
add support for drain
Browse files Browse the repository at this point in the history
Tested on Mac OS, Linux and Windows with UART emulated on USB.

I wrote general BSD code, because it should work, but I am not able to test
it.

On Mac OS I am quite sure that drain behaves as expected because it fixed
an issue with buffer overflow (which OS does not report but fails).

For Windows it seems that drain is actually part of `Write`, because
`Write` was long and `Drain` was fast. But I have not found any mention in
Win32 docs about buffering and asynchronous write, so I put there flushing
code to be sure, and this code did not break anything.

For Linux `Drain` is also taking more time than writing so it looks working
too.
  • Loading branch information
polomsky committed Jun 16, 2023
1 parent e381f2c commit ff38fe2
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 0 deletions.
3 changes: 3 additions & 0 deletions serial.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ type Port interface {
// Returns the number of bytes written.
Write(p []byte) (n int, err error)

// Wait until all data in the buffer are sent
Drain() error

// ResetInputBuffer Purges port read buffer
ResetInputBuffer() error

Expand Down
10 changes: 10 additions & 0 deletions serial_bsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
// +build darwin dragonfly freebsd netbsd openbsd

package serial

import "golang.org/x/sys/unix"

func (port *unixPort) Drain() error {
return unix.IoctlSetInt(port.handle, unix.TIOCDRAIN, 0)
}
10 changes: 10 additions & 0 deletions serial_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,13 @@ func setTermSettingsBaudrate(speed int, settings *unix.Termios) (error, bool) {
settings.Ospeed = toTermiosSpeedType(baudrate)
return nil, false
}

func (port *unixPort) Drain() error {
// simulate drain with change settings with TCSETSW
settings, err := port.getTermSettings()
if err != nil {
return err
}

return unix.IoctlSetTermios(port.handle, unix.TCSETSW, settings)
}
4 changes: 4 additions & 0 deletions serial_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ func (port *windowsPort) Write(p []byte) (int, error) {
return int(writed), err
}

func (port *windowsPort) Drain() (err error) {
return syscall.FlushFileBuffers(port.handle)
}

const (
purgeRxAbort uint32 = 0x0002
purgeRxClear = 0x0008
Expand Down

0 comments on commit ff38fe2

Please sign in to comment.