RFR: 8366659: ObjectMonitor::wait() can deadlock with a suspension request [v13]

Serguei Spitsyn sspitsyn at openjdk.org
Thu Nov 20 23:58:41 UTC 2025


On Thu, 20 Nov 2025 05:38:21 GMT, David Holmes <dholmes at openjdk.org> wrote:

>> Changes requested by lmesnik (Reviewer).
>
> @lmesnik are the JVMTI thread state transitions performed in the event posting code? If so the different order, and thus different states, would be a concern. That said we have noticed that only the timeout case seems to operate in a way that the monitor reentry can post contended_enter and contended_entered events, which seems very odd in itself. Though I will also note that the way the suspension code drops and then re-acquires the monitor, any contended_enter* events could get posted multiple times which would also be surprising.
> 
> Maintaining the event order is problematic as, with the fix to the deadlock issue, we only allow suspension during reentry, and that would mean the `monitor_waited` event would be posted whilst the thread is still suspended. To be clear(er) in the old code we would do:
> 
> wait -> suspend if needed -> resumed -> post monitor_waited -> renter monitor
> 
> whereas the new code, if we kept the placement of the event,  would do
> 
> wait -> post monitor_waited -> reenter monitor -> suspend if needed and drop monitor -> resumed -> reenter monitor
> 
> and what the proposed code actually does is
> 
> wait -> reenter monitor -> suspend if needed and drop monitor -> resumed -> reenter monitor -> post monitor_waited 
> 
> 
> Given the lack of specificity in the JVM TI spec around these different events I think any assumptions in a TCK test could be challenged, but it would still be a change in behaviour.

@dholmes-ora David, thank you for your input!

> @dholmes-ora I have done a bit of refactoring and introduced a private method post_waited_event(), which we can call in different places depending on the scenario.

I like the refactoring.

> For instance, for the timed-out case, the sequence of events is now unchanged, i.e.:
> `wait -> waited -> contended enter -> contended entered`
> 
> For the notified case, using your extended notation, it is now behaving like this:
> `wait  -> reenter monitor -> suspend if needed and drop monitor -> resumed -> post monitor_waited -> reenter monitor`

My understanding is that we need both timed-out and notified cases to do the same as David suggested above:
  `wait -> post monitor_waited -> reenter monitor -> suspend if needed and drop monitor -> resumed -> reenter monitor`
It would give us two advantages:
 - timed-out and notified cases are unified
 - avoid incompatibility risk, e.g.:
   - no new combinations of JVMTI thread state bits are introduced
   - the object monitor events order is kept same as was before (is it true?)

Is there a problem to make it unified?

> I think this is what we eventually want. @sspitsyn could you confirm/refute that it does not change thread state bits?

As I see, this still introduces new combinations of thread state bits for the notified case.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/27040#issuecomment-3560695036


More information about the serviceability-dev mailing list