Skip to content

Commit b2b12df

Browse files
committed
IOIO: fix lock dead-lock
1 parent 7708ce3 commit b2b12df

File tree

2 files changed

+23
-19
lines changed

2 files changed

+23
-19
lines changed

ioio/src/main/java/net/sourceforge/smallbasic/ioio/DigitalOutputImpl.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package net.sourceforge.smallbasic.ioio;
22

3+
import java.util.concurrent.atomic.AtomicBoolean;
4+
35
import ioio.lib.api.DigitalOutput;
46
import ioio.lib.api.IOIO;
57
import ioio.lib.api.exception.ConnectionLostException;
68
import ioio.lib.spi.Log;
79

810
public class DigitalOutputImpl extends IOTask implements DigitalOutput {
911
private static final String TAG = "DigitalOutput";
12+
private final AtomicBoolean value = new AtomicBoolean(false);
1013
private DigitalOutput output;
11-
private volatile boolean value;
1214

1315
public DigitalOutputImpl() {
1416
super();
@@ -24,7 +26,7 @@ public void close() {
2426

2527
@Override
2628
public void loop() throws InterruptedException, ConnectionLostException {
27-
output.write(value);
29+
output.write(value.get());
2830
}
2931

3032
@Override
@@ -40,6 +42,6 @@ public void setup(IOIO ioio) {
4042

4143
@Override
4244
public void write(boolean value) throws ConnectionLostException {
43-
this.value = value;
45+
this.value.set(value);
4446
}
4547
}

ioio/src/main/java/net/sourceforge/smallbasic/ioio/IOLock.java

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,60 +13,51 @@ public class IOLock<I> {
1313
private Consumer<I> consumer;
1414

1515
public float invoke(Function<Float, I> function) {
16-
CountDownLatch latch = getLatch();
16+
CountDownLatch latch = beginLatch();
1717
lock.writeLock().lock();
1818
AtomicReference<Float> result = new AtomicReference<>();
1919
try {
2020
this.consumer = (i) -> {
2121
result.set(function.apply(i));
2222
latch.countDown();
2323
};
24-
latch.await();
25-
}
26-
catch (InterruptedException e) {
27-
throw new RuntimeException(e);
2824
}
2925
finally {
3026
lock.writeLock().unlock();
3127
}
28+
endLatch(latch);
3229
return result.get();
3330
}
3431

3532
public void invoke(Consumer<I> consumer) {
36-
CountDownLatch latch = getLatch();
33+
CountDownLatch latch = beginLatch();
3734
lock.writeLock().lock();
3835
try {
3936
this.consumer = (i) -> {
4037
consumer.accept(i);
4138
latch.countDown();
4239
};
43-
latch.await();
44-
}
45-
catch (InterruptedException e) {
46-
throw new RuntimeException(e);
4740
}
4841
finally {
4942
lock.writeLock().unlock();
5043
}
44+
endLatch(latch);
5145
}
5246

5347
public int invokeInt(Function<Integer, I> function) {
54-
CountDownLatch latch = getLatch();
48+
CountDownLatch latch = beginLatch();
5549
lock.writeLock().lock();
5650
AtomicReference<Integer> result = new AtomicReference<>();
5751
try {
5852
this.consumer = (i) -> {
5953
result.set(function.apply(i));
6054
latch.countDown();
6155
};
62-
latch.await();
63-
}
64-
catch (InterruptedException e) {
65-
throw new RuntimeException(e);
6656
}
6757
finally {
6858
lock.writeLock().unlock();
6959
}
60+
endLatch(latch);
7061
return result.get();
7162
}
7263

@@ -89,7 +80,18 @@ public void process(I input) {
8980
/**
9081
* CountDownLatch ensures the calling method returns once process has completed
9182
*/
92-
private static CountDownLatch getLatch() {
83+
private CountDownLatch beginLatch() {
9384
return new CountDownLatch(1);
9485
}
86+
87+
/**
88+
* Wait for the looper to process the next consumer
89+
*/
90+
private void endLatch(CountDownLatch latch) {
91+
try {
92+
latch.await();
93+
} catch (InterruptedException e) {
94+
throw new RuntimeException(e);
95+
}
96+
}
9597
}

0 commit comments

Comments
 (0)