Мне нужно защитить часть кода от одновременного выполнения в сопрограмме.Защита от одновременного выполнения в многопоточной среде будет простым делом с использованием шаблона класса std :: lock_guard .Моя сопрограмма, однако, вызывается из одного потока, так что решение не применимо.
Ниже (псевдо) код того, что я пытаюсь выполнить:
future<http_response> send_req_async(http_request req) {
while (true) {
// Attempt to send an HTTP request
auto const& access_token{ token_store::access_token() };
auto const response{ co_await impl::send_req_async(req, access_token) };
if (response.status_code() == http_code::ok) {
co_return response;
}
// Attempt to refresh access token
if (response.status_code() == http_code::unauthorized) {
// The following scope needs to be guarded against concurrent execution.
// To guard against concurrent execution from multiple threads I would use:
// lock_guard<mutex> guard(refresh_token_mutex);
if (access_token != token_store::access_token()) {
continue;
}
auto const& token{ co_await refresh_token(token_store::refresh_token()) };
token_store::save_access_token(token);
// End of section that needs to be guarded.
}
}
}
Код предназначен для параллельного выполнения нескольких запросов, в то же время разрешая только один вызов сопрограммы при попытке обновить токен с истекшим сроком доступа.В идеале решение должно приостанавливать параллельный вызов сопрограммы, пока выполняется операция обновления токена, и автоматически возобновлять ее после этого (т. Е. Семантика std::lock_guard
в многопоточной среде).
Есть ли что-нибудь построенноев механизм сопрограмм или стандартную библиотеку C ++, которая позволяет мне реализовать это в чистом виде, или мне придется свернуть свой собственный?
Примечание: я использую Visual Studio 2017 15.7.2, так что вы можете предполагать полную поддержку C ++ 17, а также его реализацию Coroutine TS.