1
Feature requests / Re: Asynchronously transfer files via ftp
« on: October 26, 2017, 01:32:46 pm »
Sorry for necroing something a billion years old.
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.
Can be legally optimized by the compiler into
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
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));
}
{
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));
}
{
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