------------------------------------------------------------ revno: 3070 committer: poy <p...@123gen.com> 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;
_______________________________________________ Mailing list: https://launchpad.net/~linuxdcpp-team Post to : linuxdcpp-team@lists.launchpad.net Unsubscribe : https://launchpad.net/~linuxdcpp-team More help : https://help.launchpad.net/ListHelp