Przeglądaj źródła

Replaced std::async call with custom thread invocation

Paul-Louis Ageneau 5 lat temu
rodzic
commit
3be2b0427f
1 zmienionych plików z 18 dodań i 1 usunięć
  1. 18 1
      src/certificate.cpp

+ 18 - 1
src/certificate.cpp

@@ -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;