Skip to content

Commit

Permalink
Merge pull request #16245 from pshipton/jdk20unsupported
Browse files Browse the repository at this point in the history
Fix use of Thread.resume(), stop(), suspend() in tests for jdk20
  • Loading branch information
keithc-ca committed Nov 2, 2022
2 parents fd7e4b9 + 564643b commit db33cb6
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
*******************************************************************************/
package org.openj9.test.java.lang;

import java.lang.ref.WeakReference;
import org.openj9.test.util.VersionCheck;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
import org.testng.Assert;
import org.testng.AssertJUnit;
import java.lang.ref.WeakReference;

@Test(groups = { "level.sanity" })
public class Test_Thread {
Expand Down Expand Up @@ -734,29 +735,38 @@ public void run() {
*/
@Test
public void test_resume() {
int orgval;
ResSupThread t;
try {
t = new ResSupThread(Thread.currentThread());
synchronized (t) {
ct = new Thread(t, "Interupt Test2");
ct.start();
t.wait();
if (VersionCheck.major() < 20) {
int orgval;
ResSupThread t;
try {
t = new ResSupThread(Thread.currentThread());
synchronized (t) {
ct = new Thread(t, "Interupt Test2");
ct.start();
t.wait();
}
ct.suspend();
// Wait to be sure the suspend has occurred
Thread.sleep(500);
orgval = t.getCheckVal();
// Wait to be sure the thread is suspended
Thread.sleep(500);
AssertJUnit.assertTrue("Failed to suspend thread", orgval == t.getCheckVal());
ct.resume();
// Wait to be sure the resume has occurred.
Thread.sleep(500);
AssertJUnit.assertTrue("Failed to resume thread", orgval != t.getCheckVal());
ct.interrupt();
} catch (InterruptedException e) {
Assert.fail("Unexpected interrupt occurred", e);
}
} else {
try {
Thread.currentThread().resume();
Assert.fail("expected UnsupportedOperationException");
} catch (UnsupportedOperationException e) {
// expected
}
ct.suspend();
// Wait to be sure the suspend has occurred
Thread.sleep(500);
orgval = t.getCheckVal();
// Wait to be sure the thread is suspended
Thread.sleep(500);
AssertJUnit.assertTrue("Failed to suspend thread", orgval == t.getCheckVal());
ct.resume();
// Wait to be sure the resume has occurred.
Thread.sleep(500);
AssertJUnit.assertTrue("Failed to resume thread", orgval != t.getCheckVal());
ct.interrupt();
} catch (InterruptedException e) {
Assert.fail("Unexpected interrupt occurred", e);
}
}

Expand Down Expand Up @@ -964,31 +974,40 @@ public void run() {
*/
@Test
public void test_stop() {
try {
Runnable r = new ResSupThread(null);
synchronized (r) {
st = new Thread(r, "Interupt Test5");
st.start();
r.wait();
if (VersionCheck.major() < 20) {
try {
Runnable r = new ResSupThread(null);
synchronized (r) {
st = new Thread(r, "Interupt Test5");
st.start();
r.wait();
}
} catch (InterruptedException e) {
Assert.fail("Unexpected interrupt received", e);
}
st.stop();

/*
* Thread.stop() implementation is changed from 1.1.7 to the 1.2
* behaviour. now stop() doesn't ensure immediate thread death, so we
* have to wait till st thread joins back to current thread, before
* making an isAlive() check.
*/
try {
st.join(10000);
} catch (InterruptedException e1) {
st.interrupt();
Assert.fail("Failed to stopThread before 10000 timeout", e1);
}
AssertJUnit.assertTrue("Failed to stopThread", !st.isAlive());
} else {
try {
Thread.currentThread().stop();
Assert.fail("expected UnsupportedOperationException");
} catch (UnsupportedOperationException e) {
// expected
}
} catch (InterruptedException e) {
Assert.fail("Unexpected interrupt received", e);
}
st.stop();

/*
* Thread.stop() implementation is changed from 1.1.7 to the 1.2
* behaviour. now stop() doesn't ensure immediate thread death, so we
* have to wait till st thread joins back to current thread, before
* making an isAlive() check.
*/
try {
st.join(10000);
} catch (InterruptedException e1) {
st.interrupt();
Assert.fail("Failed to stopThread before 10000 timeout", e1);
}
AssertJUnit.assertTrue("Failed to stopThread", !st.isAlive());
}

/**
Expand All @@ -1006,16 +1025,25 @@ public void run() {
}
}
}
try {
StopBeforeStartThread t = new StopBeforeStartThread();
t.stop();
t.start();
t.join();
synchronized (t) {
AssertJUnit.assertFalse("thread should not run if stop called before start, stop()", t.failed);
if (VersionCheck.major() < 20) {
try {
StopBeforeStartThread t = new StopBeforeStartThread();
t.stop();
t.start();
t.join();
synchronized (t) {
AssertJUnit.assertFalse("thread should not run if stop called before start, stop()", t.failed);
}
} catch (Exception e) {
Assert.fail("Unexpected exception:", e);
}
} else {
try {
Thread.currentThread().stop();
Assert.fail("expected UnsupportedOperationException");
} catch (UnsupportedOperationException e) {
// expected
}
} catch (Exception e) {
Assert.fail("Unexpected exception:", e);
}
}

Expand All @@ -1024,55 +1052,64 @@ public void run() {
*/
@Test
public void test_suspend() {
int orgval;
ResSupThread t = new ResSupThread(Thread.currentThread());
try {
synchronized (t) {
ct = new Thread(t, "Interupt Test6");
ct.start();
t.wait();
if (VersionCheck.major() < 20) {
int orgval;
ResSupThread t = new ResSupThread(Thread.currentThread());
try {
synchronized (t) {
ct = new Thread(t, "Interupt Test6");
ct.start();
t.wait();
}
ct.suspend();
// Wait to be sure the suspend has occurred
Thread.sleep(500);
orgval = t.getCheckVal();
// Wait to be sure the thread is suspended
Thread.sleep(500);
AssertJUnit.assertTrue("Failed to suspend thread", orgval == t.getCheckVal());
ct.resume();
// Wait to be sure the resume has occurred.
Thread.sleep(500);
AssertJUnit.assertTrue("Failed to resume thread", orgval != t.getCheckVal());
ct.interrupt();
} catch (InterruptedException e) {
Assert.fail("Unexpected interrupt occurred", e);
}
ct.suspend();
// Wait to be sure the suspend has occurred
Thread.sleep(500);
orgval = t.getCheckVal();
// Wait to be sure the thread is suspended
Thread.sleep(500);
AssertJUnit.assertTrue("Failed to suspend thread", orgval == t.getCheckVal());
ct.resume();
// Wait to be sure the resume has occurred.
Thread.sleep(500);
AssertJUnit.assertTrue("Failed to resume thread", orgval != t.getCheckVal());
ct.interrupt();
} catch (InterruptedException e) {
Assert.fail("Unexpected interrupt occurred", e);
}

/*
* [PR 106321] suspend() must not synchronize when a Thread is
* suspending itself
*/
final Object notify = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
/*
* [PR 106321] suspend() must not synchronize when a Thread is
* suspending itself
*/
final Object notify = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (notify) {
notify.notify();
}
Thread.currentThread().suspend();
}
});
try {
synchronized (notify) {
notify.notify();
t1.start();
notify.wait();
}
Thread.currentThread().suspend();
// wait for Thread to suspend
Thread.sleep(500);
AssertJUnit.assertTrue("Thread should be alive", t1.isAlive());
t1.resume();
t1.join();
} catch (InterruptedException e) {
}
});
try {
synchronized (notify) {
t1.start();
notify.wait();
} else {
try {
Thread.currentThread().suspend();
Assert.fail("expected UnsupportedOperationException");
} catch (UnsupportedOperationException e) {
// expected
}
// wait for Thread to suspend
Thread.sleep(500);
AssertJUnit.assertTrue("Thread should be alive", t1.isAlive());
t1.resume();
t1.join();
} catch (InterruptedException e) {
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2001, 2021 IBM Corp. and others
* Copyright (c) 2001, 2022 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -39,6 +39,8 @@ class GetStaticTestHelper {
try {
Thread.sleep(1000000);
} catch(InterruptedException e) {
GetStaticDuringClinit.interrupted = true;
break;
}
}
}
Expand All @@ -48,7 +50,8 @@ public class GetStaticDuringClinit {
public static Object lock = new Object();
public static boolean runBlocker = false;
public static boolean threadsReady = false;
public static boolean passed = true;
public static volatile boolean passed = true;
public static volatile boolean interrupted = false;

public static String jitRead() {
return GetStaticTestHelper.i;
Expand Down Expand Up @@ -87,9 +90,11 @@ public void run() {
lock.notifyAll();
}
String value = jitRead();
// <clinit> for GetStaticTestHelper never returns, so if execution reaches
// here, the VM has allowed an invalid getstatic.
passed = false;
if (!interrupted) {
// <clinit> for GetStaticTestHelper never returns, so if execution reaches
// here, the VM has allowed an invalid getstatic.
passed = false;
}
}
};
initializer.start();
Expand All @@ -109,8 +114,8 @@ public void run() {
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
initializer.stop();
blocker.stop();
initializer.interrupt();
blocker.interrupt();
try {
initializer.join();
} catch (InterruptedException e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2001, 2019 IBM Corp. and others
* Copyright (c) 2001, 2022 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -39,6 +39,8 @@ public static void staticMethod() {
try {
Thread.sleep(1000000);
} catch(InterruptedException e) {
InvokeStaticDuringClinit.interrupted = true;
break;
}
}
}
Expand All @@ -48,7 +50,8 @@ public class InvokeStaticDuringClinit {
public static Object lock = new Object();
public static boolean runBlocker = false;
public static boolean threadsReady = false;
public static boolean passed = true;
public static volatile boolean passed = true;
public static volatile boolean interrupted = false;

public static void staticMethod() {
}
Expand Down Expand Up @@ -82,9 +85,11 @@ public void run() {
lock.notifyAll();
}
jitSend();
// <clinit> for InvokeStaticTestHelper never returns, so if execution reaches
// here, the VM has allowed an invalid invokestatic.
passed = false;
if (!interrupted) {
// <clinit> for InvokeStaticTestHelper never returns, so if execution reaches
// here, the VM has allowed an invalid invokestatic.
passed = false;
}
}
};
initializer.start();
Expand All @@ -104,8 +109,8 @@ public void run() {
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
initializer.stop();
blocker.stop();
initializer.interrupt();
blocker.interrupt();
try {
initializer.join();
} catch (InterruptedException e) {
Expand Down

0 comments on commit db33cb6

Please sign in to comment.