Is it possible for sf::Ftp to transfer(download/upload) files in a separate thread?
Something like this:
sf::Ftp ftp;
ftp.connect("ftp.server.com");
ftp.login("username","password");
ftp.startDownload("remotefile.txt", "local/path");
while(ftp.isTransfering())
std::cout<<"\rStatus: "<<ftp.getTransferPercentage()<<"%";
std::cout<<std::endl<<"Done."<<std::endl;
Since SFML 2 is still stuck at C++03, use sf::Thread please.
Ouch. I think that's one of the major reasons why nobody ever started working on it.
I just made&pushed a implementation using std::thread:
sf::Ftp::TransferState state;
server.downloadAsynced(filename, directory,sf::Ftp::Binary,state);
while (!state.isTransferCompleted())
std::printf("\r%.2f KB / Total %.2f KB", (float)state.getTransferedSize() / 1024.0f, (float)fileSize / 1024.0f);
std::printf("\nCompleted", (float)fileSize / 1024.0f, (float)fileSize / 1024.0f);
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 (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 (https://godbolt.org/g/33fuDe)