Removed port-alive-check loop on Windows implementation
This commit is contained in:
@@ -24,9 +24,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type windowsPort struct {
|
type windowsPort struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
handle syscall.Handle
|
handle syscall.Handle
|
||||||
readTimeoutCycles int64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func nativeGetPortsList() ([]string, error) {
|
func nativeGetPortsList() ([]string, error) {
|
||||||
@@ -83,38 +82,26 @@ func (port *windowsPort) Read(p []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
defer syscall.CloseHandle(ev.HEvent)
|
defer syscall.CloseHandle(ev.HEvent)
|
||||||
|
|
||||||
cycles := int64(0)
|
err = syscall.ReadFile(port.handle, p, &readed, ev)
|
||||||
for {
|
if err == syscall.ERROR_IO_PENDING {
|
||||||
err := syscall.ReadFile(port.handle, p, &readed, ev)
|
err = getOverlappedResult(port.handle, ev, &readed, true)
|
||||||
if err == syscall.ERROR_IO_PENDING {
|
|
||||||
err = getOverlappedResult(port.handle, ev, &readed, true)
|
|
||||||
}
|
|
||||||
switch err {
|
|
||||||
case nil:
|
|
||||||
// operation completed successfully
|
|
||||||
case syscall.ERROR_OPERATION_ABORTED:
|
|
||||||
// port may have been closed
|
|
||||||
return int(readed), &PortError{code: PortClosed, causedBy: err}
|
|
||||||
default:
|
|
||||||
// error happened
|
|
||||||
return int(readed), err
|
|
||||||
}
|
|
||||||
|
|
||||||
if readed > 0 {
|
|
||||||
return int(readed), nil
|
|
||||||
}
|
|
||||||
if err := resetEvent(ev.HEvent); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if port.readTimeoutCycles != -1 {
|
|
||||||
cycles++
|
|
||||||
if cycles == port.readTimeoutCycles {
|
|
||||||
// Timeout
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
// operation completed successfully
|
||||||
|
case syscall.ERROR_OPERATION_ABORTED:
|
||||||
|
// port may have been closed
|
||||||
|
return int(readed), &PortError{code: PortClosed, causedBy: err}
|
||||||
|
default:
|
||||||
|
// error happened
|
||||||
|
return int(readed), err
|
||||||
|
}
|
||||||
|
if readed > 0 {
|
||||||
|
return int(readed), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timeout
|
||||||
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (port *windowsPort) Write(p []byte) (int, error) {
|
func (port *windowsPort) Write(p []byte) (int, error) {
|
||||||
@@ -372,26 +359,24 @@ func (port *windowsPort) GetModemStatusBits() (*ModemStatusBits, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (port *windowsPort) SetReadTimeout(timeout time.Duration) error {
|
func (port *windowsPort) SetReadTimeout(timeout time.Duration) error {
|
||||||
var cycles, cycleDuration int64
|
commTimeouts := &commTimeouts{
|
||||||
if timeout == NoTimeout {
|
|
||||||
cycles = -1
|
|
||||||
cycleDuration = 1000
|
|
||||||
} else {
|
|
||||||
cycles = timeout.Milliseconds()/1000 + 1
|
|
||||||
cycleDuration = timeout.Milliseconds() / cycles
|
|
||||||
}
|
|
||||||
|
|
||||||
err := setCommTimeouts(port.handle, &commTimeouts{
|
|
||||||
ReadIntervalTimeout: 0xFFFFFFFF,
|
ReadIntervalTimeout: 0xFFFFFFFF,
|
||||||
ReadTotalTimeoutMultiplier: 0xFFFFFFFF,
|
ReadTotalTimeoutMultiplier: 0xFFFFFFFF,
|
||||||
ReadTotalTimeoutConstant: uint32(cycleDuration),
|
ReadTotalTimeoutConstant: 0xFFFFFFFE,
|
||||||
WriteTotalTimeoutConstant: 0,
|
WriteTotalTimeoutConstant: 0,
|
||||||
WriteTotalTimeoutMultiplier: 0,
|
WriteTotalTimeoutMultiplier: 0,
|
||||||
})
|
}
|
||||||
if err != nil {
|
if timeout != NoTimeout {
|
||||||
|
ms := timeout.Milliseconds()
|
||||||
|
if ms > 0xFFFFFFFE || ms < 0 {
|
||||||
|
return &PortError{code: InvalidTimeoutValue}
|
||||||
|
}
|
||||||
|
commTimeouts.ReadTotalTimeoutConstant = uint32(ms)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := setCommTimeouts(port.handle, commTimeouts); err != nil {
|
||||||
return &PortError{code: InvalidTimeoutValue, causedBy: err}
|
return &PortError{code: InvalidTimeoutValue, causedBy: err}
|
||||||
}
|
}
|
||||||
port.readTimeoutCycles = cycles
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user