scream3r/java-simple-serial-connector — pull request #36 by cmaglie (2014-01-18 12:40:43+00:00)
Title: Fix for a "file handler" leak in native openPort method.

First of all, thanks for the great library!

During my tests on the Arduino IDE I've found some sporadic crashes of the JVM.

Looking at the JVM crash logs, the crash happens while JSSC is reading from the serial port with readBytes method.

```
--------------- T H R E A D ---------------

Current thread (0x0909f800): JavaThread "EventThread /dev/ttyACM0" [_thread_in_native, id=27325, stack(0x74b78000,0x74bc9000)]

siginfo:si_signo=SIGSEGV: si_errno=0, si_code=1 (SEGV_MAPERR), si_addr=0x0000000c

Registers:
EAX=0x092d3fb8, EBX=0x00400000, ECX=0xb76ce3c0, EDX=0xffffffe0
ESP=0x74bc7cc0, EBP=0x00000000, ESI=0x00400000, EDI=0x00000000
EIP=0xb385e64a, EFLAGS=0x00210206, CR2=0x0000000c

Top of Stack: (sp=0x74bc7cc0)
0x74bc7cc0: 0909f920 74bc7d1c 000004d8 00000000
0x74bc7cd0: 00000018 74bc7d20 000004d8 00000000
0x74bc7ce0: 74bc7ce0 00000000 74bc7d1c 78e40148
0x74bc7cf0: 00000000 78e3f5d0 00000000 74bc7d10
0x74bc7d00: 74bc7d40 b3856fa7 00000000 b385c4d6
0x74bc7d10: 00000018 000004d8 00000000 a1bd9080
0x74bc7d20: 74bc7d20 792b9c3f 74bc7d4c 792be0a8
0x74bc7d30: 00000000 792b9c68 74bc7d10 74bc7d48

Instructions: (pc=0xb385e64a)
0xb385e62a: 18 01 00 00 c7 87 14 01 00 00 28 e6 85 b3 89 a7
0xb385e63a: 10 01 00 00 c7 87 5c 01 00 00 04 00 00 00 ff d0
0xb385e64a: 81 7d 0c ba c4 85 b3 0f 84 0d 00 00 00 81 7d 0c
0xb385e65a: cb c4 85 b3 0f 85 06 00 00 00 83 ec 08 dd 1c 24

Register to memory mapping:

EAX=0x092d3fb8 is an unknown value
EBX=0x00400000 is an unknown value
ECX=0xb76ce3c0: in /lib/i386-linux-gnu/libc.so.6 at 0xb7569000
EDX=0xffffffe0 is an unknown value
ESP=0x74bc7cc0 is pointing into the stack for thread: 0x0909f800
EBP=0x00000000 is an unknown value
ESI=0x00400000 is an unknown value
EDI=0x00000000 is an unknown value

Stack: [0x74b78000,0x74bc9000], sp=0x74bc7cc0, free space=319k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)

[error occurred during error reporting (printing native stack), id 0xb]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j jssc.SerialNativeInterface.readBytes(JI)[B+0
j jssc.SerialPort.readBytes(I)[B+15
j jssc.SerialPort.readBytes()[B+19
j processing.app.Serial.serialEvent(Ljssc/SerialPortEvent;)V+11
J jssc.SerialPort$LinuxEventThread.run()V
v ~StubRoutines::call_stub
```

After some debugging I've discovered that the issue was caused by a resource leak in native openPorts method.

Test case:

```java
public class JSSCTest {

public static void main(String[] args) throws InterruptedException {
SerialPortList.getPortNames();
SerialPortList.getPortNames();
SerialPortList.getPortNames();
SerialPortList.getPortNames();
SerialPortList.getPortNames();
SerialPortList.getPortNames();
Thread.sleep(60000);
}

}
```

and the following is an extract of "lsof" of the resulting process:

```
cmaglie@squaqquerone:~/git/java-simple-serial-connector/src/cpp/_nix_based$ sudo lsof -p 11216
[...cut...]
java 5482 cmaglie 97r CHR 4,67 0t0 1863 /dev/ttyS3
java 5482 cmaglie 98u CHR 4,66 0t0 5714 /dev/ttyS2
java 5482 cmaglie 99r CHR 4,65 0t0 5713 /dev/ttyS1
java 5482 cmaglie 100r CHR 4,64 0t0 5493 /dev/ttyS0
java 5482 cmaglie 101r CHR 4,94 0t0 1890 /dev/ttyS30
java 5482 cmaglie 102r CHR 4,93 0t0 1889 /dev/ttyS29
java 5482 cmaglie 103r CHR 4,92 0t0 1888 /dev/ttyS28
java 5482 cmaglie 104r CHR 4,91 0t0 1887 /dev/ttyS27
java 5482 cmaglie 105w CHR 4,90 0t0 1886 /dev/ttyS26
java 5482 cmaglie 106r CHR 4,89 0t0 1885 /dev/ttyS25
java 5482 cmaglie 107r CHR 4,88 0t0 1884 /dev/ttyS24
java 5482 cmaglie 108r CHR 4,87 0t0 1883 /dev/ttyS23
java 5482 cmaglie 109r CHR 4,86 0t0 1882 /dev/ttyS22
java 5482 cmaglie 110r CHR 4,85 0t0 1881 /dev/ttyS21
java 5482 cmaglie 111r CHR 4,84 0t0 1880 /dev/ttyS20
java 5482 cmaglie 112r CHR 4,83 0t0 1879 /dev/ttyS19
java 5482 cmaglie 113r CHR 4,82 0t0 1878 /dev/ttyS18
java 5482 cmaglie 114r CHR 4,81 0t0 1877 /dev/ttyS17
java 5482 cmaglie 115r CHR 4,80 0t0 1876 /dev/ttyS16
java 5482 cmaglie 116r CHR 4,79 0t0 1875 /dev/ttyS15
java 5482 cmaglie 117u CHR 4,78 0t0 1874 /dev/ttyS14
java 5482 cmaglie 118r CHR 4,77 0t0 1873 /dev/ttyS13
java 5482 cmaglie 119r CHR 4,76 0t0 1872 /dev/ttyS12
java 5482 cmaglie 120r CHR 4,75 0t0 1871 /dev/ttyS11
java 5482 cmaglie 121r CHR 4,74 0t0 1870 /dev/ttyS10
java 5482 cmaglie 122r CHR 4,73 0t0 1869 /dev/ttyS9
java 5482 cmaglie 123r CHR 4,72 0t0 1868 /dev/ttyS8
java 5482 cmaglie 124r CHR 4,71 0t0 1867 /dev/ttyS7
cmaglie@squaqquerone:~/git/java-simple-serial-connector/src/cpp/_nix_based$
```

As you can see the file handlers are allocated and never released.
This bug leads to VM crashes, at least on Linux, when the number of "leaked" file handlers goes over 1024 and a select is made on one of them (in our case during readBytes).

This pull request fix the problem.

I've successfully compiled and tested on Linux.
Not compiled nor tested on Windows and Mac.