123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- From 65267c6e83e7e29ed3bdddde13d2c4bbb10e1bff Mon Sep 17 00:00:00 2001
- From: Billy O'Neal <billy.oneal@gmail.com>
- Date: Thu, 6 Dec 2018 23:57:00 -0800
- Subject: [PATCH] Remove use of aligned_union that broke CentOS 7. (#987)
- Signed-off-by: Billy O'Neal <billy.oneal@gmail.com>
- [Backport from upstream commit 65267c6e83e7e29ed3bdddde13d2c4bbb10e1bff]
- Signed-off-by: Adam Duskett <aduskett@gmail.com>
- ---
- Release/src/pplx/threadpool.cpp | 127 +++++++++++++++-----------------
- 1 file changed, 61 insertions(+), 66 deletions(-)
- diff --git a/Release/src/pplx/threadpool.cpp b/Release/src/pplx/threadpool.cpp
- index 1c28cca8f..58920c025 100644
- --- a/Release/src/pplx/threadpool.cpp
- +++ b/Release/src/pplx/threadpool.cpp
- @@ -1,9 +1,7 @@
- /***
- -* Copyright (C) Microsoft. All rights reserved.
- -* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- -*
- -* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
- -**/
- + * Copyright (C) Microsoft. All rights reserved.
- + * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- + **/
- #include "stdafx.h"
-
- #if !defined(CPPREST_EXCLUDE_WEBSOCKETS) || !defined(_WIN32)
- @@ -11,8 +9,9 @@
-
- #include <boost/asio/detail/thread.hpp>
- #include <new>
- -#include <vector>
- #include <type_traits>
- +#include <utility>
- +#include <vector>
-
- #if defined(__ANDROID__)
- #include <android/log.h>
- @@ -29,9 +28,11 @@ static void abort_if_no_jvm()
- {
- if (JVM == nullptr)
- {
- - __android_log_print(ANDROID_LOG_ERROR, "CPPRESTSDK", "%s",
- - "The CppREST SDK must be initialized before first use on android: "
- - "https://github.com/Microsoft/cpprestsdk/wiki/How-to-build-for-Android");
- + __android_log_print(ANDROID_LOG_ERROR,
- + "CPPRESTSDK",
- + "%s",
- + "The CppREST SDK must be initialized before first use on android: "
- + "https://github.com/Microsoft/cpprestsdk/wiki/How-to-build-for-Android");
- std::abort();
- }
- }
- @@ -52,9 +53,7 @@ JNIEnv* get_jvm_env()
-
- struct threadpool_impl final : crossplat::threadpool
- {
- - threadpool_impl(size_t n)
- - : crossplat::threadpool(n)
- - , m_work(m_service)
- + threadpool_impl(size_t n) : crossplat::threadpool(n), m_work(m_service)
- {
- for (size_t i = 0; i < n; i++)
- add_thread();
- @@ -69,26 +68,20 @@ struct threadpool_impl final : crossplat::threadpool
- }
- }
-
- - threadpool_impl& get_shared()
- - {
- - return *this;
- - }
- + threadpool_impl& get_shared() { return *this; }
-
- private:
- void add_thread()
- {
- - m_threads.push_back(std::unique_ptr<boost::asio::detail::thread>(
- - new boost::asio::detail::thread([&]{ thread_start(this); })));
- + m_threads.push_back(
- + std::unique_ptr<boost::asio::detail::thread>(new boost::asio::detail::thread([&] { thread_start(this); })));
- }
-
- #if defined(__ANDROID__)
- - static void detach_from_java(void*)
- - {
- - JVM.load()->DetachCurrentThread();
- - }
- + static void detach_from_java(void*) { JVM.load()->DetachCurrentThread(); }
- #endif // __ANDROID__
-
- - static void* thread_start(void *arg) CPPREST_NOEXCEPT
- + static void* thread_start(void* arg) CPPREST_NOEXCEPT
- {
- #if defined(__ANDROID__)
- // Calling get_jvm_env() here forces the thread to be attached.
- @@ -110,17 +103,14 @@ struct threadpool_impl final : crossplat::threadpool
- #if defined(_WIN32)
- struct shared_threadpool
- {
- - std::aligned_union<0, threadpool_impl>::type shared_storage;
- + union {
- + threadpool_impl shared_storage;
- + };
-
- - threadpool_impl& get_shared()
- - {
- - return reinterpret_cast<threadpool_impl&>(shared_storage);
- - }
- + threadpool_impl& get_shared() { return shared_storage; }
- +
- + shared_threadpool(size_t n) : shared_storage(n) {}
-
- - shared_threadpool(size_t n)
- - {
- - ::new (static_cast<void*>(&get_shared())) threadpool_impl(n);
- - }
- ~shared_threadpool()
- {
- // if linked into a DLL, the threadpool shared instance will be
- @@ -138,52 +128,59 @@ typedef shared_threadpool platform_shared_threadpool;
- typedef threadpool_impl platform_shared_threadpool;
- #endif
-
- -std::pair<bool, platform_shared_threadpool*> initialize_shared_threadpool(size_t num_threads)
- +namespace
- {
- - static std::aligned_union<0, platform_shared_threadpool>::type storage;
- - platform_shared_threadpool* const ptr =
- - &reinterpret_cast<platform_shared_threadpool&>(storage);
- - bool initialized_this_time = false;
- -#if defined(__ANDROID__)
- - // mutex based implementation due to paranoia about (lack of) call_once support on Android
- - // remove this if/when call_once is supported
- - static std::mutex mtx;
- - static std::atomic<bool> initialized;
- - abort_if_no_jvm();
- - if (!initialized.load())
- +template<class T>
- +struct uninitialized
- +{
- + union {
- + T storage;
- + };
- +
- + bool initialized;
- +
- + uninitialized() CPPREST_NOEXCEPT : initialized(false) {}
- + uninitialized(const uninitialized&) = delete;
- + uninitialized& operator=(const uninitialized&) = delete;
- + ~uninitialized()
- {
- - std::lock_guard<std::mutex> guard(mtx);
- - if (!initialized.load())
- + if (initialized)
- {
- - ::new (static_cast<void*>(ptr)) platform_shared_threadpool(num_threads);
- - initialized.store(true);
- - initialized_this_time = true;
- + storage.~T();
- }
- - } // also unlock
- + }
- +
- + template<class... Args>
- + void construct(Args&&... vals)
- + {
- + ::new (static_cast<void*>(&storage)) T(std::forward<Args>(vals)...);
- + initialized = true;
- + }
- +};
- +} // unnamed namespace
-
- -#else // ^^^ __ANDROID__ ^^^ // vvv !__ANDROID___ vvv //
- +std::pair<bool, platform_shared_threadpool*> initialize_shared_threadpool(size_t num_threads)
- +{
- + static uninitialized<platform_shared_threadpool> uninit_threadpool;
- + bool initialized_this_time = false;
- static std::once_flag of;
-
- -// #if defined(__ANDROID__) // if call_once can be used for android
- -// abort_if_no_jvm();
- -// #endif // __ANDROID__
- - std::call_once(of, [num_threads, ptr, &initialized_this_time] {
- - ::new (static_cast<void*>(ptr)) platform_shared_threadpool(num_threads);
- + #if defined(__ANDROID__)
- + abort_if_no_jvm();
- + #endif // __ANDROID__
- +
- + std::call_once(of, [num_threads, &initialized_this_time] {
- + uninit_threadpool.construct(num_threads);
- initialized_this_time = true;
- });
- -#endif // __ANDROID__
-
- - return {initialized_this_time, ptr};
- + return {initialized_this_time, &uninit_threadpool.storage};
- }
- }
-
- namespace crossplat
- {
- -threadpool& threadpool::shared_instance()
- -{
- - return initialize_shared_threadpool(40).second->get_shared();
- -}
- -
- +threadpool& threadpool::shared_instance() { return initialize_shared_threadpool(40).second->get_shared(); }
-
- void threadpool::initialize_with_threads(size_t num_threads)
- {
- @@ -196,9 +193,7 @@ void threadpool::initialize_with_threads(size_t num_threads)
- }
-
- #if defined(__ANDROID__)
- -void cpprest_init(JavaVM* vm) {
- - JVM = vm;
- -}
- +void cpprest_init(JavaVM* vm) { JVM = vm; }
- #endif
-
- std::unique_ptr<crossplat::threadpool> crossplat::threadpool::construct(size_t num_threads)
|