diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 9679ca68c..b3589a1f0 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -131,7 +131,7 @@ void Client::Tick() { updateInfo = info.updateInfo; applyUpdateInfo = true; - messageOfTheDay = info.messageOfTheDay; + SetMessageOfTheDay(info.messageOfTheDay); } for (auto ¬ification : info.notifications) { @@ -142,7 +142,7 @@ void Client::Tick() { if (!usingAltUpdateServer) { - messageOfTheDay = ByteString::Build("Error while fetching MotD: ", ex.what()).FromUtf8(); + SetMessageOfTheDay(ByteString::Build("Error while fetching MotD: ", ex.what()).FromUtf8()); } } versionCheckRequest.reset(); @@ -154,7 +154,7 @@ void Client::Tick() auto info = alternateVersionCheckRequest->Finish(); updateInfo = info.updateInfo; applyUpdateInfo = true; - messageOfTheDay = info.messageOfTheDay; + SetMessageOfTheDay(info.messageOfTheDay); for (auto ¬ification : info.notifications) { AddServerNotification(notification); @@ -162,7 +162,7 @@ void Client::Tick() } catch (const http::RequestError &ex) { - messageOfTheDay = ByteString::Build("Error while checking for updates: ", ex.what()).FromUtf8(); + SetMessageOfTheDay(ByteString::Build("Error while checking for updates: ", ex.what()).FromUtf8()); } alternateVersionCheckRequest.reset(); } diff --git a/src/client/http/requestmanager/Libcurl.cpp b/src/client/http/requestmanager/Libcurl.cpp index 657b2085e..af8420fcb 100644 --- a/src/client/http/requestmanager/Libcurl.cpp +++ b/src/client/http/requestmanager/Libcurl.cpp @@ -296,13 +296,8 @@ namespace http { { std::lock_guard lk(sharedStateMx); - for (auto &requestHandle : requestHandles) - { - if (requestHandle->statusCode) - { - requestHandlesToUnregister.push_back(requestHandle); - } - } + // Register new handles first. This always succeeds even if the handle is "failed early" so that + // a single MarkDone call could be issued on all handles further down in this block. for (auto &requestHandle : requestHandlesToRegister) { // Must not be present @@ -311,6 +306,17 @@ namespace http RegisterRequestHandle(requestHandle); } requestHandlesToRegister.clear(); + // Then unregister done handles. As explained above, registering a new handle may also immediately mark + // it done and we won't be coming back here until Wait() returns, so this has to come second. + for (auto &requestHandle : requestHandles) + { + if (requestHandle->statusCode) + { + requestHandlesToUnregister.push_back(requestHandle); + } + } + // Actually unregister handles queued to be unregistered. They can be queued just above, or from another thread. + // Thus, it's ok for them to be in the queue multiple times, but it's not ok to try to unregister them multiple times. for (auto &requestHandle : requestHandlesToUnregister) { auto eraseFrom = std::remove(requestHandles.begin(), requestHandles.end(), requestHandle);