Search in sources :

Example 6 with ThreadInterruptedError

use of org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError in project scout.rt by eclipse.

the class FutureAwaitTest method testBlockingConditionWaitFor_Interrupted.

@Test(timeout = 5000)
public void testBlockingConditionWaitFor_Interrupted() throws java.lang.InterruptedException {
    final IBlockingCondition condition = Jobs.newBlockingCondition(true);
    // Run the test in a separate thread
    IFuture<Void> controller = Jobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            Thread.currentThread().interrupt();
            try {
                condition.waitFor();
                fail("interruption expected");
            } catch (ThreadInterruptedError e) {
                assertTrue(Thread.currentThread().isInterrupted());
            }
        }
    }, Jobs.newInput());
    controller.awaitDoneAndGet(10, TimeUnit.SECONDS);
}
Also used : ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) Test(org.junit.Test)

Example 7 with ThreadInterruptedError

use of org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError in project scout.rt by eclipse.

the class AbstractServiceTunnel method checkAlreadyCancelled.

/**
 * Will throw a CancellationException if the future is already cancelled.
 *
 * @throws ThreadInterruptedError
 *           if the current thread is cancelled
 */
protected void checkAlreadyCancelled(ServiceTunnelRequest serviceRequest) {
    final RunMonitor monitor = RunMonitor.CURRENT.get();
    if (monitor != null && monitor.isCancelled()) {
        final StringBuilder cancellationExceptionText = new StringBuilder();
        cancellationExceptionText.append("RunMonitor is already cancelled.");
        if (serviceRequest != null) {
            cancellationExceptionText.append(" (Request was '");
            cancellationExceptionText.append(serviceRequest.getServiceInterfaceClassName());
            cancellationExceptionText.append(".");
            cancellationExceptionText.append(serviceRequest.getOperation());
            cancellationExceptionText.append("(..)')");
        }
        throw new ThreadInterruptedError(cancellationExceptionText.toString());
    }
}
Also used : RunMonitor(org.eclipse.scout.rt.platform.context.RunMonitor) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError)

Example 8 with ThreadInterruptedError

use of org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError in project scout.rt by eclipse.

the class RemoteServiceInvocationCallable method cancel.

/**
 * Cancels the remote service operation on server side.
 */
public void cancel() {
    try {
        final String sessionId = m_serviceRequest.getSessionId();
        if (sessionId == null) {
            // cannot cancel an event without session. The IRunMonitorCancelService requires a session.
            return;
        }
        final Method serviceMethod = IRunMonitorCancelService.class.getMethod(IRunMonitorCancelService.CANCEL_METHOD, long.class);
        final Object[] serviceArgs = new Object[] { m_serviceRequest.getRequestSequence() };
        ServiceTunnelRequest request = m_tunnel.createRequest(IRunMonitorCancelService.class, serviceMethod, serviceArgs);
        request.setClientNodeId(m_serviceRequest.getClientNodeId());
        request.setSessionId(sessionId);
        request.setUserAgent(m_serviceRequest.getUserAgent());
        m_tunnel.invokeService(request);
    } catch (final FutureCancelledError | ThreadInterruptedError e) {
    // NOSONAR
    // NOOP: Do not cancel 'cancel-request' to prevent loop.
    } catch (RuntimeException | NoSuchMethodException e) {
        LOG.warn("Failed to cancel server processing [requestSequence={}]", m_serviceRequest.getRequestSequence(), e);
    }
}
Also used : FutureCancelledError(org.eclipse.scout.rt.platform.util.concurrent.FutureCancelledError) ServiceTunnelRequest(org.eclipse.scout.rt.shared.servicetunnel.ServiceTunnelRequest) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) Method(java.lang.reflect.Method)

Example 9 with ThreadInterruptedError

use of org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError in project scout.rt by eclipse.

the class MutualExclusionTest method testBlockingCondition_InterruptedWhileReAcquiringTheMutex.

/**
 * We have 3 jobs that are scheduled simultaneously. Thereby, job1 enters a blocking condition which in turn lets job2
 * run. Job2 unblocks job1 so that job1 is trying to re-acquire the mutex. While waiting for the mutex to be
 * available, job1 is interrupted due to a cancel-request of job2.<br/>
 * This test verifies, that job1 is interrupted, competes for the mutex anew and only continues once a permit becomes
 * available. Also, job3 must not start running as long as job1 did not complete.
 */
