Skip to content

Commit 1ff9b6f

Browse files
committed
If the timeout is set to NoTimeout, make Read wait forever.
Otherwise the maximul allowed timeout is 0x7FFFFFFF milliseconds, equivalent to about 24.85 days. This patch will make a transparent repeated read in case this long timeout should ever happen.
1 parent fb4b111 commit 1ff9b6f

File tree

1 file changed

+32
-21
lines changed

1 file changed

+32
-21
lines changed

serial_windows.go

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ import (
2828
)
2929

3030
type windowsPort struct {
31-
mu sync.Mutex
32-
handle windows.Handle
31+
mu sync.Mutex
32+
handle windows.Handle
33+
hasTimeout bool
3334
}
3435

3536
func nativeGetPortsList() ([]string, error) {
@@ -72,26 +73,33 @@ func (port *windowsPort) Read(p []byte) (int, error) {
7273
}
7374
defer windows.CloseHandle(ev.HEvent)
7475

75-
err = windows.ReadFile(port.handle, p, &readed, ev)
76-
if err == windows.ERROR_IO_PENDING {
77-
err = windows.GetOverlappedResult(port.handle, ev, &readed, true)
78-
}
79-
switch err {
80-
case nil:
81-
// operation completed successfully
82-
case windows.ERROR_OPERATION_ABORTED:
83-
// port may have been closed
84-
return int(readed), &PortError{code: PortClosed, causedBy: err}
85-
default:
86-
// error happened
87-
return int(readed), err
88-
}
89-
if readed > 0 {
90-
return int(readed), nil
91-
}
76+
for {
77+
err = windows.ReadFile(port.handle, p, &readed, ev)
78+
if err == windows.ERROR_IO_PENDING {
79+
err = windows.GetOverlappedResult(port.handle, ev, &readed, true)
80+
}
81+
switch err {
82+
case nil:
83+
// operation completed successfully
84+
case windows.ERROR_OPERATION_ABORTED:
85+
// port may have been closed
86+
return int(readed), &PortError{code: PortClosed, causedBy: err}
87+
default:
88+
// error happened
89+
return int(readed), err
90+
}
91+
if readed > 0 {
92+
return int(readed), nil
93+
}
9294

93-
// Timeout
94-
return 0, nil
95+
// Timeout
96+
port.mu.Lock()
97+
hasTimeout := port.hasTimeout
98+
port.mu.Unlock()
99+
if hasTimeout {
100+
return 0, nil
101+
}
102+
}
95103
}
96104

97105
func (port *windowsPort) Write(p []byte) (int, error) {
@@ -304,9 +312,12 @@ func (port *windowsPort) SetReadTimeout(timeout time.Duration) error {
304312
commTimeouts.ReadTotalTimeoutConstant = uint32(ms)
305313
}
306314

315+
port.mu.Lock()
316+
defer port.mu.Unlock()
307317
if err := windows.SetCommTimeouts(port.handle, commTimeouts); err != nil {
308318
return &PortError{code: InvalidTimeoutValue, causedBy: err}
309319
}
320+
port.hasTimeout = (timeout != NoTimeout)
310321

311322
return nil
312323
}

0 commit comments

Comments
 (0)