On Wed, 28 Feb 2024 07:11:52 GMT, Serguei Spitsyn <[email protected]> wrote:
>> Using the interrupt is carried over from the original version of the test. I
>> did consider replacing it, but opted to keep it in so there was one less
>> change in the test to review. I can do as you suggested if you wish.
>>
>> I did have them sharing a common superclass at one point, but the only thing
>> they ended up having in common is the `interruptee` field. They still each
>> needed their own constructor and the `run()` methods. Although the `run()`
>> methods are very similar looking, it is hard to factor them into common code
>> due to the placement of the `synchronize` and the `wait()` call.
>>
>> I don't like the idea of a wait(5) that will always end out timing out. It's
>> misleading. We aren't really waiting, we are sleeping, and would only have
>> chosen wait() instead of sleep() to accommodate code sharing. It also would
>> make the PreciseInterruptor have a wait() time of 5ms, which we don't want.
>> In fact it can often take more than 5ms due to the single stepping that is
>> going on at the same time. Keeping the code for each interruptor separate
>> makes it clearer what each is attempting to do.
>
> I'm okay to keep it as is, especially as the `interrupt()` was used before
> your fixes.
>
> I was thinking about something like below:
>
> abstract static class Interruptor implements Runnable {
> Thread interruptee;
> boolean doStop = false;
> abstract void action();
>
> void doStop() { doStop = true; }
>
> public void run() {
> synchronized (InterruptHangTarg.sync) {
> while (!doStop) {
> InterruptHangTarg.interruptsSent++;
> interruptee.interrupt();
> try {
> action();
> } catch (InterruptedException ee) {
> throw RuntimeException("Failed: InterruptedThread
> should not be interrupted!" + ee);
> }
> }
> }
> }
> }
> static class AggressiveInterruptor extends Interruptor {
> AggressiveInterruptor(Thread interruptee) {
> this.interruptee = interruptee;
> }
> protected action() {
> InterruptHangTarg.sync.wait(5);
> }
> }
> static class PreciseInterruptor extends Interruptor {
> AggressiveInterruptor(Thread interruptee) {
> this.interruptee = interruptee;
> }
> protected action() {
> InterruptHangTarg.sync.wait();
> }
> }
The first version I did was just a single class that handled both interruptors,
and looked similar to what you have above, except instead of a call to action()
it instead had a conditional to decide what action to take based on the mode
(precise or aggressvie).
The problem with this is the `sychronized` statement. Initially I thought it
was benign for the aggressive case, and even had a comment saying it was
unnecessary for the aggressive case, but doing so unconditionally made it
easier to share code. However, I ran into some problem with it. I'm not exactly
sure now what it was. I can see that the `synchronized` for
interruptorThread.interrupt() call will end up deadlocking, although I don't
recall that being the issue I had. For some reason I thought it was a problem
at the start of the test, but I can't see what it might have been. Possibly due
to other restructuring it no longer exists.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/17989#discussion_r1506720062