Currently on Linux 2.6.39 and Python 2.6.6 (and likely others), operations that call _reconfigurePort() result in a flurry of 5 ioctl() system calls consisting of 4 TCGETS and 1 TCSETS as seen by strace. In the case of a timeout property change on the POSIX backend, all of these are superfluous, because as noted in PosixSerial._reconfigurePort(), "timeout is done via select". Avoiding the _reconfigurePort() call in SerialBase.setTimeout() would break cross-platform abstraction, so a lower impact and more broadly beneficial choice is to insert a check in PosixSerial._reconfigurePort to avoid making the higher-overhead termios.tcsetattr() call if nothing changed.The attached 6 line patch does so, and among others, reduces a timeout property change in PosixSerial from 5 system calls to 1 low-overhead tcgetattr() call.
Background: This issue was discovered as a side effect of a side investigation into an intermittent data corruption problem. On USB->Serial dongles, calling tcsetattr even with unchanged parameters can cause an even larger flurry of USB control messages to the dongle. On one popular USB->Serial vendor's chips, these control messages when sent with data in the hardware FIFOs can cause a half bit-period slip in the middle of a UART byte transmit waveform. This results in intermittent, and hard to diagnose data corruption issue. It was triggered by Python code that adjusted timeouts appropriately before each command/response cycle over the serial port. A workaround for the corruption issue is being pursued in the kernel driver, but will likely involve draining the FIFO before sending these USB control commands, in which case the extra tcsetattr calls that this patch avoids will dodge a future performance/throughput issue.