@Test
// regression
@Times(100)
public void testBlockingCondition_InterruptedWhileReAcquiringTheMutex() throws java.lang.InterruptedException {
    // synchronized because modified/read by different threads.
    final List<String> protocol = Collections.synchronizedList(new ArrayList<String>());
    final IBlockingCondition condition = Jobs.newBlockingCondition(true);
    final BlockingCountDownLatch latchJob2 = new BlockingCountDownLatch(1);
    final BlockingCountDownLatch job1FinishLatch = new BlockingCountDownLatch(1);
    final IFuture<Void> future1 = ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("running-1");
            try {
                protocol.add("before-blocking-1");
                condition.waitFor();
            } catch (ThreadInterruptedError e) {
                protocol.add("interrupted-1 (a)");
            } catch (RuntimeException e) {
                protocol.add("jobException-1");
            }
            if (Thread.currentThread().isInterrupted()) {
                protocol.add("interrupted-1 (b)");
            }
            if (ModelJobs.isModelThread()) {
                protocol.add("model-thread-1");
            }
            protocol.add("done-1");
            job1FinishLatch.countDown();
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withName("job-1").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
    final IFuture<Void> future2 = ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("running-2a");
            if (future1.getState() == JobState.WAITING_FOR_BLOCKING_CONDITION) {
                protocol.add("job2: job-1-waiting-for-blocking-condition");
            }
            if (!future1.getExecutionSemaphore().isPermitOwner(future1)) {
                protocol.add("job2: job-1-not-permit-owner");
            }
            protocol.add("unblocking condition");
            condition.setBlocking(false);
            // job-1 (interrupted acquisition task), job-2 (latch), job-3 (waiting for mutex)
            JobTestUtil.waitForPermitCompetitors(m_clientSession.getModelJobSemaphore(), 3);
            if (future1.getState() == JobState.WAITING_FOR_PERMIT) {
                protocol.add("job2: job-1-waiting-for-mutex");
            }
            protocol.add("before-cancel-job1-2");
            // interrupt job1 while acquiring the mutex
            future1.cancel(true);
            // job-1 (interrupted acquisition task), job-1 (re-acquiring a permit), job-2 (latch), job-3 (waiting for mutex)
            JobTestUtil.waitForPermitCompetitors(m_clientSession.getModelJobSemaphore(), 4);
            // cancelled, but still running
            JobTestUtil.waitForState(future1, JobState.DONE);
            protocol.add("running-2b");
            latchJob2.countDownAndBlock();
            protocol.add("done-2");
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withName("job-2").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
    final IFuture<Void> future3 = ModelJobs.schedule(new IRunnable() {

        @Override
        public void run() throws Exception {
            protocol.add("done-3");
        }
    }, ModelJobs.newInput(ClientRunContexts.copyCurrent()).withName("job-3").withExecutionHint(JOB_IDENTIFIER).withExceptionHandling(null, false));
    assertTrue(latchJob2.await());
    assertEquals(future1.getState(), JobState.DONE);
    assertEquals(future2.getState(), JobState.RUNNING);
    assertEquals(future3.getState(), JobState.WAITING_FOR_PERMIT);
    latchJob2.unblock();
    Jobs.getJobManager().awaitDone(Jobs.newFutureFilterBuilder().andMatchExecutionHint(JOB_IDENTIFIER).toFilter(), 5, TimeUnit.SECONDS);
    List<String> expectedProtocol = new ArrayList<>();
    expectedProtocol.add("running-1");
    expectedProtocol.add("before-blocking-1");
    expectedProtocol.add("running-2a");
    expectedProtocol.add("job2: job-1-waiting-for-blocking-condition");
    expectedProtocol.add("job2: job-1-not-permit-owner");
    expectedProtocol.add("unblocking condition");
    expectedProtocol.add("job2: job-1-waiting-for-mutex");
    expectedProtocol.add("before-cancel-job1-2");
    expectedProtocol.add("running-2b");
    expectedProtocol.add("done-2");
    expectedProtocol.add("interrupted-1 (b)");
    expectedProtocol.add("model-thread-1");
    expectedProtocol.add("done-1");
    expectedProtocol.add("done-3");
    assertEquals(expectedProtocol, protocol);
    assertEquals(future1.getState(), JobState.DONE);
    assertEquals(future2.getState(), JobState.DONE);
    assertEquals(future3.getState(), JobState.DONE);
    assertTrue(future1.isCancelled());
    future1.awaitDone(1, TimeUnit.NANOSECONDS);
    assertFalse(future2.isCancelled());
    future2.awaitDone(1, TimeUnit.NANOSECONDS);
    assertFalse(future3.isCancelled());
    future3.awaitDone(1, TimeUnit.NANOSECONDS);
}
Also used : BlockingCountDownLatch(org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch) ArrayList(java.util.ArrayList) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError) IRunnable(org.eclipse.scout.rt.platform.util.concurrent.IRunnable) ProcessingException(org.eclipse.scout.rt.platform.exception.ProcessingException) AssertionException(org.eclipse.scout.rt.platform.util.Assertions.AssertionException) IBlockingCondition(org.eclipse.scout.rt.platform.job.IBlockingCondition) Test(org.junit.Test) Times(org.eclipse.scout.rt.testing.platform.runner.Times)

Example 10 with ThreadInterruptedError

use of org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError in project scout.rt by eclipse.

the class DefaultBeanInstanceProducer method getApplicationScopedInstance.

