Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite-loop in readBytes when pulling plug #94

Closed
hiddenalpha opened this issue Jul 29, 2021 · 1 comment
Closed

Infinite-loop in readBytes when pulling plug #94

hiddenalpha opened this issue Jul 29, 2021 · 1 comment

Comments

@hiddenalpha
Copy link

hiddenalpha commented Jul 29, 2021

Actual Behavior

Jssc ends up in an infinite-loop when device plug gets pulled.

Affected method (source):

Java_jssc_SerialNativeInterface_readBytes(JNIEnv*, jobject, jlong, jint);

Tested with v2.9.2.

(See also discussion in #90)
(Is similar to #95)
(Maybe relates to #89)

Expected behavior

To be discussed what the correct behavior is in this scenario. We should
somehow communicate that we reached EOF or somehow communicate the actual error
which happened.

Maybe return some (eg negative) error codes which then gets translated to an
exception in SerialPort wrapper or similar?

How to reproduce

(HINT: In this example I interact with SerialNativeInterface class directly.
But the behavior IMHO should be the same when used via SerialPort wrapper)

  • Setup a java class as shown in example below
  • Plug in our device. (I used an arduino via USB)
  • Launch reproducer
  • Send some example data from device to make sure everything works
    (I wrote a primitive program on arduino so I can send a few bytes by pushing a button)
    (HINT: This step is optional. It's just to verify that we connected successfully)
  • Take a look at CPU usage by java process. Up to now everything should be fine.
  • Pull plug of the device (in my case the USB cable of arduino)
  • Now look again at the CPU usage of our process. In my case its near 100% infinitely looping in native _readBytes() as we ignore everyting which is not the regular case from 'select', 'poll' and 'read' (Eg EOF or any other errors). See return of select ignored and error and EOF of read ignored.

Reproducer:

import jssc.SerialNativeInterface;

class InfiniteLoopOnEofInReadBytes
{

    private static final String portName = "/dev/ttyACM0";
    private static final int baudr = 9600;
    private static final boolean doExclusiveLock = false;
    private long fd;

    public static void main( String[] args ) {
        new InfiniteLoopOnEofInReadBytes().reproduce();
    }

    private void reproduce()
    {
        // Setup
        SerialNativeInterface serialNativeInterface = new SerialNativeInterface();
        fd = serialNativeInterface.openPort( portName, doExclusiveLock );
        if( fd<0 ) throw new IllegalStateException( "openPort( "+ portName +" ) failed with code "+ fd +". Is the device plugged in?");
        serialNativeInterface.setParams( fd, baudr, 8, 1, 0, true, true, 0 );

        while(true){
            // Read a few bytes.
            // As soon we pull the plug, this method never returns and hangs in an
            // infinite-loop internally (HINT: Don't confuse this with our outer loop here).
            System.out.println( "readBytes( fd, 4 )" );
            byte[] bytes = serialNativeInterface.readBytes( fd, 4 );

            // Log them.
            System.out.print( "Got "+ bytes.length +" bytes:" );
            for( byte b : bytes ){
                System.out.print( String.format(" 0x%02X", b) );
            }
            System.out.print("\n");
        }
    }
}
@hiddenalpha
Copy link
Author

I assume this is fixed through #155 as read now should throw an IOException in place of infinite looping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant