added display of checking stage in GUI (at end of transfer). Gave names to the states in ftTransferModule. Added a flag for ForceCheck files (not functional yet)

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3274 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2010-07-09 21:04:29 +00:00
parent 36a9159884
commit fbd8a33db0
7 changed files with 119 additions and 49 deletions

View file

@ -1395,7 +1395,7 @@ bool ftController::FileCancel(std::string hash)
return true; return true;
} }
bool ftController::FileControl(std::string hash, uint32_t flags) bool ftController::FileControl(const std::string& hash, uint32_t flags)
{ {
//#ifdef CONTROL_DEBUG //#ifdef CONTROL_DEBUG
std::cerr << "ftController::FileControl(" << hash << ","; std::cerr << "ftController::FileControl(" << hash << ",";

View file

@ -70,7 +70,8 @@ class ftFileControl
COMPLETED = 1, COMPLETED = 1,
ERROR_COMPLETION = 2, ERROR_COMPLETION = 2,
QUEUED = 3, QUEUED = 3,
PAUSED = 4 PAUSED = 4,
CHECKING_HASH = 5
}; };
ftFileControl(); ftFileControl();
@ -150,7 +151,7 @@ class ftController: public CacheTransfer, public RsThread, public pqiMonitor, pu
void setFreeDiskSpaceLimit(uint32_t size_in_mb) ; void setFreeDiskSpaceLimit(uint32_t size_in_mb) ;
bool FileCancel(std::string hash); bool FileCancel(std::string hash);
bool FileControl(std::string hash, uint32_t flags); bool FileControl(const std::string& hash, uint32_t flags);
bool FileClearCompleted(); bool FileClearCompleted();
bool FlagFileComplete(std::string hash); bool FlagFileComplete(std::string hash);
bool getFileDownloadChunksDetails(const std::string& hash,FileChunksInfo& info); bool getFileDownloadChunksDetails(const std::string& hash,FileChunksInfo& info);

View file

@ -466,8 +466,12 @@ bool ftFileCreator::finished()
bool ftFileCreator::hashReceivedData(std::string& hash) bool ftFileCreator::hashReceivedData(std::string& hash)
{ {
RsStackMutex stack(ftcMutex) ; // csoler: No mutex here please !
//
// This is a bit dangerous, but otherwise we might stuck the GUI for a
// long time. Therefore, we must pay attention not to call this function
// at a time file_name nor hash can be modified, which is easy.
//
return RsDirUtil::hashFile(file_name,hash) ; return RsDirUtil::hashFile(file_name,hash) ;
} }

View file

@ -58,7 +58,10 @@ class ftFileCreator: public ftFileProvider
FileChunksInfo::ChunkStrategy getChunkStrategy() ; FileChunksInfo::ChunkStrategy getChunkStrategy() ;
// Computes a sha1sum of the partial file, to check that the data is overall consistent. // Computes a sha1sum of the partial file, to check that the data is overall consistent.
// // This function is not mutexed. This is a bit dangerous, but otherwise we might stuck the GUI for a
// long time. Therefore, we must pay attention not to call this function
// at a time file_name nor hash can be modified, which is quite easy.
bool hashReceivedData(std::string& hash) ; bool hashReceivedData(std::string& hash) ;
// Computes a CRC32 map of all chunks, for comparison with reference, and re-starting invalid chunks. // Computes a CRC32 map of all chunks, for comparison with reference, and re-starting invalid chunks.

View file

