On Tue, 19 Oct 2021 20:21:59 GMT, Chris Plummer <cjplum...@openjdk.org> wrote:

>> Richard Reingruber has updated the pull request incrementally with one 
>> additional commit since the last revision:
>> 
>>   Call blockOnDebuggerSuspend() after setup of the resumer tracking.
>
> src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c line 772:
> 
>> 770:     debugMonitorExit(threadLock);
>> 771:     eventHandler_lock(); /* for proper lock order */
>> 772:     debugMonitorEnter(threadLock);
> 
> Somewhere we need to mention that `trackAppResume()` exits with threadLock 
> still being held, although with my recommended changes below this would no 
> longer be the case.

If we cannot release `threadLock` before calling `doPendingTasks()` then I 
would suggest to comment that the caller of `trackAppResume()` is expected to 
hold `threadLock` and that it will be temporarily released.

> src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c line 807:
> 
>> 805:     }
>> 806: 
>> 807:     eventHandler_unlock();
> 
> This is still a bit odd looking because we grabbed this lock for lock 
> ordering purposes, but are now releasing it out of order. But it's starting 
> to sink in with me that the root of our problem here is that lock order 
> dictates grabbing handlerLock first, and we need to eventually wait on 
> threadLock but with handlerLock released, which suggest the lock ordering is 
> reversed. There is probably some design bug here that results in that, but 
> I'd hate to mess with the ordering of these two locks to try to fix it. Maybe 
> a 3rd lock would help (wait on some new lock instead of threadLock). We could 
> grab that lock first in `doPendingTasks()`, and not have to exit 
> `trackAppResume()` with threadLock held, but again this might be more risk 
> than it is worth.
> 
> So it we aren't going to change the lock ordering or introduce a 3rd lock, 
> then my suggestion would be (after making the above suggested change to 
> release threadLock before calling `threadControl_onEventHandlerExit()`) to 
> move the locking and unlocking into `doPendingTasks()`. At the start of the 
> `node->handlingAppResume` block, grab handlerLock and threadLock, and explain 
> that handlerLock is being grabbed because trackAppResume() will (indirectly) 
> try to grab it, and grabbing it before threadLock is necessary for lock 
> ordering. Then grab threadLock and hold onto it until the end of the block. 
> Between the `trackAppResume()` and `blockOnDebuggerSuspend()` calls, release 
> handlerLock and explain that it will not be needed anymore, and has to be 
> released before calling `blockOnDebuggerSuspend()`.

To me it does not look odd. I'd think it is ok to release locks out of order.

IMHO adding a new third lock to be waited on in `doPendingTasks()` would make 
things even more complicated. Accesses to `suspendCount` are synchronized 
through `threadLock`. Waiting on that lock for change of `suspendCount` is 
straightforward really.

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

PR: https://git.openjdk.java.net/jdk/pull/5849

Reply via email to