← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2226: Various fixes

 

Merge authors:
  Gennady Proskurin (gpr)
  Jacek Sieka (arnetheduck)
------------------------------------------------------------
revno: 2226 [merge]
committer: Jacek Sieka <arnetheduck@xxxxxxxxx>
branch nick: trunk
timestamp: Wed 2010-09-01 20:45:01 +0800
message:
  Various fixes
modified:
  changelog.txt
  dcpp/AdcHub.cpp
  dcpp/BufferedSocket.cpp
  dcpp/BufferedSocket.h
  dcpp/Client.cpp
  dcpp/Client.h
  dcpp/NmdcHub.cpp
  dcpp/Pointer.h
  dcpp/QueueManager.cpp
  dcpp/QueueManager.h
  dcpp/SFVReader.cpp
  dcpp/Semaphore.h
  dcpp/ShareManager.cpp
  dcpp/ShareManager.h
  dcpp/Thread.cpp
  dcpp/Thread.h
  dcpp/ThrottleManager.cpp
  dcpp/Util.h
  win32/AboutDlg.cpp
  win32/QueueFrame.cpp


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'changelog.txt'
--- changelog.txt	2010-08-29 17:23:20 +0000
+++ changelog.txt	2010-08-30 14:04:10 +0000
@@ -14,6 +14,10 @@
 * New icons
 * Update the links in the "Help" menu (poy)
 * Prevent current-directory Windows DLL injection (cologic)
