Menu

#164 write sometimes never returns

v2.7
open
None
5
2015-01-27
2014-05-08
No

Hi,

I think I have encountered a bug in pyserial. It's quite hard to reproduce. Sometimes write() doesn't return anything forever (I have kept it running for up to 10 minutes).
I'm running pyserial on Windows, with a virtual console port from an Opticon barcode scanner.

This is the code I use (I'm quite new to python, I keep ; because I come from PHP and this makes it easier for me to read).

When A barcode gets scanned I add 2 commands. If I don't add a sleep(0.001) in between the write somehow never returns.
When I uncomment anything within the forloop I can no longer reproduce the bug, so I suspect this is some strange timing issue.

class SerialBarcodeScanner(serial.Serial):

def _sendCommand(self):
    Logger(15, self._commandsToSend);
    if(len(self._commandsToSend) == 0): 
        Logger.serial(12, "Nothing to send, returning!");
        return;

    Logger(15, "LKooping through commands");
    for(i, command) in enumerate(self._commandsToSend):
        try:
            #Logger.serial(15, "Checking if", command, "still needs to be sent")
            if(command[1] < time.time()):
                Logger(15, "Deleting", command, ".")
                del self._commandsToSend[i];
                continue;
            #Logger.serial(15, "Writing", command)
            #time.sleep(0.001); #Otherwise write sometimes never returns.
            self.write(self._com(chr(27) + command[0] + chr(13)));
            #Logger.serial(15, "Done writing command");
        except:
            pass;
    Logger(15, "Finished looping through commands");

I worked around it by adding time.sleep(0.001). This has the downside that if you scan a lot of barcodes at the same time the sound gets stopped for a fraction of a second every once in a while. Not a showstopper but I think it could become a problem on slower or preoccupied PC's.

1 command is a command to enable the led light, 1 command is to enable the sound on the device.

Discussion

  • Michaël de Groot

    Oh by the way: It never hits the "Deleting" log line.

     
  • Chris Liechti

    Chris Liechti - 2014-08-04

    I would avoid "try: ... except: pass" as it hides possible errors, at least log the exceptions.

    How the port was opened is not shown, writes can be blocking for a longer time if flow control is enabled (software or hardware) and the other end signals to stop.

    If this is not the case and write still blocks indefinitely, it would not be the first serial port driver to have bugs... but in that case, i do not see how pySerial could solve this issue.

     
  • Chris Liechti

    Chris Liechti - 2014-08-04
    • status: open --> pending-works-for-me
     

Log in to post a comment.