@ -27,6 +27,7 @@
* #define FT_DEBUG 1 * #define FT_DEBUG 1
*****/ *****/
#define FT_DEBUG 1
#include "fttransfermodule.h" #include "fttransfermodule.h"
/************************************************************************* /*************************************************************************
@ -58,9 +59,11 @@ const int32_t FT_TM_FAST_RTT = 1.0;
const int32_t FT_TM_STD_RTT = 5.0; const int32_t FT_TM_STD_RTT = 5.0;
const int32_t FT_TM_SLOW_RTT = 9.0; const int32_t FT_TM_SLOW_RTT = 9.0;
#define FT_TM_FLAG_DOWNLOADING 0 #define FT_TM_FLAG_DOWNLOADING 0
#define FT_TM_FLAG_CHECKING 3 #define FT_TM_FLAG_CANCELED 1
#define FT_TM_FLAG_CHECKING 3 #define FT_TM_FLAG_COMPLETE 2
#define FT_TM_FLAG_CHECKING 3
#define FT_TM_FLAG_CHUNK_CRC 4
ftTransferModule::ftTransferModule(ftFileCreator *fc, ftDataMultiplex *dm, ftController *c) ftTransferModule::ftTransferModule(ftFileCreator *fc, ftDataMultiplex *dm, ftController *c)
:mFileCreator(fc), mMultiplexor(dm), mFtController(c), mFlag(FT_TM_FLAG_DOWNLOADING) :mFileCreator(fc), mMultiplexor(dm), mFtController(c), mFlag(FT_TM_FLAG_DOWNLOADING)
@ -69,7 +72,9 @@ ftTransferModule::ftTransferModule(ftFileCreator *fc, ftDataMultiplex *dm, ftCon
mHash = mFileCreator->getHash(); mHash = mFileCreator->getHash();
mSize = mFileCreator->getFileSize(); mSize = mFileCreator->getFileSize();
mFileStatus.hash = mHash; mFileStatus.hash = mHash;
_hash_thread = NULL ;
// Dummy for Testing (should be handled independantly for // Dummy for Testing (should be handled independantly for
// each peer. // each peer.
@ -380,34 +385,36 @@ bool ftTransferModule::queryInactive()
{ {
/* NB: Not sure about this lock... might cause deadlock. /* NB: Not sure about this lock... might cause deadlock.
*/ */
RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ {
RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/
#ifdef FT_DEBUG #ifdef FT_DEBUG
std::cerr << "ftTransferModule::queryInactive()" << std::endl; std::cerr << "ftTransferModule::queryInactive()" << std::endl;
#endif #endif
if (mFileStatus.stat == ftFileStatus::PQIFILE_INIT) if (mFileStatus.stat == ftFileStatus::PQIFILE_INIT)
mFileStatus.stat = ftFileStatus::PQIFILE_DOWNLOADING; mFileStatus.stat = ftFileStatus::PQIFILE_DOWNLOADING;
if (mFileStatus.stat == ftFileStatus::PQIFILE_CHECKING) if (mFileStatus.stat == ftFileStatus::PQIFILE_CHECKING)
return false ; return false ;
if (mFileStatus.stat != ftFileStatus::PQIFILE_DOWNLOADING) if (mFileStatus.stat != ftFileStatus::PQIFILE_DOWNLOADING)
{ {
if (mFileStatus.stat == ftFileStatus::PQIFILE_FAIL_CANCEL) if (mFileStatus.stat == ftFileStatus::PQIFILE_FAIL_CANCEL)
mFlag = 2; //file canceled by user mFlag = FT_TM_FLAG_COMPLETE; //file canceled by user
return false; return false;
} }
std::map<std::string,peerInfo>::iterator mit; std::map<std::string,peerInfo>::iterator mit;
for(mit = mFileSources.begin(); mit != mFileSources.end(); mit++) for(mit = mFileSources.begin(); mit != mFileSources.end(); mit++)
{ {
locked_tickPeerTransfer(mit->second); locked_tickPeerTransfer(mit->second);
} }
if(mFileCreator->finished()) // transfer is complete if(mFileCreator->finished()) // transfer is complete
{ {
mFileStatus.stat = ftFileStatus::PQIFILE_CHECKING ; mFileStatus.stat = ftFileStatus::PQIFILE_CHECKING ;
mFlag = 3; mFlag = FT_TM_FLAG_CHECKING;
}
} }
return true; return true;
@ -471,20 +478,18 @@ int ftTransferModule::tick()
switch (flags) switch (flags)
{ {
case 0: //file transfer not complete case FT_TM_FLAG_DOWNLOADING: //file transfer not complete
adjustSpeed(); adjustSpeed();
break; break;
case 1: //file transfer complete case FT_TM_FLAG_COMPLETE: //file transfer complete
completeFileTransfer(); completeFileTransfer();
break; break;
case 2: //file transfer canceled case FT_TM_FLAG_CANCELED: //file transfer canceled
break; break;
case 3: case FT_TM_FLAG_CHECKING: // Check if file hash matches the hashed data
// Check if file hash matches the hashed data
checkFile() ; checkFile() ;
break ; break ;
case 4: case FT_TM_FLAG_CHUNK_CRC: // File is waiting for CRC32 map. Check if received, and re-set matched chunks
// File is waiting for CRC32 map. Check if received, and re-set matched chunks
checkCRC() ; checkCRC() ;
break ; break ;
default: default:
@ -497,8 +502,42 @@ int ftTransferModule::tick()
bool ftTransferModule::isCheckingHash() bool ftTransferModule::isCheckingHash()
{ {
RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/
return mFlag == 3 ; #ifdef FT_DEBUG
std::cerr << "isCheckingHash(): mFlag=" << mFlag << std::endl;
#endif
return mFlag == FT_TM_FLAG_CHECKING ;
} }
class HashThread: public RsThread
{
public:
HashThread(ftFileCreator *m)
: _m(m),_finished(false),_hash("") {}
virtual void run()
{
_m->hashReceivedData(_hash) ;
RsStackMutex stack(_hashThreadMtx) ;
_finished = true ;
}
std::string hash()
{
RsStackMutex stack(_hashThreadMtx) ;
return _hash ;
}
bool finished()
{
RsStackMutex stack(_hashThreadMtx) ;
return _finished ;
}
private:
RsMutex _hashThreadMtx ;
ftFileCreator *_m ;
bool _finished ;
std::string _hash ;
};
bool ftTransferModule::checkFile() bool ftTransferModule::checkFile()
{ {
{ {
@ -506,24 +545,42 @@ bool ftTransferModule::checkFile()
#ifdef FT_DEBUG #ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkFile(): checking File " << mHash << std::endl ; std::cerr << "ftTransferModule::checkFile(): checking File " << mHash << std::endl ;
#endif #endif
std::string hash_check ;
if(!mFileCreator->hashReceivedData(hash_check)) // if we don't have a hashing thread, create one.
if(_hash_thread == NULL)
{ {
std::cerr << "ftTransferModule::checkFile(): Impossible to hash received file " << mHash << " for check. What is happenning?" << std::endl ; // Note: using new is really important to avoid copy and write errors in the thread.
//
_hash_thread = new HashThread(mFileCreator) ;
_hash_thread->start() ;
#ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkFile(): launched hashing thread for file " << mHash << std::endl ;
#endif
return false ; return false ;
} }
if(hash_check == mHash) if(!_hash_thread->finished())
{ {
mFlag = 1 ; // Transfer is complete.
#ifdef FT_DEBUG #ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkFile(): File verification complete ! Setting mFlag to 1" << std::endl ; std::cerr << "ftTransferModule::checkFile(): file " << mHash << " is being hashed.?" << std::endl ;
#endif #endif
return false ;
}
if(_hash_thread->hash() == mHash)
{
mFlag = FT_TM_FLAG_COMPLETE ; // Transfer is complete.
#ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkFile(): hash finished. File verification complete ! Setting mFlag to 1" << std::endl ;
#endif
delete _hash_thread ;
_hash_thread = NULL ;
return true ; return true ;
} }
mFlag = 4 ; // Ask for CRC map. But for now, cancel file transfer. delete _hash_thread ;
mFlag = FT_TM_FLAG_CHUNK_CRC ; // Ask for CRC map. But for now, cancel file transfer.
mFileStatus.stat = ftFileStatus::PQIFILE_FAIL_CANCEL ; mFileStatus.stat = ftFileStatus::PQIFILE_FAIL_CANCEL ;
} }
cancelFileTransferUpward() ; cancelFileTransferUpward() ;
@ -547,7 +604,7 @@ bool ftTransferModule::checkCRC()
#endif #endif
mFileCreator->crossCheckChunkMap(_crc32map) ; mFileCreator->crossCheckChunkMap(_crc32map) ;
mFlag = 0 ; mFlag = FT_TM_FLAG_DOWNLOADING ;
#ifdef FT_DEBUG #ifdef FT_DEBUG
std::cerr << "ftTransferModule::checkCRC(): Done. Restarting download." << std::endl ; std::cerr << "ftTransferModule::checkCRC(): Done. Restarting download." << std::endl ;

View file

@ -51,6 +51,8 @@ const uint32_t PQIPEER_DOWNLOADING = 0x0002;
const uint32_t PQIPEER_IDLE = 0x0004; const uint32_t PQIPEER_IDLE = 0x0004;
const uint32_t PQIPEER_SUSPEND = 0x0010; const uint32_t PQIPEER_SUSPEND = 0x0010;
class HashThread ;
class peerInfo class peerInfo
{ {
public: public:
@ -190,6 +192,8 @@ private:
CRC32Map _crc32map ; CRC32Map _crc32map ;
ftFileStatus mFileStatus; //used for pause/resume file transfer ftFileStatus mFileStatus; //used for pause/resume file transfer
HashThread *_hash_thread ;
}; };
#endif //FT_TRANSFER_MODULE_HEADER #endif //FT_TRANSFER_MODULE_HEADER

View file

@ -39,8 +39,9 @@ extern RsFiles *rsFiles;
class Expression; class Expression;
/* These are used mainly by ftController at the moment */ /* These are used mainly by ftController at the moment */
const uint32_t RS_FILE_CTRL_PAUSE = 0x00000100; const uint32_t RS_FILE_CTRL_PAUSE = 0x00000100;
const uint32_t RS_FILE_CTRL_START = 0x00000200; const uint32_t RS_FILE_CTRL_START = 0x00000200;
const uint32_t RS_FILE_CTRL_FORCE_CHECK = 0x00000400;
const uint32_t RS_FILE_RATE_TRICKLE = 0x00000001; const uint32_t RS_FILE_RATE_TRICKLE = 0x00000001;
const uint32_t RS_FILE_RATE_SLOW = 0x00000002; const uint32_t RS_FILE_RATE_SLOW = 0x00000002;