ExecutorService executorService = Executors.newCachedThreadPool();
try {
int rc;
pollfd[] pollfdset = { new pollfd() };
ByteByReference value = new ByteByReference();
NativeLong zero = new NativeLong(0);
/* Last time (in milliseconds) when the interrupt was generated */
long lastInterruptTime = 0;
fd = LibC.INSTANCE.open(pin.valuePath.toString(), LibC.O_RDONLY | LibC.O_NONBLOCK);
pollfdset[0].fd = fd;
pollfdset[0].events = LibC.POLLPRI;
/* Prior calling poll() the file needs to be read or poll() will return immediately without real interrupt received */
try {
LibC.INSTANCE.read(pollfdset[0].fd, value.getPointer(), 1);
} catch (LastErrorException e) {}
while(!interrupted()) {
/* Wait for GPIO interrupt or timeout to occur. Timeouts provides possibility to check thread interrupt status */
rc = LibC.INSTANCE.poll(pollfdset, 1, POLL_TIMEOUT);
switch(rc) {
/* Timeout, poll() again */
case 0:
continue;
/* There is one file descriptor ready */
case 1:
/* Is interrupt received? */
if ((pollfdset[0].revents & LibC.POLLPRI) > 0) {
/* Calculate times for software debounce */
long interruptTime = System.currentTimeMillis();
long timeDifference = interruptTime - lastInterruptTime;
/* Go to file start and read first byte */
LibC.INSTANCE.lseek(fd, zero, LibC.SEEK_SET);
rc = LibC.INSTANCE.read(pollfdset[0].fd, value.getPointer(), 1);
/* There is exactly one byte read */
if (rc == 1) {
/* Execute event handlers each in its own thread */
try {
if (pinLock.readLock().tryLock(PINLOCK_TIMEOUT, PINLOCK_TIMEOUT_UNITS)) {
try {
/* Software debounce */
if ((timeDifference > pin.debounceInterval) || (timeDifference < 0)) {
for (GPIOPinEventHandler eventHandler : pin.eventHandlers) {
EventHandlerExecutor eventHandlerExecutor = new EventHandlerExecutor(pin, eventHandler,
Character.getNumericValue(value.getValue()));
executorService.execute(eventHandlerExecutor);
}
lastInterruptTime = interruptTime;
}