/* * Copyright (C) 2015 RoboVM AB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.robovm.rt.bro; import static org.junit.Assert.*; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.CountDownLatch; import org.junit.Assume; import org.junit.Before; import org.junit.Test; import org.robovm.apple.dispatch.DispatchQueue; import org.robovm.rt.bro.annotation.Callback; /** * Tests that attaching of native threads in {@link Callback}s are only done * once even if the {@link Callback} is called multiple times from native code. */ public class CallbackAttachTest { @Before public void setUp() { // Only run this test on OSX/iOS since it relies on GCD String os = System.getProperty("os.name").toLowerCase(); Assume.assumeTrue(os.contains("mac") || os.contains("ios")); } @Test public void testAttachesOnlyOnce() throws Exception { final Set<Thread> threads = Collections.synchronizedSet(new HashSet<Thread>()); final CountDownLatch latch = new CountDownLatch(20); DispatchQueue q1 = DispatchQueue.create("q1", null); DispatchQueue q2 = DispatchQueue.create("q2", null); for (int i = 0; i < 20; i++) { ((i & 1) == 0 ? q1 : q2).async(new Runnable() { public void run() { threads.add(Thread.currentThread()); latch.countDown(); try { // Sleep some to prevent dispatch from using the same // worker thread for both queues Thread.sleep(10); } catch (InterruptedException e) { } } }); } latch.await(); assertEquals(2, threads.size()); List<Thread> l = new ArrayList<>(threads); Thread t1 = l.get(0); Thread t2 = l.get(1); assertTrue(t1.isDaemon()); assertTrue(t2.isDaemon()); assertTrue(t1.isAlive()); assertTrue(t2.isAlive()); assertEquals(0, t1.getStackTrace().length); assertEquals(0, t2.getStackTrace().length); q1.release(); q2.release(); t1.join(15000); t2.join(15000); assertFalse(t1.isAlive()); assertFalse(t2.isAlive()); } }