< prev index next >

test/jdk/jdk/internal/misc/ThreadFlock/WithScopedValue.java

Print this page

  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 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  * @summary Test ThreadFlock with scoped values

 27  * @modules java.base/jdk.internal.misc
 28  * @modules jdk.incubator.concurrent
 29  * @run junit WithScopedValue
 30  */
 31 
 32 import jdk.internal.misc.ThreadFlock;
 33 import jdk.incubator.concurrent.ScopedValue;
 34 import jdk.incubator.concurrent.StructureViolationException;
 35 import java.util.concurrent.ThreadFactory;

 36 import java.util.concurrent.atomic.AtomicReference;
 37 import java.util.stream.Stream;
 38 
 39 import org.junit.jupiter.api.Test;
 40 import org.junit.jupiter.params.ParameterizedTest;
 41 import org.junit.jupiter.params.provider.MethodSource;
 42 import static org.junit.jupiter.api.Assertions.*;
 43 
 44 class WithScopedValue {
 45 
 46     private static Stream<ThreadFactory> factories() {
 47         return Stream.of(Thread.ofPlatform().factory(), Thread.ofVirtual().factory());
 48     }
 49 
 50     /**
 51      * Test inheritance of a scoped value.
 52      */
 53     @ParameterizedTest
 54     @MethodSource("factories")
 55     void testInheritsScopedValue(ThreadFactory factory) throws Exception {
 56         ScopedValue<String> name = ScopedValue.newInstance();
 57         String value = ScopedValue.where(name, "duke", () -> {
 58             var result = new AtomicReference<String>();
 59             try (var flock = ThreadFlock.open(null)) {
 60                 Thread thread = factory.newThread(() -> {
 61                     // child
 62                     result.set(name.get());
 63                 });
 64                 flock.start(thread);
 65             }
 66             return result.get();
 67         });
 68         assertEquals("duke", value);
 69     }
 70 
 71     /**
 72      * Test exiting a dynamic scope with open thread flocks.
 73      */
 74     @Test
 75     void testStructureViolation1() {
 76         ScopedValue<String> name = ScopedValue.newInstance();
 77         class Box {
 78             ThreadFlock flock1;
 79             ThreadFlock flock2;
 80         }
 81         var box = new Box();
 82         try {
 83             ScopedValue.where(name, "x1", () -> {
 84                 box.flock1 = ThreadFlock.open(null);
 85                 box.flock2 = ThreadFlock.open(null);
 86             });
 87             fail();
 88         } catch (StructureViolationException expected) { }
 89         assertTrue(box.flock1.isClosed());
 90         assertTrue(box.flock2.isClosed());
 91     }
 92 
 93     /**
 94      * Test closing a thread flock while in a dynamic scope and with enclosing thread
 95      * flocks. This test closes enclosing flock1.
 96      */
 97     @Test
 98     void testStructureViolation2() {
 99         ScopedValue<String> name = ScopedValue.newInstance();
100         try (var flock1 = ThreadFlock.open("flock1")) {
101             ScopedValue.where(name, "x1", () -> {
102                 try (var flock2 = ThreadFlock.open("flock2")) {
103                     ScopedValue.where(name, "x2", () -> {
104                         try (var flock3 = ThreadFlock.open("flock3")) {
105                             ScopedValue.where(name, "x3", () -> {
106                                 var flock4 = ThreadFlock.open("flock4");
107 
108                                 try {
109                                     flock1.close();
110                                     fail();
111                                 } catch (StructureViolationException expected) { }
112 
113                                 assertTrue(flock1.isClosed());
114                                 assertTrue(flock2.isClosed());
115                                 assertTrue(flock3.isClosed());
116                                 assertTrue(flock4.isClosed());
117                             });
118                         }
119                     });
120                 }
121             });
122         }
123     }
124 
125     /**
126      * Test closing a thread flock while in a dynamic scope and with enclosing thread
127      * flocks. This test closes enclosing flock2.
128      */
129     @Test
130     void testStructureViolation3() {
131         ScopedValue<String> name = ScopedValue.newInstance();
132         try (var flock1 = ThreadFlock.open("flock1")) {
133             ScopedValue.where(name, "x1", () -> {
134                 try (var flock2 = ThreadFlock.open("flock2")) {
135                     ScopedValue.where(name, "x2", () -> {
136                         try (var flock3 = ThreadFlock.open("flock3")) {
137                             ScopedValue.where(name, "x3", () -> {
138                                 var flock4 = ThreadFlock.open("flock4");
139 
140                                 try {
141                                     flock2.close();
142                                     fail();
143                                 } catch (StructureViolationException expected) { }
144 
145                                 assertFalse(flock1.isClosed());
146                                 assertTrue(flock2.isClosed());
147                                 assertTrue(flock3.isClosed());
148                                 assertTrue(flock4.isClosed());
149                             });
150                         }
151                     });
152                 }
153             });
154         }
155     }
156 
157     /**
158      * Test closing a thread flock while in a dynamic scope and with enclosing thread
159      * flocks. This test closes enclosing flock3.
160      */
161     @Test
162     void testStructureViolation4() {
163         ScopedValue<String> name = ScopedValue.newInstance();
164         try (var flock1 = ThreadFlock.open("flock1")) {
165             ScopedValue.where(name, "x1", () -> {
166                 try (var flock2 = ThreadFlock.open("flock2")) {
167                     ScopedValue.where(name, "x2", () -> {
168                         try (var flock3 = ThreadFlock.open("flock3")) {
169                             ScopedValue.where(name, "x3", () -> {
170                                 var flock4 = ThreadFlock.open("flock4");
171 
172                                 try {
173                                     flock3.close();
174                                     fail();
175                                 } catch (StructureViolationException expected) { }
176 
177                                 assertFalse(flock1.isClosed());
178                                 assertFalse(flock2.isClosed());
179                                 assertTrue(flock3.isClosed());
180                                 assertTrue(flock4.isClosed());
181                             });
182                         }
183                     });
184                 }
185             });
186         }
187     }
188 
189     /**
190      * Test start when a scoped value is bound after a thread flock is created.
191      */
192     @ParameterizedTest
193     @MethodSource("factories")
194     void testStructureViolation5(ThreadFactory factory) throws Exception {
195         ScopedValue<String> name = ScopedValue.newInstance();
196         try (var flock = ThreadFlock.open(null)) {
197             ScopedValue.where(name, "duke", () -> {
198                 Thread thread = factory.newThread(() -> { });
199                 assertThrows(StructureViolationException.class, () -> flock.start(thread));
200             });
201         }
202     }
203 
204     /**
205      * Test start when a scoped value is re-bound after a thread flock is created.
206      */
207     @ParameterizedTest
208     @MethodSource("factories")
209     void testStructureViolation6(ThreadFactory factory) throws Exception {
210         ScopedValue<String> name = ScopedValue.newInstance();
211         ScopedValue.where(name, "duke", () -> {
212             try (var flock = ThreadFlock.open(null)) {
213                 ScopedValue.where(name, "duchess", () -> {
214                     Thread thread = factory.newThread(() -> { });
215                     assertThrows(StructureViolationException.class, () -> flock.start(thread));
216                 });
217             }
218         });
219     }
220 }

  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 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  * @summary Test ThreadFlock with scoped values
 27  * @enablePreview
 28  * @modules java.base/jdk.internal.misc

 29  * @run junit WithScopedValue
 30  */
 31 
 32 import jdk.internal.misc.ThreadFlock;


 33 import java.util.concurrent.ThreadFactory;
 34 import java.util.concurrent.StructureViolationException;
 35 import java.util.concurrent.atomic.AtomicReference;
 36 import java.util.stream.Stream;
 37 
 38 import org.junit.jupiter.api.Test;
 39 import org.junit.jupiter.params.ParameterizedTest;
 40 import org.junit.jupiter.params.provider.MethodSource;
 41 import static org.junit.jupiter.api.Assertions.*;
 42 
 43 class WithScopedValue {
 44 
 45     private static Stream<ThreadFactory> factories() {
 46         return Stream.of(Thread.ofPlatform().factory(), Thread.ofVirtual().factory());
 47     }
 48 
 49     /**
 50      * Test inheritance of a scoped value.
 51      */
 52     @ParameterizedTest
 53     @MethodSource("factories")
 54     void testInheritsScopedValue(ThreadFactory factory) throws Exception {
 55         ScopedValue<String> name = ScopedValue.newInstance();
 56         String value = ScopedValue.callWhere(name, "duke", () -> {
 57             var result = new AtomicReference<String>();
 58             try (var flock = ThreadFlock.open(null)) {
 59                 Thread thread = factory.newThread(() -> {
 60                     // child
 61                     result.set(name.get());
 62                 });
 63                 flock.start(thread);
 64             }
 65             return result.get();
 66         });
 67         assertEquals("duke", value);
 68     }
 69 
 70     /**
 71      * Test exiting a dynamic scope with open thread flocks.
 72      */
 73     @Test
 74     void testStructureViolation1() {
 75         ScopedValue<String> name = ScopedValue.newInstance();
 76         class Box {
 77             ThreadFlock flock1;
 78             ThreadFlock flock2;
 79         }
 80         var box = new Box();
 81         try {
 82             ScopedValue.runWhere(name, "x1", () -> {
 83                 box.flock1 = ThreadFlock.open(null);
 84                 box.flock2 = ThreadFlock.open(null);
 85             });
 86             fail();
 87         } catch (StructureViolationException expected) { }
 88         assertTrue(box.flock1.isClosed());
 89         assertTrue(box.flock2.isClosed());
 90     }
 91 
 92     /**
 93      * Test closing a thread flock while in a dynamic scope and with enclosing thread
 94      * flocks. This test closes enclosing flock1.
 95      */
 96     @Test
 97     void testStructureViolation2() {
 98         ScopedValue<String> name = ScopedValue.newInstance();
 99         try (var flock1 = ThreadFlock.open("flock1")) {
100             ScopedValue.runWhere(name, "x1", () -> {
101                 try (var flock2 = ThreadFlock.open("flock2")) {
102                     ScopedValue.runWhere(name, "x2", () -> {
103                         try (var flock3 = ThreadFlock.open("flock3")) {
104                             ScopedValue.runWhere(name, "x3", () -> {
105                                 var flock4 = ThreadFlock.open("flock4");
106 
107                                 try {
108                                     flock1.close();
109                                     fail();
110                                 } catch (StructureViolationException expected) { }
111 
112                                 assertTrue(flock1.isClosed());
113                                 assertTrue(flock2.isClosed());
114                                 assertTrue(flock3.isClosed());
115                                 assertTrue(flock4.isClosed());
116                             });
117                         }
118                     });
119                 }
120             });
121         }
122     }
123 
124     /**
125      * Test closing a thread flock while in a dynamic scope and with enclosing thread
126      * flocks. This test closes enclosing flock2.
127      */
128     @Test
129     void testStructureViolation3() {
130         ScopedValue<String> name = ScopedValue.newInstance();
131         try (var flock1 = ThreadFlock.open("flock1")) {
132             ScopedValue.runWhere(name, "x1", () -> {
133                 try (var flock2 = ThreadFlock.open("flock2")) {
134                     ScopedValue.runWhere(name, "x2", () -> {
135                         try (var flock3 = ThreadFlock.open("flock3")) {
136                             ScopedValue.runWhere(name, "x3", () -> {
137                                 var flock4 = ThreadFlock.open("flock4");
138 
139                                 try {
140                                     flock2.close();
141                                     fail();
142                                 } catch (StructureViolationException expected) { }
143 
144                                 assertFalse(flock1.isClosed());
145                                 assertTrue(flock2.isClosed());
146                                 assertTrue(flock3.isClosed());
147                                 assertTrue(flock4.isClosed());
148                             });
149                         }
150                     });
151                 }
152             });
153         }
154     }
155 
156     /**
157      * Test closing a thread flock while in a dynamic scope and with enclosing thread
158      * flocks. This test closes enclosing flock3.
159      */
160     @Test
161     void testStructureViolation4() {
162         ScopedValue<String> name = ScopedValue.newInstance();
163         try (var flock1 = ThreadFlock.open("flock1")) {
164             ScopedValue.runWhere(name, "x1", () -> {
165                 try (var flock2 = ThreadFlock.open("flock2")) {
166                     ScopedValue.runWhere(name, "x2", () -> {
167                         try (var flock3 = ThreadFlock.open("flock3")) {
168                             ScopedValue.runWhere(name, "x3", () -> {
169                                 var flock4 = ThreadFlock.open("flock4");
170 
171                                 try {
172                                     flock3.close();
173                                     fail();
174                                 } catch (StructureViolationException expected) { }
175 
176                                 assertFalse(flock1.isClosed());
177                                 assertFalse(flock2.isClosed());
178                                 assertTrue(flock3.isClosed());
179                                 assertTrue(flock4.isClosed());
180                             });
181                         }
182                     });
183                 }
184             });
185         }
186     }
187 
188     /**
189      * Test start when a scoped value is bound after a thread flock is created.
190      */
191     @ParameterizedTest
192     @MethodSource("factories")
193     void testStructureViolation5(ThreadFactory factory) throws Exception {
194         ScopedValue<String> name = ScopedValue.newInstance();
195         try (var flock = ThreadFlock.open(null)) {
196             ScopedValue.runWhere(name, "duke", () -> {
197                 Thread thread = factory.newThread(() -> { });
198                 assertThrows(StructureViolationException.class, () -> flock.start(thread));
199             });
200         }
201     }
202 
203     /**
204      * Test start when a scoped value is re-bound after a thread flock is created.
205      */
206     @ParameterizedTest
207     @MethodSource("factories")
208     void testStructureViolation6(ThreadFactory factory) throws Exception {
209         ScopedValue<String> name = ScopedValue.newInstance();
210         ScopedValue.runWhere(name, "duke", () -> {
211             try (var flock = ThreadFlock.open(null)) {
212                 ScopedValue.runWhere(name, "duchess", () -> {
213                     Thread thread = factory.newThread(() -> { });
214                     assertThrows(StructureViolationException.class, () -> flock.start(thread));
215                 });
216             }
217         });
218     }
219 }
< prev index next >