From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- .../remote/JavaThreadPoolFactory_Test.java | 48 +++ .../lib/uno/environments/remote/JobQueue_Test.java | 263 +++++++++++++ .../lib/uno/environments/remote/TestIWorkAt.java | 43 ++ .../lib/uno/environments/remote/TestReceiver.java | 27 ++ .../lib/uno/environments/remote/TestWorkAt.java | 81 ++++ .../lib/uno/environments/remote/ThreadId_Test.java | 57 +++ .../uno/environments/remote/ThreadPool_Test.java | 437 +++++++++++++++++++++ 7 files changed, 956 insertions(+) create mode 100644 ridljar/test/com/sun/star/lib/uno/environments/remote/JavaThreadPoolFactory_Test.java create mode 100644 ridljar/test/com/sun/star/lib/uno/environments/remote/JobQueue_Test.java create mode 100644 ridljar/test/com/sun/star/lib/uno/environments/remote/TestIWorkAt.java create mode 100644 ridljar/test/com/sun/star/lib/uno/environments/remote/TestReceiver.java create mode 100644 ridljar/test/com/sun/star/lib/uno/environments/remote/TestWorkAt.java create mode 100644 ridljar/test/com/sun/star/lib/uno/environments/remote/ThreadId_Test.java create mode 100644 ridljar/test/com/sun/star/lib/uno/environments/remote/ThreadPool_Test.java (limited to 'ridljar/test/com/sun/star/lib/uno/environments/remote') diff --git a/ridljar/test/com/sun/star/lib/uno/environments/remote/JavaThreadPoolFactory_Test.java b/ridljar/test/com/sun/star/lib/uno/environments/remote/JavaThreadPoolFactory_Test.java new file mode 100644 index 000000000..2d2264f06 --- /dev/null +++ b/ridljar/test/com/sun/star/lib/uno/environments/remote/JavaThreadPoolFactory_Test.java @@ -0,0 +1,48 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +package com.sun.star.lib.uno.environments.remote; + +import org.junit.Test; +import static org.junit.Assert.*; + +public final class JavaThreadPoolFactory_Test { + @Test public void test() throws InterruptedException { + ThreadId i1 = JavaThreadPoolFactory.getThreadId(); + assertEquals(i1, JavaThreadPoolFactory.getThreadId()); + final ThreadId[] i2 = new ThreadId[1]; + new Thread() { + @Override + public void run() { + synchronized (i2) { + i2[0] = JavaThreadPoolFactory.getThreadId(); + i2.notify(); + } + } + }.start(); + synchronized (i2) { + while (i2[0] == null) { + i2.wait(); + } + } + assertFalse(i1.equals(i2[0])); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ridljar/test/com/sun/star/lib/uno/environments/remote/JobQueue_Test.java b/ridljar/test/com/sun/star/lib/uno/environments/remote/JobQueue_Test.java new file mode 100644 index 000000000..a63c9c7ed --- /dev/null +++ b/ridljar/test/com/sun/star/lib/uno/environments/remote/JobQueue_Test.java @@ -0,0 +1,263 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +package com.sun.star.lib.uno.environments.remote; + +import com.sun.star.lib.uno.typedesc.TypeDescription; +import org.junit.Test; +import static org.junit.Assert.*; + +public final class JobQueue_Test { + @Test public void testThreadLeavesJobQueueOnDispose0() + throws InterruptedException + { + testThreadLeavesJobQueueOnDispose(0); + } + + @Test public void testThreadLeavesJobQueueOnDispose5000() + throws InterruptedException + { + testThreadLeavesJobQueueOnDispose(5000); + } + + private void testThreadLeavesJobQueueOnDispose(int waitTime) + throws InterruptedException + { + TestThread t = new TestThread(waitTime); + t.waitToStart(); + String msg = "xcxxxxxxxx"; + t._jobQueue.dispose(t._disposeId, new RuntimeException (msg)); + t.waitToTerminate(); +/*TODO: below test fails with "expected: but was:": + assertEquals(msg, t._message); +*/ + } + + @Test public void testThreadLeavesJobQueueOnReply0() + throws InterruptedException + { + testThreadLeavesJobQueueOnReply(0); + } + + @Test public void testThreadLeavesJobQueueOnReply5000() + throws InterruptedException + { + testThreadLeavesJobQueueOnReply(5000); + } + + private void testThreadLeavesJobQueueOnReply(int waitTime) + throws InterruptedException + { + TestThread t = new TestThread(waitTime); + t.waitToStart(); + // put reply job: + t._jobQueue.putJob( + new Job(null, __iReceiver, + new Message( + null, false, "oid", __workAt_td, null, false, null, + false, null, null)), + null); + t.waitToTerminate(); + assertTrue(true); // TODO! ??? + } + + @Test public void testStaticThreadExecutesJobs0() + throws InterruptedException + { + testStaticThreadExecutesJobs(0); + } + + @Test public void testStaticThreadExecutesJobs5000() + throws InterruptedException + { + testStaticThreadExecutesJobs(5000); + } + + private void testStaticThreadExecutesJobs(int waitTime) + throws InterruptedException + { + TestThread t = new TestThread(waitTime); + t.waitToStart(); + testExecuteJobs(t._jobQueue); + t._jobQueue.dispose(t._disposeId, + new RuntimeException("xxxxxxxxxxxxx")); + t.waitToTerminate(); + } + + @Test public void testDynamicThreadExecutesJob() throws InterruptedException + { + testExecuteJobs( + new JobQueue( + __javaThreadPoolFactory, ThreadId.createFresh(), true)); + } + + @Test public void testStaticThreadExecutesAsyncs() + throws InterruptedException + { + TestThread t = new TestThread(); + JobQueue async_jobQueue = new JobQueue(__javaThreadPoolFactory, + t._threadId); + assertEquals(1, async_jobQueue._ref_count); + t._jobQueue = __javaThreadPoolFactory.getJobQueue(t._threadId); + assertEquals(1, t._jobQueue._ref_count); + t.waitToStart(); + TestWorkAt workAt = new TestWorkAt(); + testAsyncJobQueue(workAt, async_jobQueue, t._threadId); + t._jobQueue.dispose(t._disposeId, + new RuntimeException("xxxxxxxxxxxxx")); + t.waitToTerminate(); + assertEquals(TestWorkAt.MESSAGES, workAt._async_counter); + assertEquals(TestWorkAt.MESSAGES, workAt._sync_counter); + } + + @Test public void testDynamicThreadExecutesAsyncs() + throws InterruptedException + { + ThreadId threadId = ThreadId.createFresh(); + JobQueue async_jobQueue = new JobQueue(__javaThreadPoolFactory, + threadId); + TestWorkAt workAt = new TestWorkAt(); + testAsyncJobQueue(workAt, async_jobQueue, threadId); + assertEquals(TestWorkAt.MESSAGES, workAt._async_counter); + assertEquals(TestWorkAt.MESSAGES, workAt._sync_counter); + } + + private void testExecuteJobs(JobQueue jobQueue) throws InterruptedException + { + TestWorkAt workAt = new TestWorkAt(); + testSendRequests(workAt, "increment", jobQueue); + synchronized (workAt) { + jobQueue.putJob(new Job(workAt, __iReceiver, + new Message( + null, true, "oid", __workAt_td, + __workAt_td.getMethodDescription( + "notifyme"), + true, null, false, null, null)), + null); + while (!workAt._notified) { + workAt.wait(); + } + } + assertEquals(TestWorkAt.MESSAGES, workAt._counter); + } + + private void testAsyncJobQueue(TestWorkAt workAt, JobQueue async_jobQueue, + ThreadId threadId) + throws InterruptedException + { + // put slow async calls first, followed by fast sync calls: + testSendRequests(workAt, "asyncCall", async_jobQueue); + testSendRequests(workAt, "syncCall", + __javaThreadPoolFactory.getJobQueue(threadId)); + synchronized (workAt) { + async_jobQueue._sync_jobQueue.putJob( + new Job(workAt, __iReceiver, + new Message( + null, true, "oid", __workAt_td, + __workAt_td.getMethodDescription("notifyme"), + true, null, false, null, null)), + null); + while (!workAt._notified) { + workAt.wait(); + } + } + assertTrue(workAt.passedAsyncTest()); + } + + private void testSendRequests(TestWorkAt workAt, String operation, + JobQueue jobQueue) { + Message iMessage = new Message( + null, true, "oid", __workAt_td, + __workAt_td.getMethodDescription(operation), + true, null, false, null, null); + for (int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + jobQueue.putJob(new Job(workAt, __iReceiver, iMessage), + new Object()); + } + } + + private static final class TestThread extends Thread { + public final ThreadId _threadId = JavaThreadPoolFactory.getThreadId(); + public final Object _disposeId = new Object(); + public JobQueue _jobQueue = null; + + public TestThread(int waitTime) { + this.waitTime = waitTime; + _jobQueue = new JobQueue(__javaThreadPoolFactory, _threadId, false); + } + + public TestThread() { + waitTime = 0; + } + + @Override + public void run() { + synchronized (lock) { + state = STATE_STARTED; + lock.notifyAll(); + } + try { + if (waitTime != 0) { + Thread.sleep(waitTime); + } + _jobQueue.enter(_disposeId); + } catch (Throwable e) { + } + synchronized (lock) { + state = STATE_DONE; + lock.notifyAll(); + } + } + + public void waitToStart() throws InterruptedException { + start(); + synchronized (lock) { + while (state == STATE_INITIAL) { + lock.wait(); + } + } + } + + public void waitToTerminate() throws InterruptedException { + synchronized (lock) { + while (state != STATE_DONE) { + lock.wait(); + } + } + join(); + } + + private final int waitTime; + + private final Object lock = new Object(); + private int state = STATE_INITIAL; + private static final int STATE_INITIAL = 0; + private static final int STATE_STARTED = 1; + private static final int STATE_DONE = 2; + } + + private static final JavaThreadPoolFactory __javaThreadPoolFactory + = new JavaThreadPoolFactory(); + private static final IReceiver __iReceiver = new TestReceiver(); + private static final TypeDescription __workAt_td + = TypeDescription.getTypeDescription(TestIWorkAt.class); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ridljar/test/com/sun/star/lib/uno/environments/remote/TestIWorkAt.java b/ridljar/test/com/sun/star/lib/uno/environments/remote/TestIWorkAt.java new file mode 100644 index 000000000..7bb71a80e --- /dev/null +++ b/ridljar/test/com/sun/star/lib/uno/environments/remote/TestIWorkAt.java @@ -0,0 +1,43 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +package com.sun.star.lib.uno.environments.remote; + + +import com.sun.star.lib.uno.typeinfo.MethodTypeInfo; +import com.sun.star.lib.uno.typeinfo.TypeInfo; +import com.sun.star.uno.XInterface; + +public interface TestIWorkAt extends XInterface { + void syncCall() throws Throwable ; + void asyncCall() throws Throwable ; + + void increment() throws Throwable; + + void notifyme(); + + TypeInfo UNOTYPEINFO[] = { + new MethodTypeInfo("increment", 0, 0), + new MethodTypeInfo("notifyme", 1, 0), + new MethodTypeInfo("syncCall", 2, 0), + new MethodTypeInfo("asyncCall", 3, 0) + }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ridljar/test/com/sun/star/lib/uno/environments/remote/TestReceiver.java b/ridljar/test/com/sun/star/lib/uno/environments/remote/TestReceiver.java new file mode 100644 index 000000000..6c8f36885 --- /dev/null +++ b/ridljar/test/com/sun/star/lib/uno/environments/remote/TestReceiver.java @@ -0,0 +1,27 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +package com.sun.star.lib.uno.environments.remote; + +final class TestReceiver implements IReceiver { + public void sendReply(boolean exception, ThreadId threadId, Object result) { + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ridljar/test/com/sun/star/lib/uno/environments/remote/TestWorkAt.java b/ridljar/test/com/sun/star/lib/uno/environments/remote/TestWorkAt.java new file mode 100644 index 000000000..93297815c --- /dev/null +++ b/ridljar/test/com/sun/star/lib/uno/environments/remote/TestWorkAt.java @@ -0,0 +1,81 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +package com.sun.star.lib.uno.environments.remote; + +import static org.junit.Assert.*; + +class TestWorkAt implements TestIWorkAt { + /** + * When set to true, enables various debugging output. + */ + private static final boolean DEBUG = false; + + static final int MESSAGES = 35; + + + int _counter; + + int _sync_counter; + int _async_counter; + + private boolean _passedAsync = true; + boolean _notified = false; + + public synchronized void syncCall() throws Throwable { + ++ _sync_counter; + + // at least in currently run tests this should never fire, so don't + // defer the check until passedAsyncTest and assert here + assertEquals(MESSAGES, _async_counter); + if(_async_counter != MESSAGES) + _passedAsync = false; + + if(DEBUG) System.err.println("syncCall:" + _sync_counter + " " + _passedAsync + " " + Thread.currentThread()); + } + + public synchronized void asyncCall() throws Throwable { + ++ _async_counter; + + if(DEBUG) System.err.println("asyncCall:" + _async_counter + " " + Thread.currentThread()); + } + + public synchronized void increment() throws Throwable { + if(DEBUG) System.err.println("increment - " + Thread.currentThread()); + + ++ _counter; + notifyAll(); + } + + public synchronized void notifyme() { + if(DEBUG) System.err.println("\t\t\tnotifying me" + Thread.currentThread()); + + notifyAll(); + + _notified = true; + } + + public synchronized boolean passedAsyncTest() { + assertEquals(MESSAGES, _sync_counter); + assertTrue(_passedAsync); + return _passedAsync && (_sync_counter == MESSAGES); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ridljar/test/com/sun/star/lib/uno/environments/remote/ThreadId_Test.java b/ridljar/test/com/sun/star/lib/uno/environments/remote/ThreadId_Test.java new file mode 100644 index 000000000..8ee7f4a4c --- /dev/null +++ b/ridljar/test/com/sun/star/lib/uno/environments/remote/ThreadId_Test.java @@ -0,0 +1,57 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +package com.sun.star.lib.uno.environments.remote; + +import java.util.Arrays; +import org.junit.Test; +import static org.junit.Assert.*; + +public final class ThreadId_Test { + @Test public void test() { + ThreadId i1 = ThreadId.createFresh(); + assertTrue(i1.equals(i1)); + assertFalse(i1.equals(null)); + assertFalse(i1.equals(new Object())); + assertEquals(i1.hashCode(), i1.hashCode()); + byte[] i1bytes = i1.getBytes(); + assertNotNull(i1bytes); + assertTrue(i1bytes.length >= 5); + assertEquals('j', i1bytes[0]); + assertEquals('a', i1bytes[1]); + assertEquals('v', i1bytes[2]); + assertEquals('a', i1bytes[3]); + assertEquals(':', i1bytes[4]); + assertArrayEquals(i1bytes, i1.getBytes()); + + ThreadId i2 = ThreadId.createFresh(); + assertFalse(i1.equals(i2)); + assertFalse(i2.equals(i1)); + assertFalse(Arrays.equals(i1bytes, i2.getBytes())); + + ThreadId i3 = new ThreadId(i1bytes); + assertTrue(i3.equals(i1)); + assertFalse(i3.equals(i2)); + assertTrue(i1.equals(i3)); + assertEquals(i1.hashCode(), i3.hashCode()); + assertArrayEquals(i1bytes, i3.getBytes()); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ridljar/test/com/sun/star/lib/uno/environments/remote/ThreadPool_Test.java b/ridljar/test/com/sun/star/lib/uno/environments/remote/ThreadPool_Test.java new file mode 100644 index 000000000..7da68db23 --- /dev/null +++ b/ridljar/test/com/sun/star/lib/uno/environments/remote/ThreadPool_Test.java @@ -0,0 +1,437 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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 . + */ + +package com.sun.star.lib.uno.environments.remote; + +import com.sun.star.lib.uno.typedesc.MethodDescription; +import com.sun.star.lib.uno.typedesc.TypeDescription; +import org.junit.Test; +import static org.junit.Assert.*; + +public class ThreadPool_Test { + @Test public void testDispose() throws InterruptedException { + IThreadPool iThreadPool = ThreadPoolManager.create(); + TestThread testThread = new TestThread(iThreadPool); + + ThreadId threadId = null; + + // start the test thread + synchronized(testThread) { + testThread.start(); + + testThread.wait(); + + threadId = testThread._threadId; + + // let the thread attach and enter the threadpool + testThread.notifyAll(); + } + + String message = "blabla"; + + // terminate the test thread + synchronized(testThread) { + // put reply job + iThreadPool.dispose(new RuntimeException(message)); + + testThread.wait(); + } + + testThread.join(); + +/*TODO: below test fails with "expected: but was:": + assertEquals(message, testThread._message); +*/ + } + + @Test public void testThreadAsync() throws InterruptedException { + TestWorkAt workAt = new TestWorkAt(); + + ThreadId threadId = ThreadId.createFresh(); + + // queue asyncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, false, threadId, "increment"); + } + + synchronized(workAt) { + putJob(workAt, false, threadId, "notifyme"); + + while(!workAt._notified) { + workAt.wait(); + } + } + + assertEquals(TestWorkAt.MESSAGES, workAt._counter); + } + + @Test public void testDynamicThreadSync() throws InterruptedException { + TestWorkAt workAt = new TestWorkAt(); + + ThreadId threadId = ThreadId.createFresh(); + + // queue asyncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, true, threadId, "increment"); + } + + synchronized(workAt) { + putJob(workAt, true, threadId, "notifyme"); + + while(!workAt._notified) { + workAt.wait(); + } + } + + assertEquals(TestWorkAt.MESSAGES, workAt._counter); + } + + @Test public void testStaticThreadSync() throws InterruptedException { + TestWorkAt workAt = new TestWorkAt(); + + TestThread testThread = new TestThread(); + + ThreadId threadId = null; + + // start the test thread + synchronized(testThread) { + testThread.start(); + + testThread.wait(); + + threadId = testThread._threadId; + + // let the thread attach and enter the threadpool + testThread.notifyAll(); + } + + // queue syncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, true, threadId, "increment"); + } + + // terminate the test thread + synchronized(testThread) { + // put reply job + putJob(workAt, true, threadId, null); + + testThread.wait(); + } + + testThread.join(); + + assertEquals(TestWorkAt.MESSAGES, workAt._counter); + } + + @Test public void testDynamicThreadAsyncSyncOrder() + throws InterruptedException + { + TestWorkAt workAt = new TestWorkAt(); + + ThreadId threadId = ThreadId.createFresh(); + + // queue asyncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, false, threadId, "asyncCall"); + } + + // queue syncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, true, threadId, "syncCall"); + } + + synchronized(workAt) { + putJob(workAt, true, threadId, "notifyme"); + + while(!workAt._notified) { + workAt.wait(); + } + } + + assertTrue(workAt.passedAsyncTest()); + } + + @Test public void testStaticThreadAsyncSyncOrder() + throws InterruptedException + { + TestWorkAt workAt = new TestWorkAt(); + + TestThread testThread = new TestThread(); + + // start the test thread + synchronized(testThread) { + testThread.start(); + + testThread.wait(); + } + + ThreadId threadId = testThread._threadId; + + // queue asyncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, false, threadId, "asyncCall"); + } + + // let the thread attach and enter the threadpool + synchronized(testThread) { + testThread.notifyAll(); + } + + // queue syncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, true, threadId, "syncCall"); + } + + // terminate the test thread + synchronized(testThread) { + // put reply job + putJob(workAt, true, threadId, null); + + testThread.wait(); + } + + testThread.join(); + + assertTrue(workAt.passedAsyncTest()); + } + + @Test public void testStress() throws InterruptedException { + TestWorkAt workAt = new TestWorkAt(); + for (int i = 0; i < TestWorkAt.MESSAGES; ++i) { + Thread.yield(); // force scheduling + ThreadId threadID = ThreadId.createFresh(); + putJob(workAt, true, threadID, "increment"); + putJob(workAt, false, threadID, "increment"); + } + synchronized (workAt) { + while (workAt._counter < 2 * TestWorkAt.MESSAGES) { + workAt.wait(); + } + } + + abstract class Stress extends Thread { + private Stress(int count) { + this.count = count; + } + + @Override + public void run() { + try { + for (int i = 0; i < count; ++i) { + runTest(); + } + } catch (Throwable e) { + e.printStackTrace(System.err); + } + } + + protected abstract void runTest() throws InterruptedException; + + private final int count; + } + + Stress stress1 = new Stress(50) { + @Override + protected void runTest() throws InterruptedException { + testThreadAsync(); + } + }; + stress1.start(); + + Stress stress2 = new Stress(50) { + @Override + protected void runTest() throws InterruptedException { + testDynamicThreadSync(); + } + }; + stress2.start(); + + Stress stress3 = new Stress(50) { + @Override + protected void runTest() throws InterruptedException { + testStaticThreadSync(); + } + }; + stress3.start(); + + Stress stress4 = new Stress(50) { + @Override + protected void runTest() throws InterruptedException { + testDynamicThreadAsyncSyncOrder(); + } + }; + stress4.start(); + + Stress stress5 = new Stress(50) { + @Override + protected void runTest() throws InterruptedException { + testStaticThreadAsyncSyncOrder(); + } + }; + stress5.start(); + + Stress stress6 = new Stress(500) { + @Override + protected void runTest() throws InterruptedException { + testDispose(); + } + }; + stress6.start(); + + stress1.join(); + stress2.join(); + stress3.join(); + stress4.join(); + stress5.join(); + stress6.join(); + } + + @Test public void testAsyncSync() throws InterruptedException { + TestWorkAt workAt = new TestWorkAt(); + ThreadId threadId = ThreadId.createFresh(); + MyWorkAt myWorkAt = new MyWorkAt( workAt ); + + // queue asyncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + if( i == 2 ) + { + putJob( myWorkAt, false , threadId, "asyncCall" ); + } + putJob(workAt, false, threadId, "asyncCall"); + } + + synchronized(workAt) { + putJob(workAt, false, threadId, "notifyme"); + + while(!workAt._notified) { + workAt.wait(); + } + } + + assertEquals(TestWorkAt.MESSAGES, workAt._async_counter); + assertTrue(myWorkAt._success); + } + + private static void putJob(TestIWorkAt iWorkAt, boolean synchron, + ThreadId threadId, String operation) { + __iThreadPool.putJob( + new Job(iWorkAt, __iReceiver, + new Message( + threadId, operation != null, "oid", __workAt_td, + (operation == null + ? null + : ((MethodDescription) + __workAt_td.getMethodDescription(operation))), + synchron, null, false, null, null))); + } + + private static final class TestThread extends Thread { + ThreadId _threadId; + IThreadPool _iThreadPool; + + TestThread() { + this(__iThreadPool); + } + + TestThread(IThreadPool iThreadPool) { + _iThreadPool = iThreadPool; + } + + @Override + public void run() { + _threadId = _iThreadPool.getThreadId(); + + + try { + synchronized(this) { + // notify that we are running + notify(); + + _iThreadPool.attach(); + + // wait until we should continue + wait(); + } + + _iThreadPool.enter(); + } + catch(Throwable throwable) { + } + + _iThreadPool.detach(); + + synchronized(this) { + // notify the listeners that we are dying + notifyAll(); + } + } + } + + private static final class MyWorkAt implements TestIWorkAt { + public MyWorkAt( TestWorkAt async_WorkAt ) { + _async_WorkAt = async_WorkAt; + } + + public void syncCall() throws Throwable + { + Message iMessage = new Message( + __iThreadPool.getThreadId(), false, "oid", __workAt_td, null, + false, null, false, null, null); + + // marshal reply + ThreadPool_Test.__iThreadPool.putJob( + new Job(this, ThreadPool_Test. __iReceiver, iMessage)); + } + + public void asyncCall() throws Throwable { + for (int i = 0 ; i < 5 ; ++i) { + ThreadPool_Test.__iThreadPool.attach(); + ThreadPool_Test.putJob(this, true, __iThreadPool.getThreadId(), + "syncCall"); + // wait for reply + ThreadPool_Test.__iThreadPool.enter(); + ThreadPool_Test.__iThreadPool.detach(); + } + // async must have waited for this call + _success = _async_WorkAt._async_counter == 2; + } + + public void increment() throws Throwable {} + + public void notifyme() {} + + public boolean _success = false; + + private final TestWorkAt _async_WorkAt; + } + + private static final IThreadPool __iThreadPool = ThreadPoolManager.create(); + private static final IReceiver __iReceiver = new TestReceiver(); + private static final TypeDescription __workAt_td + = TypeDescription.getTypeDescription(TestIWorkAt.class); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3