Skip to content

Commit 0356c27

Browse files
committed
Merge branch 'development' of https://git01.codeplex.com/casablanca into cleanup_test_projs
2 parents 02c1fdc + e9a2d87 commit 0356c27

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

Release/src/http/listener/http_server_httpsys.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,17 @@ void http_windows_server::receive_requests()
425425
{
426426
HTTP_REQUEST p_request;
427427
ULONG bytes_received;
428-
for(;;)
428+
429+
// Oversubscribe since this is a blocking call and we don't want to count
430+
// towards the concurrency runtime's thread count. A more proper fix
431+
// would be to use Overlapped I/O and asynchronously call HttpReceiveHttpRequest.
432+
// This requires additional work to be careful sychronizing with the listener
433+
// shutdown. This is much easier especially given the http_listener is 'experimental'
434+
// and with VS2015 PPL tasks run on the threadpool.
435+
#if _MSC_VER < 1900
436+
concurrency::Context::Oversubscribe(true);
437+
#endif
438+
for (;;)
429439
{
430440
unsigned long error_code = HttpReceiveHttpRequest(
431441
m_hRequestQueue,
@@ -436,7 +446,7 @@ void http_windows_server::receive_requests()
436446
&bytes_received,
437447
0);
438448

439-
if(error_code != NO_ERROR && error_code != ERROR_MORE_DATA)
449+
if (error_code != NO_ERROR && error_code != ERROR_MORE_DATA)
440450
{
441451
break;
442452
}
@@ -447,6 +457,9 @@ void http_windows_server::receive_requests()
447457
http_request msg = http_request::_create_request(std::move(pRequestContext));
448458
pContext->async_process_request(p_request.RequestId, msg, bytes_received);
449459
}
460+
#if _MSC_VER < 1900
461+
concurrency::Context::Oversubscribe(false);
462+
#endif
450463
}
451464

452465
pplx::task<void> http_windows_server::respond(http::http_response response)

Release/tests/functional/http/listener/connections_and_errors.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717

1818
#include <cpprest/http_client.h>
1919

20+
// For single_core test case.
21+
#if defined(_WIN32) && _MSC_VER < 1900
22+
#include <concrt.h>
23+
#endif
24+
2025
using namespace utility;
2126
using namespace web;
2227
using namespace web::http;
@@ -143,6 +148,39 @@ TEST_FIXTURE(uri_address, save_request_reply)
143148
listener.close().wait();
144149
}
145150

151+
#if defined(_WIN32) && _MSC_VER < 1900
152+
TEST_FIXTURE(uri_address, single_core_request)
153+
{
154+
// Fake having a scheduler with only 1 core.
155+
concurrency::CurrentScheduler::Create(concurrency::SchedulerPolicy(2, 1, Concurrency::MinConcurrency, 1, Concurrency::MaxConcurrency));
156+
157+
http_listener listener(m_uri);
158+
listener.open().wait();
159+
test_http_client::scoped_client client(m_uri);
160+
test_http_client * p_client = client.client();
161+
162+
listener.support([](http_request request)
163+
{
164+
request.reply(status_codes::OK).get();
165+
});
166+
VERIFY_ARE_EQUAL(0, p_client->request(methods::POST, U("")));
167+
168+
// Don't wait on the task otherwise it could inline allowing other tasks to run on the scheduler.
169+
std::atomic_flag responseEvent = ATOMIC_FLAG_INIT;
170+
responseEvent.test_and_set();
171+
p_client->next_response().then([&](test_response *p_response)
172+
{
173+
http_asserts::assert_test_response_equals(p_response, status_codes::OK);
174+
responseEvent.clear();
175+
});
176+
while (responseEvent.test_and_set()) {}
177+
178+
listener.close().wait();
179+
180+
concurrency::CurrentScheduler::Detach();
181+
}
182+
#endif
183+
146184
TEST_FIXTURE(uri_address, save_request_response)
147185
{
148186
http_listener listener(m_uri);

0 commit comments

Comments
 (0)