I am having an issue where the render completes with no problem, but, more often than not, when I close the edit after rendering, my DAW crashes.
In DEBUG mode, it crashes less often, but it still occurs.
I get
Exception Thrown - Access Violation at line void CriticalSection::enter() const noexcept { EnterCriticalSection ((CRITICAL_SECTION*) lock); } in juce_win32_Threads.cpp.
I use the following code to initiate the render;
File renderFile{ File::getSpecialLocation(File::userDesktopDirectory).getNonexistentChildFile("render", ".wav") };
te::EditTimeRange range{ 0.0, (edit->getLength() + 1.0) };// add 1.0 seconds to render tail
juce::BigInteger tracksToDo{ 0 };
for (auto i = 0; i < te::getAllTracks(*edit).size(); i++)
tracksToDo.setBit(i);
if (te::Renderer::renderToFile("Render", renderFile, *edit, range, tracksToDo))
AlertWindow::showMessageBoxAsync(AlertWindow::InfoIcon, "Rendered", renderFile.getFullPathName());
else
AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Render", "Failed!");
And the behind the scenes code is;
void runTaskWithProgressBar(te::ThreadPoolJobWithProgress& t) override
{
double progress{ 0.0 };
TaskRunner runner(t, progress);
AlertWindow w("Rendering", {}, AlertWindow::NoIcon);
w.addProgressBarComponent(progress);
w.setVisible(true);
while (runner.isThreadRunning())
if (!MessageManager::getInstance()->runDispatchLoopUntil(10))
break;
}
//==============================================================================
struct TaskRunner : public Thread
{
TaskRunner(te::ThreadPoolJobWithProgress& t, double& prog ) :
Thread(t.getJobName()), task(t), progress(prog)
{
startThread();
}
~TaskRunner()
{
task.signalJobShouldExit();
waitForThreadToExit(10000);
}
void run() override
{
while (!threadShouldExit())
{
progress = task.getCurrentTaskProgress();
if (task.runJob() == ThreadPoolJob::jobHasFinished)
break;
}
}
te::ThreadPoolJobWithProgress& task;
double& progress;
};
Could it be that the render is not letting go of the thread? What are the best practices here?
I am also suspicious of the line,
waitForThreadToExit(10000);
, in the destructor for the TaskRunner class. That 10 second wait time seems very arbitrary. And, changing it to other values does not seem to make any difference. Perhaps there is a better way to handle the thread exit?
I am not a threading guru by any stretch of the imagination, so any pointers or suggestions are welcome?

