// to
// call StreamRecevier.waitForMessage(), and so also synchronises on
// that
// monitor. See bug 2936167.
final ScriptEngine scriptEngine = scriptEngineContainer
.getScriptEngine(m_initialisationMessage.getScript());
m_logger.info("Running \"{}\" using {}", m_initialisationMessage.getScript(),
scriptEngine.getDescription());
m_messagePump.start();
// Don't write out the data log header until now as the script may
// declare new statistics.
final StringBuilder dataLogHeader = new StringBuilder("Thread, Run, Test, Start time (ms since Epoch)");
final ExpressionView[] detailExpressionViews = m_statisticsServices.getDetailStatisticsView()
.getExpressionViews();
for (final ExpressionView detailExpressionView : detailExpressionViews) {
dataLogHeader.append(", ");
dataLogHeader.append(detailExpressionView.getDisplayName());
}
m_dataLogger.info(dataLogHeader.toString());
sendStatusMessage(ProcessReport.STATE_STARTED, (short) 0, numberOfThreads);
boolean threadRampUp = properties.getBoolean("grinder.threadRampUp", false);
final ThreadSynchronisation threadSynchronisation = threadRampUp ?
new ThreadRampUpEnabledThreadSynchronisation(m_eventSynchronisation, m_sleeper) :
new ThreadSynchronisation(m_eventSynchronisation);
m_terminalLogger.info("Starting threads");
synchronized (m_eventSynchronisation) {
m_threadStarter = new ThreadStarterImplementation(threadSynchronisation, scriptEngine);
for (int i = 0; i < numberOfThreads; i++) {
m_threadStarter.startThread(null);
}
}
threadSynchronisation.startThreads();
m_times.setExecutionStartTime();
m_logger.info("Start time is {} ms since Epoch", m_times.getExecutionStartTime());
final TimerTask reportTimerTask = new ReportToConsoleTimerTask(threadSynchronisation);
final TimerTask shutdownTimerTask = new ShutdownTimerTask();
// Schedule a regular statistics report to the console. We don't
// need to schedule this at a fixed rate. Each report contains the
// work done since the last report.
// First (empty) report to console to start it recording if its
// not already.
reportTimerTask.run();
final Timer timer = new Timer(true);
timer.schedule(reportTimerTask, reportToConsoleInterval, reportToConsoleInterval);
try {
if (duration > 0) {
m_terminalLogger.info("This test will shut down after {} ms", duration);
timer.schedule(shutdownTimerTask, duration);
}
// Wait for a termination event.
synchronized (m_eventSynchronisation) {
while (!threadSynchronisation.isFinished()) {
if (m_consoleListener.checkForMessage(ConsoleListener.ANY ^ ConsoleListener.START)) {
break;
}
if (m_shutdownTriggered) {
m_terminalLogger.info("Specified duration exceeded, Test is shut down");
break;
}
m_eventSynchronisation.waitNoInterrruptException();
}
}
synchronized (m_eventSynchronisation) {
if (!threadSynchronisation.isFinished()) {
m_terminalLogger.info("Waiting for threads to terminate");
m_threadStarter = m_invalidThreadStarter;
m_threadContexts.shutdownAll();
// Interrupt any sleepers.
SleeperImplementation.shutdownAllCurrentSleepers();
final long time = System.currentTimeMillis();
final long maximumShutdownTime = 10000;
while (!threadSynchronisation.isFinished()) {
if (System.currentTimeMillis() - time > maximumShutdownTime) {
m_terminalLogger.info("Ignoring unresponsive threads");
break;
}
m_eventSynchronisation.waitNoInterrruptException(maximumShutdownTime);
}
}
}
} finally {
reportTimerTask.cancel();
shutdownTimerTask.cancel();
}
scriptEngine.shutdown();
// Final report to the console.
reportTimerTask.run();
if (!m_communicationShutdown) {