Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is constant polling in RXTX necessary?

While trying to figure out this problem (any help there is appreciated), I ran RXTX while monitoring its activity using PortMon and noticed that RXTX constantly checks if data is available, even when the Java client reads from the gnu.io.SerialPort object only through a SerialPortEventListener.

Why is this? Is it a poor implementation choice by the RXTX folks, a poor API choice by Sun (since RXTX follows the javax.comm API), or a limitation of running Java supported by native code?

Hyperterminal, on the other hand, does no polling (and works without a problem). Does it have access to some hidden Windows system calls that let it do this?

like image 238
Nate Parsons Avatar asked Sep 08 '09 04:09

Nate Parsons


1 Answers

No it's not due to the javax.xomm API. Rxtx can be used through that API or not by the way.

Rxtx internals are a bit different/weird though and has some bugs. Short version, this is how it is supposed to work: You have two parameters to play with: timeout and threshold. According to the source code setting the timeout to 0 (none) and threshold to 1 (requiring at least 1 byte before returning) should give us normal, by InputStream defined, blocking reads.

The problem is that even when setting it up like this there is a bug in the current stable release (2.1.7r2). The threshold parameter is always set to 0! From the source code:

/* TESTING ttyset.c_cc[ VMIN ] = threshold; */ ttyset.c_cc[ VMIN ] = 0;

The confusing part is that this was also the case in 2004 and reported on the mailing list and fixed, but it was either not really fixed or has come back again (a regression). There is actually a new bug report that for some reason I couldn’t find at first. I eventually found it going throw the pre-release package source code and found an otherwise not published change log (the web page doesn’t show change logs after the last stable version, its available in CVS though).

Solution

  1. It is fixed on HEAD, so you can use the latest pre-release version (2.2-series) or compile it from CVS.
  2. Make an ugly workaround along the lines of:

    int read(InputStream in) throws IOException {
      int b; 
      while ((b=in.read()) == -1) { 
        try { Thread.sleep(10); } catch (InterruptedException e) { }
      }
      return b;
    }
    

Then you do: read(in) instead of in.read().

I actually wrote a blog entry about this 2 years ago so I wouldn't forget.

like image 174
Mattias Isegran Bergander Avatar answered Oct 15 '22 12:10

Mattias Isegran Bergander