private T getApplicationScopedInstance(final IBean<T> bean) {
    T instance = m_applicationScopedInstance.get();
    if (instance != null) {
        return instance;
    }
    if (m_creatorThread.compareAndSet(null, Thread.currentThread())) {
        try {
            // check again to avoid race conditions
            instance = m_applicationScopedInstance.get();
            if (instance != null) {
                return instance;
            }
            // current thread has to create instance
            instance = safeCreateInstance(bean.getBeanClazz());
            m_applicationScopedInstance.set(instance);
            return instance;
        } finally {
            synchronized (this) {
                // reset creator thread so that another one tries to create the bean again in case the current ran into an exception.
                m_creatorThread.set(null);
                // wake up other threads waiting on the application-scoped instance
                this.notifyAll();
            }
        }
    }
    // remember creator thread for logging purposes
    final Thread creatorThread = m_creatorThread.get();
    final int maxWaitTimeSeconds = getDeadlockDetectionMaxWaitTimeSeconds();
    final long maxWaitEndTimeMillis = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(maxWaitTimeSeconds);
    boolean logDebug = LOG.isDebugEnabled();
    do {
        try {
            synchronized (this) {
                if (m_creatorThread.get() == null) {
                    break;
                }
                long waitTimeMillis = logDebug ? TimeUnit.SECONDS.toMillis(Math.min(maxWaitTimeSeconds, DEADLOCK_DETECTION_DEBUG_WAIT_TIME_SECONDS)) : maxWaitEndTimeMillis - System.currentTimeMillis();
                if (waitTimeMillis > 0) {
                    // wait for the creator to complete, but not too long because the notify signal could have been missed
                    this.wait(waitTimeMillis);
                }
            }
        } catch (InterruptedException e) {
            throw new ThreadInterruptedError("Thread has been interrupted");
        }
        if (m_creatorThread.get() == null) {
            break;
        }
        if (logDebug) {
            logWarnPotentialDeadlock(creatorThread);
            logDebug = false;
        }
    } while (// try as long as the other thread is still creating the bean and the max wait time has not been elapsed
    System.currentTimeMillis() < maxWaitEndTimeMillis);
    // check if bean has been created in the meantime
    instance = m_applicationScopedInstance.get();
    if (instance != null) {
        return instance;
    }
    // bean has not been created
    if (System.currentTimeMillis() < maxWaitEndTimeMillis) {
        throw new BeanCreationException("Thread was waiting on bean instance creator thread which most likely failed (check the log).").withContextInfo("beanClass", bean == null || bean.getBeanClazz() == null ? "n/a" : bean.getBeanClazz().getName()).withContextInfo("creatorThreadID", creatorThread == null ? "n/a" : creatorThread.getId()).withContextInfo("creatorThreadName", creatorThread == null ? "n/a" : creatorThread.getName());
    } else {
        logWarnPotentialDeadlock(creatorThread);
        throw new BeanCreationException("Potential deadlock detected: bean is being created by another thread. Either the creation takes longer than {}s " + "or the current and the creator threads are blocking each other (check the log).", maxWaitTimeSeconds).withContextInfo("beanClass", bean == null || bean.getBeanClazz() == null ? "n/a" : bean.getBeanClazz().getName()).withContextInfo("creatorThreadID", creatorThread == null ? "n/a" : creatorThread.getId()).withContextInfo("creatorThreadName", creatorThread == null ? "n/a" : creatorThread.getName());
    }
}
Also used : BeanCreationException(org.eclipse.scout.rt.platform.exception.BeanCreationException) ThreadInterruptedError(org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError)

Aggregations

ThreadInterruptedError (org.eclipse.scout.rt.platform.util.concurrent.ThreadInterruptedError)36 IRunnable (org.eclipse.scout.rt.platform.util.concurrent.IRunnable)20 Test (org.junit.Test)14 BlockingCountDownLatch (org.eclipse.scout.rt.testing.platform.util.BlockingCountDownLatch)13 TimedOutError (org.eclipse.scout.rt.platform.util.concurrent.TimedOutError)8 FutureCancelledError (org.eclipse.scout.rt.platform.util.concurrent.FutureCancelledError)7 AssertionException (org.eclipse.scout.rt.platform.util.Assertions.AssertionException)5 ArrayList (java.util.ArrayList)4 ProcessingException (org.eclipse.scout.rt.platform.exception.ProcessingException)4 ClientRunContext (org.eclipse.scout.rt.client.context.ClientRunContext)3 PlatformException (org.eclipse.scout.rt.platform.exception.PlatformException)3 IBlockingCondition (org.eclipse.scout.rt.platform.job.IBlockingCondition)3 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 JMSException (javax.jms.JMSException)2 NamingException (javax.naming.NamingException)2 IClientSession (org.eclipse.scout.rt.client.IClientSession)2 IMessageBox (org.eclipse.scout.rt.client.ui.messagebox.IMessageBox)2 RunMonitor (org.eclipse.scout.rt.platform.context.RunMonitor)2 VetoException (org.eclipse.scout.rt.platform.exception.VetoException)2