10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 8330748
27 * @summary Test ByteArrayOutputStream.writeTo releases carrier thread
28 * @requires vm.continuations
29 * @modules java.base/java.lang:+open
30 * @run main WriteToReleasesCarrier
31 */
32
33 import java.io.ByteArrayOutputStream;
34 import java.io.IOException;
35 import java.io.OutputStream;
36 import java.nio.charset.StandardCharsets;
37 import java.lang.reflect.Constructor;
38 import java.util.Arrays;
39 import java.util.concurrent.CountDownLatch;
40 import java.util.concurrent.ExecutorService;
41 import java.util.concurrent.Executor;
42 import java.util.concurrent.Executors;
43 import java.util.concurrent.atomic.AtomicBoolean;
44 import java.util.concurrent.locks.LockSupport;
45
46 public class WriteToReleasesCarrier {
47 public static void main(String[] args) throws Exception {
48 byte[] bytes = "Hello".getBytes(StandardCharsets.UTF_8);
49
50 var baos = new ByteArrayOutputStream();
51 baos.write(bytes);
52
53 var target = new ParkingOutputStream();
54
55 try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
56 Thread.Builder builder = virtualThreadBuilder(scheduler);
57 var started = new CountDownLatch(1);
58 var vthread1 = builder.start(() -> {
59 started.countDown();
60 try {
61 baos.writeTo(target);
62 } catch (IOException ioe) { }
63 });
64 try {
65 started.await();
66 await(vthread1, Thread.State.WAITING);
67
68 // carrier should be released, use it for another thread
69 var executed = new AtomicBoolean();
70 var vthread2 = builder.start(() -> {
71 executed.set(true);
72 });
73 vthread2.join();
74 if (!executed.get()) {
75 throw new RuntimeException("Second virtual thread did not run");
76 }
101 */
102 static class ParkingOutputStream extends OutputStream {
103 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
104
105 @Override
106 public void write(int i) {
107 LockSupport.park();
108 baos.write(i);
109 }
110
111 @Override
112 public void write(byte[] b, int off, int len) {
113 LockSupport.park();
114 baos.write(b, off, len);
115 }
116
117 byte[] toByteArray() {
118 return baos.toByteArray();
119 }
120 }
121
122 /**
123 * Returns a builder to create virtual threads that use the given scheduler.
124 */
125 static Thread.Builder.OfVirtual virtualThreadBuilder(Executor scheduler) throws Exception {
126 Class<?> clazz = Class.forName("java.lang.ThreadBuilders$VirtualThreadBuilder");
127 Constructor<?> ctor = clazz.getDeclaredConstructor(Executor.class);
128 ctor.setAccessible(true);
129 return (Thread.Builder.OfVirtual) ctor.newInstance(scheduler);
130 }
131 }
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 8330748
27 * @summary Test ByteArrayOutputStream.writeTo releases carrier thread
28 * @requires vm.continuations
29 * @modules java.base/java.lang:+open
30 * @library /test/lib
31 * @run main WriteToReleasesCarrier
32 */
33
34 import java.io.ByteArrayOutputStream;
35 import java.io.IOException;
36 import java.io.OutputStream;
37 import java.nio.charset.StandardCharsets;
38 import java.util.Arrays;
39 import java.util.concurrent.CountDownLatch;
40 import java.util.concurrent.ExecutorService;
41 import java.util.concurrent.Executor;
42 import java.util.concurrent.Executors;
43 import java.util.concurrent.atomic.AtomicBoolean;
44 import java.util.concurrent.locks.LockSupport;
45 import jdk.test.lib.thread.VThreadScheduler;
46
47 public class WriteToReleasesCarrier {
48 public static void main(String[] args) throws Exception {
49 byte[] bytes = "Hello".getBytes(StandardCharsets.UTF_8);
50
51 var baos = new ByteArrayOutputStream();
52 baos.write(bytes);
53
54 var target = new ParkingOutputStream();
55
56 try (ExecutorService scheduler = Executors.newFixedThreadPool(1)) {
57 Thread.Builder builder = VThreadScheduler.virtualThreadBuilder(scheduler);
58 var started = new CountDownLatch(1);
59 var vthread1 = builder.start(() -> {
60 started.countDown();
61 try {
62 baos.writeTo(target);
63 } catch (IOException ioe) { }
64 });
65 try {
66 started.await();
67 await(vthread1, Thread.State.WAITING);
68
69 // carrier should be released, use it for another thread
70 var executed = new AtomicBoolean();
71 var vthread2 = builder.start(() -> {
72 executed.set(true);
73 });
74 vthread2.join();
75 if (!executed.get()) {
76 throw new RuntimeException("Second virtual thread did not run");
77 }
102 */
103 static class ParkingOutputStream extends OutputStream {
104 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
105
106 @Override
107 public void write(int i) {
108 LockSupport.park();
109 baos.write(i);
110 }
111
112 @Override
113 public void write(byte[] b, int off, int len) {
114 LockSupport.park();
115 baos.write(b, off, len);
116 }
117
118 byte[] toByteArray() {
119 return baos.toByteArray();
120 }
121 }
122 }
|