stephane / libmodbus

A Modbus library for Linux, Mac OS, FreeBSD and Windows
http://libmodbus.org
GNU Lesser General Public License v2.1
3.42k stars 1.74k forks source link

Timeout struct should be re-written after select #388

Closed stevemk14ebr closed 7 years ago

stevemk14ebr commented 7 years ago

Timeout should be reset after select

http://man7.org/linux/man-pages/man2/select.2.html

On Linux, select() modifies timeout to reflect the amount of time not slept; most other implementations do not do this. (POSIX.1 permits either behavior.) This causes problems both when Linux code which reads timeout is ported to other operating systems, and when code is ported to Linux that reuses a struct timeval for multiple select()s in a loop without reinitializing it. Consider timeout to be undefined after select() returns.

In _modbus_receive_msg

 while (length_to_read != 0) {
        rc = ctx->backend->select(ctx, &rset, p_tv, length_to_read);
        if (rc == -1) {

This loops without ever reseting p_tv, which will decrease to a smaller and smaller number the more iterations it takes, causing unexpected timeouts. To fix simply reset p_tv to its initial value after select. I am not sure if this was desired behavior, since its possible you wanted the entire function to timeout after some time, which this would do (i think), or if you wanted select to timeout after some time (which this fails in that case)

stephane commented 7 years ago

A link to concerned function would be easier to follow (and provides version and file). The while contains the code to handle the timeout values: https://github.com/stephane/libmodbus/blob/master/src/modbus.c#L463