cpprestsdk
cpprestsdk copied to clipboard
wait() on request hangs / deadlocks
Hello, I have the following code embedded in my library, which is built for Windows with VS2015 And after running some tests, I have noticed that there is a deadlock that is happening spuriously (probably 2-3 times on 50 runs).
The strange part is that this deadlock occurs only if I run multiple requests in the same applications (e.g multiple requests to different endpoints).
For example:
requestA requestB <- deadlock
or
requestA requestB requestC <- deadlock or requestB deadlocks, but never request A
bool send_request(request_method method,
const std::string& apiName,
const web::json::value& query_body,
response_data_container& response_data) {
int status_code = 200;
uri_builder builder(apiName));
bool status = true;
http_request request(get_method(method));
request.set_body(query_body);
request.set_request_uri(builder.to_string());
// Add some request headers
client_->request(request)
.then([&status, &status_code](const http_response& response) {
// continue when the response is available
if (response.status_code() != status_codes::OK) {
status_code = response.status_code();
// LOG some error
// return an empty JSON value and set the status to false
status = false;
return pplx::task<json::value>();
}
status_code = response.status_code();
return response.extract_json();
}).then([&response_data, &status, &status_code](
const pplx::task<json::value> &previous_response) {
// continue when the JSON value is available
try {
if (previous_response.get().size() == 0) {
LOG("JSON content of reply is empty");
return status;
}
response_data = previous_response.get();
return status;
} catch (http_exception &e) {
const int error_code = e.error_code().value();
LOG("Error getting response: (%d) %s", error_code, e.what());
// Map http error code to status_code here..
status = false;
}
return status;
}).wait(); <-- deadlocks here
return status;
}
I can't figure out what I am doing wrong here? I know that .get() is block API but I am calling it in continuation. maybe it is the problem?
I want also to add here, that this behaviour is seen only on Windows 10, but when I am trying to run these tests on Windows server 2016, I can't see or get any deadlock.
I'm having the exact same issue, with Visual Studio 2019 and Windows 10. I've mixing cppwinrt's thread handling with cpprest. All of the cpprest object where created on the same thread, so that shouldn't be an issue. In my case when there is an ongoing request and the second thread calls the client.request(request).get() function the both threads will be locked up, and never return. As a workaround I switched the http request handling to the crp and kept the json parsing from the cpprest-sdk.
This looks like it's probably the "waiting on completions inside of other tasks" thing. How many tasks are active (or waiting) when the deadlock happens
So I have retried again with the simplest code path as possible. I have only one task that is running. That is, just sending a simple request to the server, and doing nothing else, not even extracting JSON response.
And I am still hitting the same issue. From my debug session that looks related to some kind of condition variable inside Windows, or PPL library that is cpprestdk/windows is using for tasking.
Here are few screenshots:
As you can see, the condition is waiting, but I don't know what is waiting for? I have a single threaded application with a single task.
Thank you,