public void run()

in src/core/src/main/java/org/apache/jmeter/threads/JMeterThread.java [259:347]


    public void run() {
        // threadContext is not thread-safe, so keep within thread
        JMeterContext threadContext = JMeterContextService.getContext();
        LoopIterationListener iterationListener = null;
        try {
            iterationListener = initRun(threadContext);
            while (running) {
                Sampler sam = threadGroupLoopController.next();
                while (running && sam != null) {
                    processSampler(sam, null, threadContext);
                    threadContext.cleanAfterSample();

                    boolean lastSampleOk = TRUE.equals(threadContext.getVariables().get(LAST_SAMPLE_OK));
                    // restart of the next loop
                    // - was requested through threadContext
                    // - or the last sample failed AND the onErrorStartNextLoop option is enabled
                    if (threadContext.getTestLogicalAction() != TestLogicalAction.CONTINUE
                            || (onErrorStartNextLoop && !lastSampleOk)) {
                        if (log.isDebugEnabled() && onErrorStartNextLoop
                                && threadContext.getTestLogicalAction() != TestLogicalAction.CONTINUE) {
                            log.debug("Start Next Thread Loop option is on, Last sample failed, starting next thread loop");
                        }
                        if(onErrorStartNextLoop && !lastSampleOk){
                            triggerLoopLogicalActionOnParentControllers(sam, threadContext, JMeterThread::continueOnThreadLoop);
                        } else {
                            switch (threadContext.getTestLogicalAction()) {
                                case BREAK_CURRENT_LOOP:
                                    triggerLoopLogicalActionOnParentControllers(sam, threadContext, JMeterThread::breakOnCurrentLoop);
                                    break;
                                case START_NEXT_ITERATION_OF_THREAD:
                                    triggerLoopLogicalActionOnParentControllers(sam, threadContext, JMeterThread::continueOnThreadLoop);
                                    break;
                                case START_NEXT_ITERATION_OF_CURRENT_LOOP:
                                    triggerLoopLogicalActionOnParentControllers(sam, threadContext, JMeterThread::continueOnCurrentLoop);
                                    break;
                                default:
                                    break;
                            }
                        }
                        threadContext.setTestLogicalAction(TestLogicalAction.CONTINUE);
                        sam = null;
                        setLastSampleOk(threadContext.getVariables(), true);
                    }
                    else {
                        sam = threadGroupLoopController.next();
                    }
                }

                // It would be possible to add finally for Thread Loop here
                if (threadGroupLoopController.isDone()) {
                    running = false;
                    log.info("Thread is done: {}", threadName);
                }
            }
        }
        // Might be found by controller.next()
        catch (JMeterStopTestException e) { // NOSONAR
            if (log.isInfoEnabled()) {
                log.info("Stopping Test: {}", e.toString());
            }
            shutdownTest();
        }
        catch (JMeterStopTestNowException e) { // NOSONAR
            if (log.isInfoEnabled()) {
                log.info("Stopping Test Now: {}", e.toString());
            }
            stopTestNow();
        } catch (JMeterStopThreadException e) { // NOSONAR
            if (log.isInfoEnabled()) {
                log.info("Stop Thread seen for thread {}, reason: {}", getThreadName(), e.toString());
            }
        } catch (Exception | JMeterError e) {
            log.error("Test failed!", e);
        } catch (ThreadDeath e) {
            throw e; // Must not ignore this one
        } finally {
            currentSamplerForInterruption = null; // prevent any further interrupts
            interruptLock.lock();  // make sure current interrupt is finished, prevent another starting yet
            try {
                threadContext.clear();
                log.info("Thread finished: {}", threadName);
                threadFinished(iterationListener);
                monitor.threadFinished(this); // Tell the monitor we are done
                JMeterContextService.removeContext(); // Remove the ThreadLocal entry
            } finally {
                interruptLock.unlock(); // Allow any pending interrupt to complete (OK because currentSampler == null)
            }
        }
    }