Sorry for necroing something a billion years old.
I think this is thread safe, for only one thread would write data at once, and there's only one primitive data object (thus one memory block). The other threads are only reading the data, so there should be no problem with thread safety.
Writing and reading at the same time
is a data race, and it's UB. There is no way around having atomics for flags, and that probably means relying on non-standard sources for them before C++11.
Looking at
https://github.com/Edgaru089/SFML/blob/master/src/SFML/Network/Ftp.cpp.
void Ftp::downloadAsynced(const std::string & remoteFile, const std::string& localPath, TransferMode mode, TransferState& state)
{
std::thread downloadThread(&Ftp::download, this, remoteFile, localPath, mode, std::ref(state));
downloadThread.detach();
// Wait until the transfer has started
while(state.isTransferCompleted())
sleep(milliseconds(5));
}
Can be legally optimized by the compiler into
void Ftp::downloadAsynced(const std::string & remoteFile, const std::string& localPath, TransferMode mode, TransferState& state)
{
std::thread downloadThread(&Ftp::download, this, remoteFile, localPath, mode, std::ref(state));
downloadThread.detach();
// isTransferCompleted has no optimization barriers in it
if(state.isTransferCompleted())
while(true)
sleep(milliseconds(5));
}
This isn't all data races can do to wreak your program, don't do it.
PS:
gcc 7.2 does indeed make that optimization under O2