From fe4199dace73ee38262528f7ae88cbfba99120dd Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 31 Dec 2018 12:01:59 +0100 Subject: Make thread-safe --- src/Window.cpp | 135 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 99 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/Window.cpp b/src/Window.cpp index 5e4930f..255986a 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -68,7 +68,10 @@ namespace dchat { if(!rooms || !rooms->database) { - windowNotification->show("You are not connected to the bootstrap node yet! please wait..."); + dispatchFunction([this]() + { + windowNotification->show("You are not connected to the bootstrap node yet! please wait..."); + }); return; } @@ -76,17 +79,23 @@ namespace dchat { fprintf(stderr, "Trying to login with username %s\n", username.raw().c_str()); rooms->loginUser(username.raw(), password.raw()); - //windowNotification->show(Glib::ustring("Successfully logged in as ") + username); - drawBackgroundConnection.disconnect(); - chatWindow.show(); - stack.set_visible_child(chatWindow); - chatWindow.scrollToBottom(); + dispatchFunction([this]() + { + //windowNotification->show(Glib::ustring("Successfully logged in as ") + username); + drawBackgroundConnection.disconnect(); + chatWindow.show(); + stack.set_visible_child(chatWindow); + chatWindow.scrollToBottom(); + }); } catch(std::exception &e) { Glib::ustring errMsg = "Failed to login, reason: "; errMsg += e.what(); - windowNotification->show(errMsg); + dispatchFunction([this, errMsg]() + { + windowNotification->show(errMsg); + }); } }); @@ -94,7 +103,10 @@ namespace dchat { if(!rooms || !rooms->database) { - windowNotification->show("You are not connected to the bootstrap node yet! please wait..."); + dispatchFunction([this]() + { + windowNotification->show("You are not connected to the bootstrap node yet! please wait..."); + }); return; } @@ -102,10 +114,13 @@ namespace dchat { fprintf(stderr, "Trying to register username %s\n", username.raw().c_str()); rooms->registerUser(username.raw(), password.raw()); - windowNotification->show(Glib::ustring("Successfully registered user ") + username); - drawBackgroundConnection.disconnect(); - chatWindow.show(); - stack.set_visible_child(chatWindow); + dispatchFunction([this]() + { + //windowNotification->show(Glib::ustring("Successfully registered user ") + username); + drawBackgroundConnection.disconnect(); + chatWindow.show(); + stack.set_visible_child(chatWindow); + }); } catch(std::exception &e) { @@ -113,13 +128,19 @@ namespace dchat errMsg += username.raw(); errMsg += ", reason: "; errMsg += e.what(); - windowNotification->show(errMsg); + dispatchFunction([this, errMsg]() + { + windowNotification->show(errMsg); + }); } }); loginWindow.setRegisterPasswordMismatch([this] { - windowNotification->show("Passwords do not match"); + dispatchFunction([this]() + { + windowNotification->show("Passwords do not match"); + }); }); auto bootstrapNodes = getBootstrapNodesFromFile(); @@ -136,52 +157,87 @@ namespace dchat roomCallbackFuncs.connectCallbackFunc = [this, bootstrapNode](std::shared_ptr rooms, const char *errMsg) { this->rooms = rooms; - if(rooms) + std::string errMsgStr = errMsg ? errMsg : "unknown"; + dispatchFunction([this, bootstrapNode, errMsgStr]() { - loginWindow.show(); - stack.set_visible_child(loginWindow); - std::string msg = "Connected to "; - msg += *bootstrapNode; - msg += ":27130"; - windowNotification->show(msg); - loginWindow.loginUsernameInput.grab_focus(); - } - else - { - std::string errMsgToShow = "Failed to connect to boostrap node, reason: "; - errMsgToShow += errMsg; - windowNotification->show(errMsgToShow); - } + if(this->rooms) + { + loginWindow.show(); + stack.set_visible_child(loginWindow); + std::string msg = "Connected to "; + msg += *bootstrapNode; + msg += ":27130"; + windowNotification->show(msg); + loginWindow.loginUsernameInput.grab_focus(); + } + else + { + std::string errMsgToShow = "Failed to connect to boostrap node, reason: "; + errMsgToShow += errMsgStr; + windowNotification->show(errMsgToShow); + } + }); }; roomCallbackFuncs.createRoomCallbackFunc = [this](std::shared_ptr room) { - chatWindow.addRoom(room); + dispatchFunction([this, room]() + { + chatWindow.addRoom(room); + }); }; roomCallbackFuncs.addUserCallbackFunc = [this](const RoomAddUserRequest &request) { - chatWindow.addUser(request); + dispatchFunction([this, request]() + { + chatWindow.addUser(request); + }); }; roomCallbackFuncs.addMessageCallbackFunc = [this](const RoomAddMessageRequest &request) { - chatWindow.addMessage(request); + dispatchFunction([this, request]() + { + chatWindow.addMessage(request); + }); }; roomCallbackFuncs.userChangeNicknameCallbackFunc = [this](const UserChangeNicknameRequest &request) { - chatWindow.setUserNickname(request); + dispatchFunction([this, request]() + { + chatWindow.setUserNickname(request); + }); }; roomCallbackFuncs.userChangeAvatarCallbackFunc = [this](const UserChangeAvatarRequest &request) { - chatWindow.setUserAvatar(request); + dispatchFunction([this, request]() + { + chatWindow.setUserAvatar(request); + }); }; roomCallbackFuncs.changeRoomNameCallbackFunc = [this](const RoomChangeNameRequest &request) { - chatWindow.changeRoomName(request); + dispatchFunction([this, request]() + { + chatWindow.changeRoomName(request); + }); }; roomCallbackFuncs.receiveInviteUserCallbackFunc = [this](const InviteUserRequest &request) { - chatWindow.addInviteRequest(request); + dispatchFunction([this, request]() + { + chatWindow.addInviteRequest(request); + }); }; + dispatcher.connect([this]() + { + std::lock_guard lock(dispatcherMutex); + for(DispatcherHandler &dispatcherHandler : dispatcherHandlers) + { + dispatcherHandler(); + } + dispatcherHandlers.clear(); + }); + Rooms::connect(bootstrapNode->c_str(), 27130, roomCallbackFuncs); backgroundRng.seed(std::random_device()()); @@ -222,6 +278,13 @@ namespace dchat } + void Window::dispatchFunction(DispatcherHandler func) + { + std::lock_guard lock(dispatcherMutex); + dispatcherHandlers.push_back(func); + dispatcher.emit(); + } + static void drawNode(const Cairo::RefPtr &cairo, double x, double y, double radius) { cairo->arc(x, y, radius, 0.0, 2.0 * M_PI); -- cgit v1.2.3