Closed bernardnormier closed 2 days ago
The assert is we setState(StateFinished) when the current state is not StateClosed.
It's not clear why we only get this now!
I think the problem is that finished
might be called before setState
releases the connection's mutex.
It might be ran as soon as _threadPool.finish()
is called here: https://github.com/zeroc-ice/ice/blob/355bea22355a8791daa72ef24f5b47be2b20c301/java/src/Ice/src/main/java/com/zeroc/Ice/ConnectionI.java#L1505
At this point _state
is not set yet to StateClosed
.
We can add locking in ConnectionI.finished
and an assert(_state == StateClosed)
.
Adding locking in finish
is not strictly necessary because it's only ran in the StateClosed
state and all the data members it accesses are immutable at this point. We can locking however and some assert to ensure the state is still StateClosed
.
I was able to reproduce on macOS after 57 iterations, same configuration (on main).
In 3.7, ConnectionI.finished
locks the connection to unschedule the timeout so ConnectionI.finished
can't execute until the lock held while setState
is executed is released.
And once the state is set to StateClosed
, the data members used by finish
are guaranteed to be immutable.
Indeed, it could be because in 3.7 we had: https://github.com/zeroc-ice/ice/blob/b08306ef3bf16a7ecadf558375b2eb4f14336047/java/src/Ice/src/main/java/com/zeroc/Ice/ConnectionI.java#L1373
whereas on main I removed the synchronized(this)
alongside the connection timeouts:
Seems to happen from time to time:
https://github.com/zeroc-ice/ice/actions/runs/9614875377/job/26520770057