4747import org .graalvm .polyglot .Context ;
4848import org .graalvm .polyglot .Value ;
4949import org .junit .Assume ;
50- import org .junit .Ignore ;
5150import org .junit .Test ;
5251
5352import java .io .ByteArrayOutputStream ;
@@ -75,14 +74,12 @@ public void testEmbedderVirtualThread() throws Throwable {
7574 }
7675 }
7776
78- @ Ignore ("GR-54696 too slow and can hang" )
7977 @ Test
8078 public void testManyVirtualThreads () throws Throwable {
8179 Assume .assumeTrue (canCreateVirtualThreads () && !TruffleOptions .AOT );
8280
83- // Above 65535, which is the documented limit for Phaser, which was used by
84- // ThreadLocalHandshake.Handshake
85- int n = 66000 ;
81+ // We want a big number of virtual threads but also to execute this test in reasonable time
82+ int n = 1000 ;
8683
8784 try (Context ctx = Context .create ()) {
8885 Throwable [] error = new Throwable [1 ];
@@ -91,25 +88,32 @@ public void testManyVirtualThreads() throws Throwable {
9188
9289 for (int i = 0 ; i < n ; i ++) {
9390 threads [i ] = Thread .startVirtualThread (() -> {
94- ctx .enter ();
9591 try {
96- waitStarted .countDown ();
97- while (true ) {
98- ctx .safepoint ();
99- Thread .yield ();
92+ ctx .enter ();
93+ try {
94+ // barrier for all threads being entered in the context
95+ waitStarted .countDown ();
96+ await (waitStarted );
97+ while (true ) {
98+ ctx .safepoint ();
99+ Thread .yield ();
100+ }
101+ } catch (Throwable t ) {
102+ if (!"Execution got interrupted." .equals (t .getMessage ())) {
103+ t .printStackTrace ();
104+ error [0 ] = t ;
105+ }
106+ } finally {
107+ ctx .leave ();
100108 }
101109 } catch (Throwable t ) {
102- if (!t .getMessage ().equals ("Execution got interrupted." )) {
103- t .printStackTrace ();
104- error [0 ] = t ;
105- }
106- } finally {
107- ctx .leave ();
110+ t .printStackTrace ();
111+ throw t ;
108112 }
109113 });
110114 }
111115
112- waitStarted . await ();
116+ await (waitStarted );
113117 ctx .interrupt (Duration .ZERO );
114118
115119 for (Thread thread : threads ) {
@@ -121,4 +125,19 @@ public void testManyVirtualThreads() throws Throwable {
121125 }
122126 }
123127
128+ private static void await (CountDownLatch latch ) {
129+ boolean interrupted = false ;
130+ while (true ) {
131+ try {
132+ latch .await ();
133+ break ;
134+ } catch (InterruptedException e ) {
135+ interrupted = true ;
136+ }
137+ }
138+ if (interrupted ) {
139+ Thread .currentThread ().interrupt ();
140+ }
141+ }
142+
124143}
0 commit comments