Skip to content

Writing on Win10 occasionally fails (and loses data) #781

@giseburt

Description

@giseburt

Operating System and Hardware: Windows 10
NodeJS Version: electron 0.37.2
Serialport version: 2.1.2
Python Version: (unknown)

Expected behavior

Writing to the serialport would occasionally block in a thread, as it does on Linux and OS X. The WriteQueue for that fd will continue to be added to for further writes. (See https://github.com/voodootikigod/node-serialport/blame/master/src/serialport.cpp#L298 , which is code I helped add. 😄 ).

Alternatively, if blocking in a thread isn't acceptable for Windows, the timeout should NOT pop that write from the queue but instead modify it to prevent double-sending of sent portion of the data, and ensure that the send will be attempted again very shortly. (We don't want to cause a performance issue here.)

It's vital that we don't add semantics that pay attention to the flow control of the device. This is regularly abused and causes all sorts of troubles. (Flow control is currently broken in Python for us for this very reason.)

Actual behavior

An error (generated from https://github.com/voodootikigod/node-serialport/blob/master/src/serialport_win.cpp#L374 ) with error code 121 ("Semphore Timout": https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx#ERROR_SEM_TIMEOUT ).

Steps and/or code to reproduce the issue

Basically, you want to coerce the device to not read what we write, forcing Windows to block while writing and eventually timing out, losing data in the process.

Option 1 (explicit flow control):

  1. Open connection to a device with flow control enabled (hardware is what we are using)
  2. write() data to the device until the device's buffer fills and it signals that flow control should stop. NOTE: This should NOT be explicitly handled by serialport. The OS handles this properly and that should be left as-is.
  3. write() more data to the serialport. The error will happen and the data written will be lost instead of queued.

Option 2 (USB-based flow control):

  1. Open a connection to a device such as an Arduino Due (native port) that has a USB virtual-serial port sketch running.
  2. Instruct the Due to not read from that serialport, allowing it's buffer to full and it will then stop accepting packets from the USB host.
    3.write() data to device until you see the error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions