I’m using a background thread to create a Path
based on some audio data, and am passing that Path
to the GUI thread via a Fifo built on AbstractFifo
. When I run as Standalone with Thread Sanitizer turned on, there are no data races. When I run as VST3 in Audio Plugin Host, I get lots of Data Races, centered around the Path::operator=
and Path(const Path& other)
functions:
I’ve created a PIP demonstrating the behavior:
FifoPIP.h (7.6 KB)
Does anyone have any idea where to even begin trying to solve this? @reuk was kind enough to put together a simple program checking out my PathFifo to see if that was problem, and it had no data races:
#include "../JuceLibraryCode/JuceHeader.h"
#include <array>
#include <future>
struct PathFifo final {
bool push(Path const &pathToClone) {
auto write = fifo.write(1);
if (write.blockSize1 >= 1) {
buffers[write.startIndex1] = pathToClone;
return true;
}
return false;
}
bool pull(Path &pathToFill) {
auto read = fifo.read(1);
if (read.blockSize1 >= 1) {
pathToFill = buffers[read.startIndex1];
return true;
}
return false;
}
private:
static constexpr int Capacity = 30;
std::array<Path, Capacity> buffers;
AbstractFifo fifo{Capacity};
};
int main(int argc, char *argv[]) {
std::promise<void> promise;
PathFifo fifo;
auto const writer =
std::async(std::launch::async, [&fifo, fut = promise.get_future()] {
while (fut.wait_for(std::chrono::seconds{0}) !=
std::future_status::ready) {
Path p;
p.startNewSubPath(rand(), rand());
p.lineTo(rand(), rand());
p.lineTo(rand(), rand());
p.closeSubPath();
fifo.push(std::move(p));
}
});
Path pulled;
for (auto i = 0; i != 1000000; ++i)
fifo.pull(pulled);
promise.set_value();
return 0;
}
I’m at a loss for what could be causing this, if it’s a bug in AudioPluginHost
, or AbstractFifo
or what…