-
Hello, I wonder if current pi4j v2 providers implementations are thread-safe. I'm working on a GPIO provider based on MCP23017 (please see: #138) and because I'd like to use it in a multi-threading application I searched for an example of how currently available providers are synchronized. Unfortunately, I could not find any synchronized method. Does this mean that it is not recommended to use the new pi4j in multi-threading applications? In case of using MCP23017 to build GPIO provider, accessing the same |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 3 replies
-
Executing the MCP23017 example, there is a lock synchronization for the i2c path in the LinuxFSI2CBus, so I believe this multiThread concern is addressed at present. public R execute(I2C i2c, CheckedFunction<LinuxFile, R> action) { |
Beta Was this translation helpful? Give feedback.
-
@taartspi thanks a lot. I have not noticed that. |
Beta Was this translation helpful? Give feedback.
-
Hi @tatery, @taartspi is correct, I2C is synchronized. But beware that each call is synchronized, so if you need to do multiple calls, then be sure to use the execute method for your entire synchronized block. So if you look at the example on https://pi4j.com/documentation/io-examples/i2c/ you will see that there are multiple calls on the |
Beta Was this translation helpful? Give feedback.
-
This impl file would probably benefit from some The actual risk is probably low assuming consumer code does not attempt to reconfigure the same I/O pin on the same chip in different threads. Not sure that is even possible with the current Pi4J APIs. |
Beta Was this translation helpful? Give feedback.
-
I have added a few public MCP23017Device(I2C i2c){
// set local reference to I2C instance
this.i2c = i2c;
// atomic operation to configure chip registers
synchronized (this.i2c) { <<--------- LOCKING ON I2C INSTANCE
// set all default pin interrupt default values
this.i2c.writeRegister(REGISTER_DEFVAL_A, (byte) 0x00);
this.i2c.writeRegister(REGISTER_DEFVAL_B, (byte) 0x00);
// set all default pin interrupt comparison behaviors
this.i2c.writeRegister(REGISTER_INTCON_A, (byte) 0x00);
this.i2c.writeRegister(REGISTER_INTCON_B, (byte) 0x00);
}
} Do you think using the I2C instance is the appropriate object to sync lock on? Thanks, Robert |
Beta Was this translation helpful? Give feedback.
-
Not sure I follow .... Anytime Pi4J creates the Digital input/output IO object (on the MCPxxxx pin) it should be properly configuring the pin direction and interrupt config. (If it's not properly configuring the pin each time, then that is a bug.) SEE: Thanks, Robert |
Beta Was this translation helpful? Give feedback.
-
@savageautomate @eitch @taartspi many thanks for great inputs. |
Beta Was this translation helpful? Give feedback.
Executing the MCP23017 example, there is a lock synchronization for the i2c path in the LinuxFSI2CBus, so I believe this multiThread concern is addressed at present. public R execute(I2C i2c, CheckedFunction<LinuxFile, R> action) {
if (i2c == null) {
throw new NullPointerException("Parameter 'i2c' is mandatory!");
} else if (action == null) {
throw new NullPointerException("Parameter 'action' is mandatory!");
} else {
try {
if (!this.lock.tryLock() && !this.lock.tryLock(this.lockAquireTimeout, this.lockAquireTimeoutUnit)) {