diff --git a/Release/include/pplx/pplxtasks.h b/Release/include/pplx/pplxtasks.h index 0c337d5a5e..e08272cdc7 100644 --- a/Release/include/pplx/pplxtasks.h +++ b/Release/include/pplx/pplxtasks.h @@ -16,9 +16,27 @@ #ifndef _PPLXTASKS_H #define _PPLXTASKS_H +#include "cpprest/details/cpprest_compat.h" + #if (defined(_MSC_VER) && (_MSC_VER >= 1800)) && !CPPREST_FORCE_PPLX #include namespace pplx = Concurrency; + +namespace Concurrency +{ + +/// +/// Sets the ambient scheduler to be used by the PPL constructs. +/// +_ASYNCRTIMP void __cdecl set_cpprestsdk_ambient_scheduler(const std::shared_ptr& _Scheduler); + +/// +/// Gets the ambient scheduler to be used by the PPL constructs +/// +_ASYNCRTIMP const std::shared_ptr& __cdecl get_cpprestsdk_ambient_scheduler(); + +} // namespace Concurrency + #if (_MSC_VER >= 1900) #include namespace Concurrency { diff --git a/Release/src/CMakeLists.txt b/Release/src/CMakeLists.txt index cea7048c7d..5f77deea1f 100644 --- a/Release/src/CMakeLists.txt +++ b/Release/src/CMakeLists.txt @@ -103,6 +103,7 @@ elseif(CPPREST_PPLX_IMPL STREQUAL "linux") install(FILES ../include/pplx/threadpool.h DESTINATION include/pplx) endif() elseif(CPPREST_PPLX_IMPL STREQUAL "win") + target_sources(cpprest PRIVATE pplx/pplxwin.cpp) if(CPPREST_WEBSOCKETS_IMPL STREQUAL "wspp") target_sources(cpprest PRIVATE pplx/threadpool.cpp ../include/pplx/threadpool.h) if(CPPREST_INSTALL_HEADERS) diff --git a/Release/src/pplx/pplxwin.cpp b/Release/src/pplx/pplxwin.cpp index e511c0ad5d..c414397c16 100644 --- a/Release/src/pplx/pplxwin.cpp +++ b/Release/src/pplx/pplxwin.cpp @@ -275,4 +275,19 @@ namespace details } // namespace pplx +#else +namespace Concurrency +{ + +void __cdecl set_cpprestsdk_ambient_scheduler(const std::shared_ptr& _Scheduler) +{ + pplx::set_ambient_scheduler(_Scheduler); +} + +const std::shared_ptr& __cdecl get_cpprestsdk_ambient_scheduler() +{ + return pplx::get_ambient_scheduler(); +} + +} // namespace pplx #endif \ No newline at end of file diff --git a/Release/tests/functional/http/client/outside_tests.cpp b/Release/tests/functional/http/client/outside_tests.cpp index bec9b0c458..bb5909d35e 100644 --- a/Release/tests/functional/http/client/outside_tests.cpp +++ b/Release/tests/functional/http/client/outside_tests.cpp @@ -111,6 +111,43 @@ TEST_FIXTURE(uri_address, multiple_https_requests) }); } +#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) && !CPPREST_FORCE_PPLX +TEST_FIXTURE(uri_address, multiple_https_requests_sync_scheduler) +{ + struct sync_scheduler : public scheduler_interface + { + public: + virtual void schedule(TaskProc_t function, PVOID context) override + { + function(context); + } + }; + + // Save the current ambient scheduler + const auto scheduler = get_cpprestsdk_ambient_scheduler(); + + // Change the ambient scheduler to one that schedules synchronously + static std::shared_ptr syncScheduler = std::make_shared(); + set_cpprestsdk_ambient_scheduler(syncScheduler); + + handle_timeout([&] { + // Use code.google.com instead of www.google.com, which redirects + http_client client(U("https://code.google.com")); + + http_response response; + for (int i = 0; i < 5; ++i) + { + response = client.request(methods::GET).get(); + VERIFY_ARE_EQUAL(status_codes::OK, response.status_code()); + response.content_ready().wait(); + } + }); + + // Revert to the original scheduler + set_cpprestsdk_ambient_scheduler(scheduler); +} +#endif + TEST_FIXTURE(uri_address, reading_google_stream) { handle_timeout([&]