From c22799b9967201b41b981e0f259896709ecbbcbf Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 12 Mar 2010 19:39:23 +0000 Subject: [PATCH] moved removal of sources off turtle mutex to avoid cross-lock. Added a closeFile() call when moving files out of the queue git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@2523 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/ft/ftcontroller.cc | 6 ++++++ libretroshare/src/turtle/p3turtle.cc | 32 +++++++++++++++++++++++----- libretroshare/src/turtle/p3turtle.h | 7 ++++-- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/libretroshare/src/ft/ftcontroller.cc b/libretroshare/src/ft/ftcontroller.cc index 28c7c2f77..19c009ba1 100644 --- a/libretroshare/src/ft/ftcontroller.cc +++ b/libretroshare/src/ft/ftcontroller.cc @@ -550,12 +550,18 @@ void ftController::locked_checkQueueElement(uint32_t pos) if(pos < _max_active_downloads) { _queue[pos]->mState = ftFileControl::DOWNLOADING ; + + if(_queue[pos]->mFlags & RS_FILE_HINTS_NETWORK_WIDE) + mTurtle->monitorFileTunnels(_queue[pos]->mName,_queue[pos]->mHash,_queue[pos]->mSize) ; } if(pos >= _max_active_downloads && _queue[pos]->mState != ftFileControl::QUEUED) { _queue[pos]->mState = ftFileControl::QUEUED ; _queue[pos]->mCreator->closeFile() ; + + if(_queue[pos]->mFlags & RS_FILE_HINTS_NETWORK_WIDE) + mTurtle->stopMonitoringFileTunnels(_queue[pos]->mHash) ; } } diff --git a/libretroshare/src/turtle/p3turtle.cc b/libretroshare/src/turtle/p3turtle.cc index a16d2890d..c025c9f05 100644 --- a/libretroshare/src/turtle/p3turtle.cc +++ b/libretroshare/src/turtle/p3turtle.cc @@ -238,6 +238,9 @@ void p3turtle::autoWash() #endif // Remove hashes that are marked as such. // + + std::vector > peers_to_remove ; + { RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ @@ -270,7 +273,7 @@ void p3turtle::autoWash() std::cerr << ")" << std::endl ; #endif for(unsigned int k=0;kfirst) ; } for(unsigned int i=0;iremoveFileSource(peers_to_remove[i].first,peers_to_remove[i].second) ; + } -void p3turtle::locked_closeTunnel(TurtleTunnelId tid) +void p3turtle::locked_closeTunnel(TurtleTunnelId tid,std::vector >& sources_to_remove) { // This is closing a given tunnel, removing it from file sources, and from the list of tunnels of its // corresponding file hash. In the original turtle4privacy paradigm, they also send back and forward @@ -378,7 +386,7 @@ void p3turtle::locked_closeTunnel(TurtleTunnelId tid) std::cerr << " Virtual Peer Id " << vpid << std::endl ; std::cerr << " Associated file source." << std::endl ; #endif - _ft_controller->removeFileSource(hash,vpid) ; + sources_to_remove.push_back(std::pair(hash,vpid)) ; // Let's be cautious. Normally we should never be here without consistent information, // but still, this happens, rarely. @@ -1677,6 +1685,20 @@ void p3turtle::monitorFileTunnels(const std::string& name,const std::string& fil { RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ + // First, check if the hash is tagged for removal (there's a delay) + + for(uint i=0;i<_hashes_to_remove.size();++i) + if(_hashes_to_remove[i] == file_hash) + { + _hashes_to_remove[i] = _hashes_to_remove.back() ; + _hashes_to_remove.pop_back() ; +#ifdef P3TURTLE_DEBUG + std::cerr << "p3turtle: File hash " << file_hash << " Was scheduled for removal. Canceling the removal." << std::endl ; +#endif + } + + // Then, check if the hash is already there + // if(_incoming_file_hashes.find(file_hash) != _incoming_file_hashes.end()) // download already asked. { #ifdef P3TURTLE_DEBUG @@ -1730,7 +1752,7 @@ static std::string printNumber(uint64_t num,bool hex=false) if(num < (((uint64_t)1)<<32)) sprintf(tmp,"%08x", uint32_t(num)) ; else - sprintf(tmp,"%08x%08x", uint32_t(num >> 32),uint32_t(num & ( (1<<32)-1 ))) ; + sprintf(tmp,"%08x%08x", uint32_t(num >> 32),uint32_t(num & ( (((uint64_t)1)<<32)-1 ))) ; return std::string(tmp) ; } else diff --git a/libretroshare/src/turtle/p3turtle.h b/libretroshare/src/turtle/p3turtle.h index 05a7c870c..f51c59db4 100644 --- a/libretroshare/src/turtle/p3turtle.h +++ b/libretroshare/src/turtle/p3turtle.h @@ -311,8 +311,11 @@ class p3turtle: public p3Service, public pqiMonitor, public RsTurtle,/* public f /// Handle tunnel digging for current file hashes void manageTunnels() ; - /// closes a given tunnel. Should be called with mutex set. - void locked_closeTunnel(TurtleTunnelId tid) ; + /// Closes a given tunnel. Should be called with mutex set. + /// The hashes and peers to remove (by calling + /// ftController::removeFileSource() are happended to the supplied vector + /// so that they can be removed off the turtle mutex. + void locked_closeTunnel(TurtleTunnelId tid,std::vector >& peers_to_remove) ; /// Main routing function int handleIncoming();