linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #06115
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3070: Fix incorrect user lists when DC++ is under heavy load
------------------------------------------------------------
revno: 3070
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Thu 2012-10-04 21:31:21 +0200
message:
Fix incorrect user lists when DC++ is under heavy load
modified:
changelog.txt
dcpp/TaskQueue.h
win32/DirectoryListingFrame.cpp
win32/HubFrame.cpp
win32/HubFrame.h
win32/TransferView.cpp
win32/TransferView.h
--
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 2012-10-01 18:25:44 +0000
+++ changelog.txt 2012-10-04 19:31:21 +0000
@@ -1,6 +1,7 @@
* Perf improvements using lock-free queues, requires P6 CPUs (poy)
* Reduce freezes when displaying file list dirs that contain lots of files (poy)
* Less CPU consumption in large hubs (poy)
+* Fix incorrect user lists when DC++ is under heavy load (poy)
-- 0.800 2012-09-16 --
* [L#270107] Revamp favorite hub settings (poy)
=== modified file 'dcpp/TaskQueue.h'
--- dcpp/TaskQueue.h 2012-01-13 20:55:20 +0000
+++ dcpp/TaskQueue.h 2012-10-04 19:31:21 +0000
@@ -20,16 +20,15 @@
#define DCPLUSPLUS_DCPP_TASK_H
#include <memory>
-#include <utility>
#include <vector>
+#include <boost/noncopyable.hpp>
+
#include "CriticalSection.h"
namespace dcpp {
-using std::make_pair;
using std::pair;
-using std::swap;
using std::unique_ptr;
using std::vector;
@@ -37,36 +36,40 @@
virtual ~Task() { };
};
-struct StringTask : public Task {
- StringTask(const string& str_) : str(str_) { }
+struct StringTask : Task {
+ StringTask(string str) : str(move(str)) { }
string str;
};
-class TaskQueue {
+template<bool threadsafe>
+class TaskQueue : private boost::noncopyable {
+protected:
+ typedef vector<pair<int, unique_ptr<Task>>> List;
+
public:
- typedef pair<int, unique_ptr<Task>> Pair;
- typedef vector<Pair> List;
-
- TaskQueue() {
- }
-
- ~TaskQueue() {
+ virtual ~TaskQueue() {
clear();
}
- void add(int type, std::unique_ptr<Task> && data) { Lock l(cs); tasks.push_back(make_pair(type, move(data))); }
- void get(List& list) { Lock l(cs); swap(tasks, list); }
- void clear() {
- List tmp;
- get(tmp);
- }
-private:
-
- TaskQueue(const TaskQueue&);
- TaskQueue& operator=(const TaskQueue&);
-
+ void add(int type, std::unique_ptr<Task> && data) { tasks.emplace_back(type, move(data)); }
+ List get() { return move(tasks); }
+ void clear() { tasks.clear(); }
+
+private:
+ List tasks;
+};
+
+template<>
+class TaskQueue<true> : public TaskQueue<false> {
+ typedef TaskQueue<false> BaseType;
+
+public:
+ void add(int type, std::unique_ptr<Task> && data) { Lock l(cs); BaseType::add(type, move(data)); }
+ List get() { Lock l(cs); return BaseType::get(); }
+ void clear() { Lock l(cs); BaseType::clear(); }
+
+private:
CriticalSection cs;
- List tasks;
};
} // namespace dcpp
=== modified file 'win32/DirectoryListingFrame.cpp'
--- win32/DirectoryListingFrame.cpp 2012-10-03 16:54:06 +0000
+++ win32/DirectoryListingFrame.cpp 2012-10-04 19:31:21 +0000
@@ -593,6 +593,8 @@
} catch(const ThreadException& e) {
error = Text::toT(e.getError());
finishLoad();
+ delete loader;
+ loader = nullptr;
}
initStatusText();
=== modified file 'win32/HubFrame.cpp'
--- win32/HubFrame.cpp 2012-10-01 18:25:44 +0000
+++ win32/HubFrame.cpp 2012-10-04 19:31:21 +0000
@@ -289,7 +289,6 @@
HubFrame::~HubFrame() {
ClientManager::getInstance()->putClient(client);
- clearTaskList();
}
bool HubFrame::preClosing() {
@@ -603,15 +602,9 @@
}
}
-void HubFrame::addTask(Tasks s, const OnlineUser& u) {
- tasks.add(s, unique_ptr<Task>(new UserTask(u)));
- updateUsers = true;
-}
-
void HubFrame::execTasks() {
updateUsers = false;
- TaskQueue::List t;
- tasks.get(t);
+ auto t = tasks.get();
HoldRedraw hold(users);
@@ -790,13 +783,9 @@
void HubFrame::removeUser(const UserPtr& aUser) {
auto i = userMap.find(aUser);
- if(i == userMap.end()) {
- // Should never happen?
- dcassert(i != userMap.end());
- return;
- }
+ dcassert(i != userMap.end());
- UserInfo* ui = i->second;
+ auto ui = i->second;
if(!ui->isHidden() && showUsers->getChecked())
users->erase(ui);
@@ -920,21 +909,33 @@
setText(Text::toT(hubUrl));
});
}
+
void HubFrame::on(Connected, Client*) noexcept {
callAsync([this] { onConnected(); });
}
+
void HubFrame::on(ClientListener::UserUpdated, Client*, const OnlineUser& user) noexcept {
- addTask(UPDATE_USER_JOIN, user);
+ auto task = new UserTask(user);
+ callAsync([this, task] {
+ tasks.add(UPDATE_USER_JOIN, unique_ptr<Task>(task));
+ updateUsers = true;
+ });
}
+
void HubFrame::on(UsersUpdated, Client*, const OnlineUserList& aList) noexcept {
for(auto& i: aList) {
- tasks.add(UPDATE_USER, unique_ptr<Task>(new UserTask(*i)));
+ auto task = new UserTask(*i);
+ callAsync([this, task] { tasks.add(UPDATE_USER, unique_ptr<Task>(task)); });
}
- updateUsers = true;
+ callAsync([this] { updateUsers = true; });
}
void HubFrame::on(ClientListener::UserRemoved, Client*, const OnlineUser& user) noexcept {
- addTask(REMOVE_USER, user);
+ auto task = new UserTask(user);
+ callAsync([this, task] {
+ tasks.add(REMOVE_USER, unique_ptr<Task>(task));
+ updateUsers = true;
+ });
}
void HubFrame::on(Redirect, Client*, const string& line) noexcept {
=== modified file 'win32/HubFrame.h'
--- win32/HubFrame.h 2012-10-01 18:25:44 +0000
+++ win32/HubFrame.h 2012-10-04 19:31:21 +0000
@@ -105,7 +105,7 @@
UPDATE_USER_JOIN, UPDATE_USER, REMOVE_USER
};
- struct UserTask : public Task {
+ struct UserTask : Task {
UserTask(const OnlineUser& ou);
HintedUser user;
@@ -174,7 +174,7 @@
bool resort;
bool confirmClose;
- TaskQueue tasks; // todo get rid of TaskQueue
+ TaskQueue<false> tasks;
UserInfo* currentUser; /// only for situations when the user list is hidden
@@ -209,6 +209,8 @@
void initTimer();
bool runTimer();
+ void execTasks();
+
UserInfo* findUser(const tstring& nick);
bool updateUser(const UserTask& u);
void removeUser(const UserPtr& aUser);
@@ -259,9 +261,6 @@
// AspectUserInfo
UserInfoList selectedUsersImpl() const;
- void addTask(Tasks s, const OnlineUser& u);
- void execTasks();
-
void onConnected();
void onDisconnected();
void onGetPassword();
=== modified file 'win32/TransferView.cpp'
--- win32/TransferView.cpp 2012-09-10 22:14:27 +0000
+++ win32/TransferView.cpp 2012-10-04 19:31:21 +0000
@@ -476,8 +476,7 @@
}
void TransferView::execTasks() {
- TaskQueue::List t;
- tasks.get(t);
+ auto t = tasks.get();
bool sortConn = false;
bool sortDown = false;
=== modified file 'win32/TransferView.h'
--- win32/TransferView.h 2012-07-11 17:13:42 +0000
+++ win32/TransferView.h 2012-10-04 19:31:21 +0000
@@ -251,7 +251,7 @@
bool startup;
- TaskQueue tasks; // todo get rid of TaskQueue
+ TaskQueue<true> tasks; // todo get rid of TaskQueue
ParamMap ucLineParams;