|
@@ -281,6 +281,23 @@ certificate_ptr make_certificate_impl(string commonName) {
|
|
|
|
|
|
// Common for GnuTLS and OpenSSL
|
|
|
|
|
|
+namespace {
|
|
|
+
|
|
|
+// Helper function roughly equivalent to std::async with policy std::launch::async
|
|
|
+// since std::async might be unreliable on some platforms (e.g. Mingw32 on Windows)
|
|
|
+template <class F, class... Args>
|
|
|
+std::future<std::result_of_t<std::decay_t<F>(std::decay_t<Args>...)>> thread_call(F &&f,
|
|
|
+ Args &&... args) {
|
|
|
+ using R = std::result_of_t<std::decay_t<F>(std::decay_t<Args>...)>;
|
|
|
+ std::packaged_task<R()> task(std::bind(f, std::forward<Args>(args)...));
|
|
|
+ std::future<R> future = task.get_future();
|
|
|
+ std::thread t(std::move(task));
|
|
|
+ t.detach();
|
|
|
+ return future;
|
|
|
+}
|
|
|
+
|
|
|
+} // namespace
|
|
|
+
|
|
|
namespace rtc {
|
|
|
|
|
|
future_certificate_ptr make_certificate(string commonName) {
|
|
@@ -292,7 +309,7 @@ future_certificate_ptr make_certificate(string commonName) {
|
|
|
if (auto it = cache.find(commonName); it != cache.end())
|
|
|
return it->second;
|
|
|
|
|
|
- auto future = std::async(make_certificate_impl, commonName);
|
|
|
+ auto future = thread_call(make_certificate_impl, commonName);
|
|
|
auto shared = future.share();
|
|
|
cache.emplace(std::move(commonName), shared);
|
|
|
return shared;
|