|
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.
|