Pi4J / pi4j-v1

DEPRECATED Java I/O library for Raspberry Pi (GPIO, I2C, SPI, UART)
http://www.pi4j.com
Apache License 2.0
1.31k stars 447 forks source link

ConcurrentModificationException when provisionPwmOutputPin #481

Closed ironman00023 closed 3 years ago

ironman00023 commented 4 years ago

Sometime i get ConcurrentModificationException when provisioning a pwm output pin. java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList$Itr.next(ArrayList.java:851) at com.pi4j.io.gpio.impl.GpioControllerImpl.provisionPin(GpioControllerImpl.java:551) at com.pi4j.io.gpio.impl.GpioControllerImpl.provisionPin(GpioControllerImpl.java:539) at com.pi4j.io.gpio.impl.GpioControllerImpl.provisionPwmOutputPin(GpioControllerImpl.java:812)

eitch commented 4 years ago

Looking at this code, we have a clear race condition.

com.pi4j.io.gpio.impl.GpioControllerImpl#provisionPin(com.pi4j.io.gpio.GpioProvider, com.pi4j.io.gpio.Pin, java.lang.String, com.pi4j.io.gpio.PinMode, com.pi4j.io.gpio.PinState)

There the list of pins is checked if it has the pin already, and then a few statements later the pin is added to the list. So one thread can be stopped after checking if it is added, and thus the pin can be added twice.

The ConcurrentModificationException is probably from a time when the check was done without the synchronization.

I think this method should be synchronized, either the entire method, or the relevant scope. But of course all other iterations in the class must be synchronized as well removeAllTriggers(), removeAllListeners(), etc.