From: <arn...@us...> - 2008-02-03 19:16:43
|
Revision: 987 http://dcplusplus.svn.sourceforge.net/dcplusplus/?rev=987&view=rev Author: arnetheduck Date: 2008-02-03 11:16:41 -0800 (Sun, 03 Feb 2008) Log Message: ----------- Fixed various races, recover partially downloaded segments Modified Paths: -------------- dcplusplus/trunk/SConstruct dcplusplus/trunk/changelog.txt dcplusplus/trunk/dcpp/DownloadManager.cpp dcplusplus/trunk/dcpp/QueueManager.cpp dcplusplus/trunk/dcpp/TimerManager.cpp dcplusplus/trunk/dcpp/TimerManager.h dcplusplus/trunk/dcpp/User.cpp dcplusplus/trunk/dcpp/User.h Modified: dcplusplus/trunk/SConstruct =================================================================== --- dcplusplus/trunk/SConstruct 2008-02-03 16:11:52 UTC (rev 986) +++ dcplusplus/trunk/SConstruct 2008-02-03 19:16:41 UTC (rev 987) @@ -149,7 +149,7 @@ # internationalization (ardour.org provided the initial idea) # -po_args = ['msgmerge', '-q', '--update', '$TARGET', '$SOURCE'] +po_args = ['msgmerge', '-q', '--update', '--backup=none', '$TARGET', '$SOURCE'] po_bld = Builder (action = Action([po_args], 'Updating translation $TARGET from $SOURCES')) env.Append(BUILDERS = {'PoBuild' : po_bld}) Modified: dcplusplus/trunk/changelog.txt =================================================================== --- dcplusplus/trunk/changelog.txt 2008-02-03 16:11:52 UTC (rev 986) +++ dcplusplus/trunk/changelog.txt 2008-02-03 19:16:41 UTC (rev 987) @@ -21,7 +21,10 @@ * In waiting users, show requested chunk (since we can't know % done) * Fixed crash when download connection was disconnected before any data was received * Fixed crash due to race condition on idle check (thans bigmuscle) - +* Fixed crash when copying identity +* Fixed potential timer race condition (thanks bigmuscle) +* The good parts of partially downloaded segments are now added to queue (thanks bigmuscle) + -- 0.704 2007-12-14 -- * Hub lists added to utilize Coral's distributed network (ullner) * Use system header arrows on common controls 6+ (thanks poy) Modified: dcplusplus/trunk/dcpp/DownloadManager.cpp =================================================================== --- dcplusplus/trunk/dcpp/DownloadManager.cpp 2008-02-03 16:11:52 UTC (rev 986) +++ dcplusplus/trunk/dcpp/DownloadManager.cpp 2008-02-03 19:16:41 UTC (rev 987) @@ -112,42 +112,6 @@ } } -void QueueManager::FileMover::moveFile(const string& source, const string& target) { - Lock l(cs); - files.push_back(make_pair(source, target)); - if(!active) { - active = true; - start(); - } -} - -int QueueManager::FileMover::run() { - for(;;) { - FilePair next; - { - Lock l(cs); - if(files.empty()) { - active = false; - return 0; - } - next = files.back(); - files.pop_back(); - } - try { - File::renameFile(next.first, next.second); - } catch(const FileException&) { - try { - // Try to just rename it to the correct name at least - string newTarget = Util::getFilePath(next.first) + Util::getFileName(next.second); - File::renameFile(next.first, newTarget); - LogManager::getInstance()->message(str(F_("%1% renamed to %2%") % next.first % newTarget)); - } catch(const FileException& e) { - LogManager::getInstance()->message(str(F_("Unable to rename %1%: %2%") % next.first % e.getError())); - } - } - } -} - void DownloadManager::removeConnection(UserConnectionPtr aConn) { dcassert(aConn->getDownload() == NULL); aConn->removeListener(this); Modified: dcplusplus/trunk/dcpp/QueueManager.cpp =================================================================== --- dcplusplus/trunk/dcpp/QueueManager.cpp 2008-02-03 16:11:52 UTC (rev 986) +++ dcplusplus/trunk/dcpp/QueueManager.cpp 2008-02-03 19:16:41 UTC (rev 987) @@ -301,6 +301,42 @@ } } +void QueueManager::FileMover::moveFile(const string& source, const string& target) { + Lock l(cs); + files.push_back(make_pair(source, target)); + if(!active) { + active = true; + start(); + } +} + +int QueueManager::FileMover::run() { + for(;;) { + FilePair next; + { + Lock l(cs); + if(files.empty()) { + active = false; + return 0; + } + next = files.back(); + files.pop_back(); + } + try { + File::renameFile(next.first, next.second); + } catch(const FileException&) { + try { + // Try to just rename it to the correct name at least + string newTarget = Util::getFilePath(next.first) + Util::getFileName(next.second); + File::renameFile(next.first, newTarget); + LogManager::getInstance()->message(str(F_("%1% renamed to %2%") % next.first % newTarget)); + } catch(const FileException& e) { + LogManager::getInstance()->message(str(F_("Unable to rename %1%: %2%") % next.first % e.getError())); + } + } + } +} + QueueManager::QueueManager() : lastSave(0), queueFile(Util::getConfigPath() + "Queue.xml"), dirty(true), nextSearch(0) { TimerManager::getInstance()->addListener(this); SearchManager::getInstance()->addListener(this); @@ -921,6 +957,15 @@ // Blah...no use keeping an unfinished file list... File::deleteFile(q->getListName()); } + if(aDownload->getType() == Transfer::TYPE_FILE) { + // mark partially downloaded chunk, but align it to block size + int64_t downloaded = aDownload->getPos(); + downloaded -= downloaded % aDownload->getTigerTree().getBlockSize(); + + if(downloaded > 0) { + q->addSegment(Segment(aDownload->getStartPos(), downloaded)); + } + } } if(q->getPriority() != QueueItem::PAUSED) { Modified: dcplusplus/trunk/dcpp/TimerManager.cpp =================================================================== --- dcplusplus/trunk/dcpp/TimerManager.cpp 2008-02-03 16:11:52 UTC (rev 986) +++ dcplusplus/trunk/dcpp/TimerManager.cpp 2008-02-03 19:16:41 UTC (rev 987) @@ -26,6 +26,7 @@ #ifdef _WIN32 DWORD TimerManager::lastTick = 0; uint32_t TimerManager::cycles = 0; +FastCriticalSection TimerManager::cs; #else timeval TimerManager::tv; #endif @@ -52,6 +53,8 @@ uint64_t TimerManager::getTick() { #ifdef _WIN32 + FastLock l(cs); + DWORD tick = ::GetTickCount(); if(tick < lastTick) { cycles++; Modified: dcplusplus/trunk/dcpp/TimerManager.h =================================================================== --- dcplusplus/trunk/dcpp/TimerManager.h 2008-02-03 16:11:52 UTC (rev 986) +++ dcplusplus/trunk/dcpp/TimerManager.h 2008-02-03 19:16:41 UTC (rev 987) @@ -74,6 +74,7 @@ #ifdef _WIN32 static DWORD lastTick; static uint32_t cycles; + static FastCriticalSection cs; #else static timeval tv; #endif Modified: dcplusplus/trunk/dcpp/User.cpp =================================================================== --- dcplusplus/trunk/dcpp/User.cpp 2008-02-03 16:11:52 UTC (rev 986) +++ dcplusplus/trunk/dcpp/User.cpp 2008-02-03 19:16:41 UTC (rev 987) @@ -26,13 +26,15 @@ namespace dcpp { +FastCriticalSection Identity::cs; + OnlineUser::OnlineUser(const UserPtr& ptr, Client& client_, uint32_t sid_) : identity(ptr, sid_), client(client_) { } void Identity::getParams(StringMap& sm, const string& prefix, bool compatibility) const { { - Lock l(cs); + FastLock l(cs); for(InfMap::const_iterator i = info.begin(); i != info.end(); ++i) { sm[prefix + string((char*)(&i->first), 2)] = i->second; } @@ -76,13 +78,20 @@ } string Identity::get(const char* name) const { - Lock l(cs); + FastLock l(cs); InfMap::const_iterator i = info.find(*(short*)name); return i == info.end() ? Util::emptyString : i->second; } +bool Identity::isSet(const char* name) const { + FastLock l(cs); + InfMap::const_iterator i = info.find(*(short*)name); + return i != info.end(); +} + + void Identity::set(const char* name, const string& val) { - Lock l(cs); + FastLock l(cs); if(val.empty()) info.erase(*(short*)name); else @@ -90,7 +99,7 @@ } bool Identity::supports(const string& name) const { - const string& su = get("SU"); + string su = get("SU"); StringTokenizer<string> st(su, ','); for(StringIter i = st.getTokens().begin(); i != st.getTokens().end(); ++i) { if(*i == name) Modified: dcplusplus/trunk/dcpp/User.h =================================================================== --- dcplusplus/trunk/dcpp/User.h 2008-02-03 16:11:52 UTC (rev 986) +++ dcplusplus/trunk/dcpp/User.h 2008-02-03 19:16:41 UTC (rev 987) @@ -103,8 +103,8 @@ Identity() : sid(0) { } Identity(const UserPtr& ptr, uint32_t aSID) : user(ptr), sid(aSID) { } - Identity(const Identity& rhs) : Flags(rhs), user(rhs.user), sid(rhs.sid), info(rhs.info) { } - Identity& operator=(const Identity& rhs) { Lock l(cs); *static_cast<Flags*>(this) = rhs; user = rhs.user; sid = rhs.sid; info = rhs.info; return *this; } + Identity(const Identity& rhs) : Flags(), sid(0) { *this = rhs; } // Use operator= since we have to lock before reading... + Identity& operator=(const Identity& rhs) { FastLock l(cs); *static_cast<Flags*>(this) = rhs; user = rhs.user; sid = rhs.sid; info = rhs.info; return *this; } #define GS(n, x) string get##n() const { return get(x); } void set##n(const string& v) { set(x, v); } GS(Nick, "NI") @@ -123,16 +123,17 @@ void setHidden(bool hidden) { set("HI", hidden ? "1" : Util::emptyString); } string getTag() const; bool supports(const string& name) const; - bool isHub() const { return isClientType(CT_HUB) || !get("HU").empty(); } - bool isOp() const { return isClientType(CT_OP) || isClientType(CT_SU) || isClientType(CT_OWNER) || !get("OP").empty(); } - bool isRegistered() const { return isClientType(CT_REGGED) || !get("RG").empty(); } - bool isHidden() const { return !get("HI").empty(); } - bool isBot() const { return isClientType(CT_BOT) || !get("BO").empty(); } - bool isAway() const { return !get("AW").empty(); } + bool isHub() const { return isClientType(CT_HUB) || isSet("HU"); } + bool isOp() const { return isClientType(CT_OP) || isClientType(CT_SU) || isClientType(CT_OWNER) || isSet("OP"); } + bool isRegistered() const { return isClientType(CT_REGGED) || isSet("RG"); } + bool isHidden() const { return isSet("HI"); } + bool isBot() const { return isClientType(CT_BOT) || isSet("BO"); } + bool isAway() const { return isSet("AW"); } bool isTcpActive() const { return !getIp().empty() || (user->isSet(User::NMDC) && !user->isSet(User::PASSIVE)); } bool isUdpActive() const { return !getIp().empty() && !getUdpPort().empty(); } string get(const char* name) const; void set(const char* name, const string& val); + bool isSet(const char* name) const; string getSIDString() const { return string((const char*)&sid, 4); } bool isClientType(ClientType ct) const; @@ -145,8 +146,8 @@ typedef std::tr1::unordered_map<short, string> InfMap; typedef InfMap::iterator InfIter; InfMap info; - /** @todo there are probably more threading issues here ...*/ - mutable CriticalSection cs; + + static FastCriticalSection cs; }; class Client; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |