diff --git a/src/slic3r/GUI/UserAccountCommunication.cpp b/src/slic3r/GUI/UserAccountCommunication.cpp index ba5b1c8f68..877ff1fe1c 100644 --- a/src/slic3r/GUI/UserAccountCommunication.cpp +++ b/src/slic3r/GUI/UserAccountCommunication.cpp @@ -242,7 +242,8 @@ void UserAccountCommunication::set_username(const std::string& username) { m_username = username; { - std::lock_guard lock(m_session_mutex); + // We don't need mutex lock here, as credentials are guarded by own mutex in m_session + //std::lock_guard lock(m_session_mutex); if (is_secret_store_ok()) { std::string tokens; if (m_remember_session) { @@ -292,7 +293,8 @@ void UserAccountCommunication::set_remember_session(bool b) std::string UserAccountCommunication::get_access_token() { { - std::lock_guard lock(m_session_mutex); + // We don't need mutex lock here, as credentials are guarded by own mutex in m_session + //std::lock_guard lock(m_session_mutex); return m_session->get_access_token(); } } @@ -300,7 +302,8 @@ std::string UserAccountCommunication::get_access_token() std::string UserAccountCommunication::get_shared_session_key() { { - std::lock_guard lock(m_session_mutex); + // We don't need mutex lock here, as credentials are guarded by own mutex in m_session + //std::lock_guard lock(m_session_mutex); return m_session->get_shared_session_key(); } } diff --git a/src/slic3r/GUI/UserAccountSession.cpp b/src/slic3r/GUI/UserAccountSession.cpp index 23fe45cebf..9c18cad514 100644 --- a/src/slic3r/GUI/UserAccountSession.cpp +++ b/src/slic3r/GUI/UserAccountSession.cpp @@ -100,7 +100,12 @@ void UserAccountSession::process_action_queue() } // priority queue works even when tokens are empty or broken while (!m_priority_action_queue.empty()) { - m_actions[m_priority_action_queue.front().action_id]->perform(p_evt_handler, m_access_token, m_priority_action_queue.front().success_callback, m_priority_action_queue.front().fail_callback, m_priority_action_queue.front().input); + std::string access_token; + { + std::lock_guard lock(m_credentials_mutex); + access_token = m_access_token; + } + m_actions[m_priority_action_queue.front().action_id]->perform(p_evt_handler, access_token, m_priority_action_queue.front().success_callback, m_priority_action_queue.front().fail_callback, m_priority_action_queue.front().input); if (!m_priority_action_queue.empty()) m_priority_action_queue.pop_front(); } @@ -108,7 +113,12 @@ void UserAccountSession::process_action_queue() if (!this->is_initialized()) return; while (!m_action_queue.empty()) { - m_actions[m_action_queue.front().action_id]->perform(p_evt_handler, m_access_token, m_action_queue.front().success_callback, m_action_queue.front().fail_callback, m_action_queue.front().input); + std::string access_token; + { + std::lock_guard lock(m_credentials_mutex); + access_token = m_access_token; + } + m_actions[m_action_queue.front().action_id]->perform(p_evt_handler, access_token, m_action_queue.front().success_callback, m_action_queue.front().fail_callback, m_action_queue.front().input); if (!m_action_queue.empty()) m_action_queue.pop(); } @@ -174,9 +184,12 @@ void UserAccountSession::token_success_callback(const std::string& body) if (access_token.empty() || refresh_token.empty() || shared_session_key.empty()) { // just debug msg, no need to translate std::string msg = GUI::format("Failed read tokens after POST.\nAccess token: %1%\nRefresh token: %2%\nShared session token: %3%\nbody: %4%", access_token, refresh_token, shared_session_key, body); - m_access_token = std::string(); - m_refresh_token = std::string(); - m_shared_session_key = std::string(); + { + std::lock_guard lock(m_credentials_mutex); + m_access_token = std::string(); + m_refresh_token = std::string(); + m_shared_session_key = std::string(); + } wxQueueEvent(p_evt_handler, new UserAccountFailEvent(EVT_UA_RESET, std::move(msg))); return; } @@ -184,11 +197,13 @@ void UserAccountSession::token_success_callback(const std::string& body) //BOOST_LOG_TRIVIAL(info) << "access_token: " << access_token; //BOOST_LOG_TRIVIAL(info) << "refresh_token: " << refresh_token; //BOOST_LOG_TRIVIAL(info) << "shared_session_key: " << shared_session_key; - - m_access_token = access_token; - m_refresh_token = refresh_token; - m_shared_session_key = shared_session_key; - m_next_token_timeout = std::time(nullptr) + expires_in; + { + std::lock_guard lock(m_credentials_mutex); + m_access_token = access_token; + m_refresh_token = refresh_token; + m_shared_session_key = shared_session_key; + m_next_token_timeout = std::time(nullptr) + expires_in; + } enqueue_action(UserAccountActionID::USER_ACCOUNT_ACTION_USER_ID, nullptr, nullptr, {}); wxQueueEvent(p_evt_handler, new UserAccountTimeEvent(EVT_UA_REFRESH_TIME, expires_in)); } @@ -212,10 +227,14 @@ void UserAccountSession::enqueue_test_with_refresh() void UserAccountSession::enqueue_refresh(const std::string& body) { - assert(!m_refresh_token.empty()); - std::string post_fields = "grant_type=refresh_token" - "&client_id=" + client_id() + - "&refresh_token=" + m_refresh_token; + std::string post_fields; + { + std::lock_guard lock(m_credentials_mutex); + assert(!m_refresh_token.empty()); + post_fields = "grant_type=refresh_token" + "&client_id=" + client_id() + + "&refresh_token=" + m_refresh_token; + } m_priority_action_queue.push_back({ UserAccountActionID::USER_ACCOUNT_ACTION_REFRESH_TOKEN , std::bind(&UserAccountSession::token_success_callback, this, std::placeholders::_1) diff --git a/src/slic3r/GUI/UserAccountSession.hpp b/src/slic3r/GUI/UserAccountSession.hpp index 333894cded..223af17d30 100644 --- a/src/slic3r/GUI/UserAccountSession.hpp +++ b/src/slic3r/GUI/UserAccountSession.hpp @@ -136,9 +136,12 @@ public: m_actions[UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_DATA_FROM_UUID].reset(nullptr); } void clear() { - m_access_token.clear(); - m_refresh_token.clear(); - m_shared_session_key.clear(); + { + std::lock_guard lock(m_credentials_mutex); + m_access_token.clear(); + m_refresh_token.clear(); + m_shared_session_key.clear(); + } m_proccessing_enabled = false; } @@ -150,12 +153,27 @@ public: void enqueue_refresh(const std::string& body); void process_action_queue(); - bool is_initialized() const { return !m_access_token.empty() || !m_refresh_token.empty(); } + bool is_initialized() const { + std::lock_guard lock(m_credentials_mutex); + return !m_access_token.empty() || !m_refresh_token.empty(); + } bool is_enqueued(UserAccountActionID action_id) const; - std::string get_access_token() const { return m_access_token; } - std::string get_refresh_token() const { return m_refresh_token; } - std::string get_shared_session_key() const { return m_shared_session_key; } - long long get_next_token_timeout() const {return m_next_token_timeout; } + std::string get_access_token() const { + std::lock_guard lock(m_credentials_mutex); + return m_access_token; + } + std::string get_refresh_token() const { + std::lock_guard lock(m_credentials_mutex); + return m_refresh_token; + } + std::string get_shared_session_key() const { + std::lock_guard lock(m_credentials_mutex); + return m_shared_session_key; + } + long long get_next_token_timeout() const { + std::lock_guard lock(m_credentials_mutex); + return m_next_token_timeout; + } //void set_polling_enabled(bool enabled) {m_polling_action = enabled ? UserAccountActionID::USER_ACCOUNT_ACTION_CONNECT_PRINTER_MODELS : UserAccountActionID::USER_ACCOUNT_ACTION_DUMMY; } void set_polling_action(UserAccountActionID action) { m_polling_action = action; } @@ -174,10 +192,13 @@ private: // set to USER_ACCOUNT_ACTION_DUMMY to switch off polling UserAccountActionID m_polling_action; + // Section of following vars is guarded by this mutex + mutable std::mutex m_credentials_mutex; std::string m_access_token; std::string m_refresh_token; std::string m_shared_session_key; - long long m_next_token_timeout; + long long m_next_token_timeout; + // End of section guarded by m_credentials_mutex std::queue m_action_queue; std::deque m_priority_action_queue; diff --git a/src/slic3r/Utils/Http.cpp b/src/slic3r/Utils/Http.cpp index 978e91b5ec..a1c4f57c69 100644 --- a/src/slic3r/Utils/Http.cpp +++ b/src/slic3r/Utils/Http.cpp @@ -398,7 +398,7 @@ void Http::priv::http_perform(const HttpRetryOpt& retry_opts) if (res == CURLE_OK) ::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status); - retry = delay >= 0ms && is_transient_error(res, http_status); + retry = retry_opts.initial_delay > 0ms && is_transient_error(res, http_status); if (retry && retry_opts.max_retries > 0 && num_retries >= retry_opts.max_retries) retry = false; if (retry) { diff --git a/src/slic3r/Utils/Http.hpp b/src/slic3r/Utils/Http.hpp index 6d21570c12..f190c40e1f 100644 --- a/src/slic3r/Utils/Http.hpp +++ b/src/slic3r/Utils/Http.hpp @@ -17,8 +17,10 @@ namespace Slic3r { struct HttpRetryOpt { + // if set to zero, no retries at all std::chrono::milliseconds initial_delay; std::chrono::milliseconds max_delay; + // if set to zero, retries forever size_t max_retries{0}; static const HttpRetryOpt& no_retry();