+* [L#617021] Fix linux semaphore (thanks gennady proskurin)
+* [L#617591] Fix multi-core/cpu issue with ref-counting (thanks gennady proskurin)
+* Fix some counters that could have caused issues when running dc++ for a long time
+* [L#617517] More portable critical sections (thanks big muscle)
 
 -- 0.770 2010-07-05 --
 * [L#550300] Catch more potential file corruptions (thanks bigmuscle)

=== modified file 'dcpp/AdcHub.cpp'
--- dcpp/AdcHub.cpp	2010-08-27 13:47:33 +0000
+++ dcpp/AdcHub.cpp	2010-08-30 14:04:10 +0000
@@ -812,9 +812,9 @@
 	addParam(lastInfoMap, c, "SS", ShareManager::getInstance()->getShareSizeString());
 	addParam(lastInfoMap, c, "SF", Util::toString(ShareManager::getInstance()->getSharedFiles()));
 	addParam(lastInfoMap, c, "EM", SETTING(EMAIL));
-	addParam(lastInfoMap, c, "HN", Util::toString(counts.normal));
-	addParam(lastInfoMap, c, "HR", Util::toString(counts.registered));
-	addParam(lastInfoMap, c, "HO", Util::toString(counts.op));
+	addParam(lastInfoMap, c, "HN", Util::toString(counts[COUNT_NORMAL]));
+	addParam(lastInfoMap, c, "HR", Util::toString(counts[COUNT_REGISTERED]));
+	addParam(lastInfoMap, c, "HO", Util::toString(counts[COUNT_OP]));
 	addParam(lastInfoMap, c, "VE", "++ " VERSIONSTRING);
 	addParam(lastInfoMap, c, "AW", Util::getAway() ? "1" : Util::emptyString);
 

=== modified file 'dcpp/BufferedSocket.cpp'
--- dcpp/BufferedSocket.cpp	2010-07-10 14:36:48 +0000
+++ dcpp/BufferedSocket.cpp	2010-08-30 14:04:10 +0000
@@ -42,13 +42,13 @@
 {
 	start();
 
-	Thread::safeInc(sockets);
+	++sockets;
 }
 
-volatile long BufferedSocket::sockets = 0;
+atomic<long> BufferedSocket::sockets(0);
 
 BufferedSocket::~BufferedSocket() throw() {
-	Thread::safeDec(sockets);
+	--sockets;
 }
 
 void BufferedSocket::setMode (Modes aMode, size_t aRollback) {
@@ -420,7 +420,7 @@
 
 bool BufferedSocket::checkEvents() throw(Exception) {
 	while(state == RUNNING ? taskSem.wait(0) : taskSem.wait()) {
-		pair<Tasks, boost::shared_ptr<TaskData> > p;
+		pair<Tasks, shared_ptr<TaskData> > p;
 		{
 			Lock l(cs);
 			dcassert(tasks.size() > 0);

=== modified file 'dcpp/BufferedSocket.h'
--- dcpp/BufferedSocket.h	2010-07-10 14:36:48 +0000
+++ dcpp/BufferedSocket.h	2010-08-30 14:04:10 +0000
@@ -26,6 +26,7 @@
 #include "Speaker.h"
 #include "Util.h"
 #include "Socket.h"
+#include <atomic>
 
 namespace dcpp {
 
@@ -60,7 +61,7 @@
 	}
 
 	static void waitShutdown() {
-		while(sockets)
+		while(sockets > 0)
 			Thread::sleep(100);
 	}
 
@@ -139,7 +140,7 @@
 	CriticalSection cs;
 
 	Semaphore taskSem;
-	deque<pair<Tasks, boost::shared_ptr<TaskData> > > tasks;
+	deque<pair<Tasks, shared_ptr<TaskData> > > tasks;
 
 	Modes mode;
 	std::unique_ptr<UnZFilter> filterIn;
@@ -163,7 +164,7 @@
 	void threadSendData() throw(Exception);
 
 	void fail(const string& aError);
-	static volatile long sockets;
+	static atomic<long> sockets;
 
 	bool checkEvents() throw(Exception);
 	void checkSocket() throw(Exception);

=== modified file 'dcpp/Client.cpp'
--- dcpp/Client.cpp	2010-08-27 13:47:33 +0000
+++ dcpp/Client.cpp	2010-08-30 14:04:10 +0000
@@ -29,7 +29,7 @@
 
 namespace dcpp {
 
-Client::Counts Client::counts;
+atomic<long> Client::counts[COUNT_UNCOUNTED];
 
 Client::Client(const string& hubURL, char separator_, bool secure_) :
 	myIdentity(ClientManager::getInstance()->getMe(), 0),
@@ -157,27 +157,20 @@
 
 void Client::updateCounts(bool aRemove) {
 	// We always remove the count and then add the correct one if requested...
-	if(countType == COUNT_NORMAL) {
-		Thread::safeDec(counts.normal);
-	} else if(countType == COUNT_REGISTERED) {
-		Thread::safeDec(counts.registered);
-	} else if(countType == COUNT_OP) {
-		Thread::safeDec(counts.op);
+	if(countType != COUNT_UNCOUNTED) {
+		--counts[countType];
+		countType = COUNT_UNCOUNTED;
 	}
 
-	countType = COUNT_UNCOUNTED;
-
 	if(!aRemove) {
 		if(getMyIdentity().isOp()) {
-			Thread::safeInc(counts.op);
 			countType = COUNT_OP;
 		} else if(getMyIdentity().isRegistered()) {
-			Thread::safeInc(counts.registered);
 			countType = COUNT_REGISTERED;
 		} else {
-			Thread::safeInc(counts.normal);
 			countType = COUNT_NORMAL;
 		}
+		++counts[countType];
 	}
 }
 

=== modified file 'dcpp/Client.h'
--- dcpp/Client.h	2010-08-27 13:47:33 +0000
+++ dcpp/Client.h	2010-08-30 14:04:10 +0000
@@ -27,6 +27,8 @@
 #include "TimerManager.h"
 #include "ClientListener.h"
 
+#include <atomic>
+
 namespace dcpp {
 
 /** Yes, this should probably be called a Hub */
@@ -72,7 +74,8 @@
 
 	static string getCounts() {
 		char buf[128];
-		return string(buf, snprintf(buf, sizeof(buf), "%ld/%ld/%ld", counts.normal, counts.registered, counts.op));
+		return string(buf, snprintf(buf, sizeof(buf), "%ld/%ld/%ld",
+				counts[COUNT_NORMAL].load(), counts[COUNT_REGISTERED].load(), counts[COUNT_OP].load()));
 	}
 
 	StringMap& escapeParams(StringMap& sm) {
@@ -112,14 +115,16 @@
 	friend class ClientManager;
 	Client(const string& hubURL, char separator, bool secure_);
 	virtual ~Client() throw();
-	struct Counts {
-		Counts(long n = 0, long r = 0, long o = 0) : normal(n), registered(r), op(o) { }
-		volatile long normal;
-		volatile long registered;
-		volatile long op;
-		bool operator !=(const Counts& rhs) { return normal != rhs.normal || registered != rhs.registered || op != rhs.op; }
+
+	enum CountType {
+		COUNT_NORMAL,
+		COUNT_REGISTERED,
+		COUNT_OP,
+		COUNT_UNCOUNTED,
 	};
 
+	static atomic<long> counts[COUNT_UNCOUNTED];
+
 	enum States {
 		STATE_CONNECTING,	///< Waiting for socket to connect
 		STATE_PROTOCOL,		///< Protocol setup
@@ -131,9 +136,6 @@
 
 	BufferedSocket* sock;
 
-	static Counts counts;
-	Counts lastCounts;
-
 	void updateCounts(bool aRemove);
 	void updateActivity() { lastActivity = GET_TICK(); }
 
@@ -152,13 +154,6 @@
 
 private:
 
-	enum CountType {
-		COUNT_UNCOUNTED,
-		COUNT_NORMAL,
-		COUNT_REGISTERED,
-		COUNT_OP
-	};
-
 	Client(const Client&);
 	Client& operator=(const Client&);
 

=== modified file 'dcpp/NmdcHub.cpp'
--- dcpp/NmdcHub.cpp	2010-08-27 13:47:33 +0000
+++ dcpp/NmdcHub.cpp	2010-08-30 14:04:10 +0000
@@ -780,8 +780,6 @@
 
 	reloadSettings(false);
 
-	lastCounts = counts;
-
 	string tmp1 = ";**\x1fU9";
 	string tmp2 = "+L9";
 	string tmp3 = "+G9";

=== modified file 'dcpp/Pointer.h'
--- dcpp/Pointer.h	2010-02-11 21:44:13 +0000
+++ dcpp/Pointer.h	2010-08-17 18:06:22 +0000
@@ -20,7 +20,7 @@
 #define DCPLUSPLUS_DCPP_POINTER_H
 
 #include <boost/intrusive_ptr.hpp>
-#include "Thread.h"
+#include <boost/smart_ptr/detail/atomic_count.hpp>
 
 namespace dcpp {
 
@@ -36,10 +36,10 @@
 	intrusive_ptr_base() throw() : ref(0) { }
 
 private:
-	friend void intrusive_ptr_add_ref(intrusive_ptr_base* p) { Thread::safeInc(p->ref); }
-	friend void intrusive_ptr_release(intrusive_ptr_base* p) { if(Thread::safeDec(p->ref) == 0) { delete static_cast<T*>(p); } }
+	friend void intrusive_ptr_add_ref(intrusive_ptr_base* p) { ++p->ref; }
+	friend void intrusive_ptr_release(intrusive_ptr_base* p) { if(--p->ref == 0) { delete static_cast<T*>(p); } }
 
-	volatile long ref;
+	boost::detail::atomic_count ref;
 };
 
 

=== modified file 'dcpp/QueueManager.cpp'
--- dcpp/QueueManager.cpp	2010-08-27 13:47:33 +0000
+++ dcpp/QueueManager.cpp	2010-08-31 13:29:04 +0000
@@ -884,6 +884,14 @@
 	}
 }
 
+void QueueManager::addListener(QueueManagerListener* ql, const function<void (const QueueItem::StringMap&)>& currentQueue) {
+	Lock l(cs);
+	Speaker<QueueManagerListener>::addListener(ql);
+	if(currentQueue) {
+		currentQueue(fileQueue.getQueue());
+	}
+}
+
 Download* QueueManager::getDownload(UserConnection& aSource, bool supportsTrees) throw() {
 	Lock l(cs);
 

=== modified file 'dcpp/QueueManager.h'
--- dcpp/QueueManager.h	2010-08-27 13:47:33 +0000
+++ dcpp/QueueManager.h	2010-08-31 13:29:04 +0000
@@ -102,8 +102,9 @@
 	void setPriority(const string& aTarget, QueueItem::Priority p) throw();
 
 	void getTargets(const TTHValue& tth, StringList& sl);
-	QueueItem::StringMap& lockQueue() throw() { cs.lock(); return fileQueue.getQueue(); } ;
-	void unlockQueue() throw() { cs.unlock(); }
+
+	using Speaker<QueueManagerListener>::addListener;
+	void addListener(QueueManagerListener* l, const function<void(const QueueItem::StringMap&)>& currentQueue);
 
 	Download* getDownload(UserConnection& aSource, bool supportsTrees) throw();
 	void putDownload(Download* aDownload, bool finished) throw();

=== modified file 'dcpp/SFVReader.cpp'
--- dcpp/SFVReader.cpp	2010-02-11 21:44:13 +0000
+++ dcpp/SFVReader.cpp	2010-08-30 14:01:53 +0000
@@ -24,7 +24,6 @@
 #include "StringTokenizer.h"
 
 #ifndef _WIN32
-#include <sys/types.h>
 #include <dirent.h>
 #include <fnmatch.h>
 #endif

=== modified file 'dcpp/Semaphore.h'
--- dcpp/Semaphore.h	2010-02-11 21:44:13 +0000
+++ dcpp/Semaphore.h	2010-08-17 17:20:10 +0000
@@ -59,7 +59,7 @@
 
 	bool wait() throw() {
 		Lock l(cs);
-		if(count == 0) {
+		while (count == 0) {
 			pthread_cond_wait(&cond, &cs.getMutex());
 		}
 		count--;
@@ -74,7 +74,10 @@
 			millis+=timev.tv_usec/1000;
 			t.tv_sec = timev.tv_sec + (millis/1000);
 			t.tv_nsec = (millis%1000)*1000*1000;
-			int ret = pthread_cond_timedwait(&cond, &cs.getMutex(), &t);
+			int ret;
+			do {
+				ret = pthread_cond_timedwait(&cond, &cs.getMutex(), &t);
+			} while (ret==0 && count==0);
 			if(ret != 0) {
 				return false;
 			}

=== modified file 'dcpp/ShareManager.cpp'
--- dcpp/ShareManager.cpp	2010-08-27 13:47:33 +0000
+++ dcpp/ShareManager.cpp	2010-08-30 14:04:10 +0000
@@ -40,7 +40,6 @@
 #include "version.h"
 
 #ifndef _WIN32
-#include <sys/types.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -52,7 +51,7 @@
 namespace dcpp {
 
 ShareManager::ShareManager() : hits(0), xmlListLen(0), bzXmlListLen(0),
-	xmlDirty(true), forceXmlRefresh(false), refreshDirs(false), update(false), initial(true), listN(0), refreshing(0),
+	xmlDirty(true), forceXmlRefresh(false), refreshDirs(false), update(false), initial(true), listN(0), refreshing(false),
 	lastXmlUpdate(0), lastFullUpdate(GET_TICK()), bloom(1<<20)
 {
 	SettingsManager::getInstance()->addListener(this);
@@ -723,7 +722,7 @@
 }
 
 void ShareManager::refresh(bool dirs /* = false */, bool aUpdate /* = true */, bool block /* = false */) throw() {
-	if(Thread::safeExchange(refreshing, 1) == 1) {
+	if(refreshing.test_and_set()) {
 		LogManager::getInstance()->message(_("File list refresh in progress, please wait for it to finish before trying to refresh again"));
 		return;
 	}
@@ -798,7 +797,8 @@
 	if(update) {
 		ClientManager::getInstance()->infoUpdated();
 	}
-	refreshing = 0;
+
+	refreshing.clear();
 	return 0;
 }
 

=== modified file 'dcpp/ShareManager.h'
--- dcpp/ShareManager.h	2010-08-27 13:47:33 +0000
+++ dcpp/ShareManager.h	2010-08-30 14:04:10 +0000
@@ -34,6 +34,8 @@
 #include "MerkleTree.h"
 #include "Pointer.h"
 
+#include <atomic>
+
 namespace dcpp {
 
 STANDARD_EXCEPTION(ShareException);
@@ -251,7 +253,7 @@
 
 	int listN;
 
-	volatile long refreshing;
+	atomic_flag refreshing;
 
 	uint64_t lastXmlUpdate;
 	uint64_t lastFullUpdate;

=== modified file 'dcpp/Thread.cpp'
--- dcpp/Thread.cpp	2010-02-11 21:44:13 +0000
+++ dcpp/Thread.cpp	2010-08-30 14:04:10 +0000
@@ -23,10 +23,6 @@
 
 namespace dcpp {
 
-#ifndef _WIN32
-pthread_mutex_t Thread::mtx = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
 #ifdef _WIN32
 void Thread::start() throw(ThreadException) {
 	join();

=== modified file 'dcpp/Thread.h'
--- dcpp/Thread.h	2010-04-23 18:32:11 +0000
+++ dcpp/Thread.h	2010-08-30 14:04:10 +0000
@@ -64,17 +64,6 @@
 	static void sleep(uint32_t millis) { ::Sleep(millis); }
 	static void yield() { ::Sleep(0); }
 
-#ifdef __MINGW32__
-	static long safeInc(volatile long& v) { return InterlockedIncrement((long*)&v); }
-	static long safeDec(volatile long& v) { return InterlockedDecrement((long*)&v); }
-	static long safeExchange(volatile long& target, long value) { return InterlockedExchange((long*)&target, value); }
-
-#else
-	static long safeInc(volatile long& v) { return InterlockedIncrement(&v); }
-	static long safeDec(volatile long& v) { return InterlockedDecrement(&v); }
-	static long safeExchange(volatile long& target, long value) { return InterlockedExchange(&target, value); }
-#endif
-
 #else
 
 	enum Priority {
@@ -100,25 +89,6 @@
 	void setThreadPriority(Priority p) { setpriority(PRIO_PROCESS, 0, p); }
 	static void sleep(uint32_t millis) { ::usleep(millis*1000); }
 	static void yield() { ::sched_yield(); }
-	static long safeInc(volatile long& v) {
-		pthread_mutex_lock(&mtx);
-		long ret = ++v;
-		pthread_mutex_unlock(&mtx);
-		return ret;
-	}
-	static long safeDec(volatile long& v) {
-		pthread_mutex_lock(&mtx);
-		long ret = --v;
-		pthread_mutex_unlock(&mtx);
-		return ret;
-	}
-	static long safeExchange(volatile long& target, long value) {
-		pthread_mutex_lock(&mtx);
-		long ret = target;
-		target = value;
-		pthread_mutex_unlock(&mtx);
-		return ret;
-	}
 #endif
 
 protected:
@@ -133,7 +103,6 @@
 		return 0;
 	}
 #else
-	static pthread_mutex_t mtx;
 	pthread_t threadHandle;
 	static void* starter(void* p) {
 		Thread* t = (Thread*)p;

=== modified file 'dcpp/ThrottleManager.cpp'
--- dcpp/ThrottleManager.cpp	2010-08-27 13:47:33 +0000
+++ dcpp/ThrottleManager.cpp	2010-08-30 14:04:10 +0000
@@ -228,7 +228,7 @@
 
 		dcassert(activeWaiter == 0 || activeWaiter == 1);
 		waitCS[1-activeWaiter].lock();
-		Thread::safeExchange(activeWaiter, 1-activeWaiter);
+		activeWaiter = 1-activeWaiter;
 		waitCS[1-activeWaiter].unlock();
 	}
 }

=== modified file 'dcpp/Util.h'
--- dcpp/Util.h	2010-08-13 03:13:16 +0000
+++ dcpp/Util.h	2010-08-30 14:01:53 +0000
@@ -21,7 +21,6 @@
 
 #ifndef _WIN32
 #include <sys/stat.h>
-#include <sys/types.h>
 #include <unistd.h>
 #include <stdlib.h>
 #endif

=== modified file 'win32/AboutDlg.cpp'
--- win32/AboutDlg.cpp	2010-08-07 15:20:27 +0000
+++ win32/AboutDlg.cpp	2010-08-30 14:04:10 +0000
@@ -45,8 +45,8 @@
 "krzysztof tyszecki, poison, mikejj, pur, bigmuscle, martin, jove, bart vullings, "
 "steven sheehy, tobias nygren, poy, dorian, stephan hohe, mafa_45, mikael eman, james ross, "
 "stanislav maslovski, david grundberg, pavel andreev, yakov suraev, kulmegil, smir, emtee, individ, "
-"pseudonym, crise, ben, ximin luo, radox, razzloss, andrew browne, darkklor, vasily.n, netcelli. "
-"Keep it coming!";
+"pseudonym, crise, ben, ximin luo, radox, razzloss, andrew browne, darkklor, vasily.n, netcelli, "
+"gennady proskurin. Keep it coming!";
 
 AboutDlg::AboutDlg(dwt::Widget* parent) :
 dwt::ModalDialog(parent),

=== modified file 'win32/QueueFrame.cpp'
--- win32/QueueFrame.cpp	2010-07-10 14:36:48 +0000
+++ win32/QueueFrame.cpp	2010-08-31 13:29:04 +0000
@@ -103,9 +103,7 @@
 	status->setHelpId(STATUS_TOTAL_COUNT, IDH_QUEUE_TOTAL_COUNT);
 	status->setHelpId(STATUS_TOTAL_BYTES, IDH_QUEUE_TOTAL_BYTES);
 
-	addQueueList(QueueManager::getInstance()->lockQueue());
-	QueueManager::getInstance()->unlockQueue();
-	QueueManager::getInstance()->addListener(this);
+	QueueManager::getInstance()->addListener(this, [this](const QueueItem::StringMap& qsm) { addQueueList(qsm); });
 
 	updateStatus();