diff options
author | Tobias Markmann <tm@ayena.de> | 2014-10-19 20:22:58 (GMT) |
---|---|---|
committer | Tobias Markmann <tm@ayena.de> | 2014-10-20 13:49:33 (GMT) |
commit | 6b22dfcf59474dd016a0355a3102a1dd3692d92c (patch) | |
tree | 2b1fd33be433a91e81fee84fdc2bf1b52575d934 /3rdParty/Boost/src/libs | |
parent | 38b0cb785fea8eae5e48fae56440695fdfd10ee1 (diff) | |
download | swift-6b22dfcf59474dd016a0355a3102a1dd3692d92c.zip swift-6b22dfcf59474dd016a0355a3102a1dd3692d92c.tar.bz2 |
Update Boost in 3rdParty to version 1.56.0.
This updates Boost in our 3rdParty directory to version 1.56.0.
Updated our update.sh script to stop on error.
Changed error reporting in SwiftTools/CrashReporter.cpp to SWIFT_LOG due to
missing include of <iostream> with newer Boost.
Change-Id: I4b35c77de951333979a524097f35f5f83d325edc
Diffstat (limited to '3rdParty/Boost/src/libs')
42 files changed, 1079 insertions, 1006 deletions
diff --git a/3rdParty/Boost/src/libs/atomic/src/lockpool.cpp b/3rdParty/Boost/src/libs/atomic/src/lockpool.cpp new file mode 100644 index 0000000..13269a1 --- /dev/null +++ b/3rdParty/Boost/src/libs/atomic/src/lockpool.cpp @@ -0,0 +1,144 @@ +/* + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * Copyright (c) 2011 Helge Bahmann + * Copyright (c) 2013-2014 Andrey Semashev + */ +/*! + * \file lockpool.cpp + * + * This file contains implementation of the lockpool used to emulate atomic ops. + */ + +#include <cstddef> +#include <boost/config.hpp> +#include <boost/assert.hpp> +#include <boost/memory_order.hpp> +#include <boost/atomic/capabilities.hpp> + +#if BOOST_ATOMIC_FLAG_LOCK_FREE == 2 +#include <boost/atomic/detail/operations_lockfree.hpp> +#elif !defined(BOOST_HAS_PTHREADS) +#error Boost.Atomic: Unsupported target platform, POSIX threads are required when native atomic operations are not available +#else +#include <pthread.h> +#define BOOST_ATOMIC_USE_PTHREAD +#endif + +#include <boost/atomic/detail/lockpool.hpp> +#include <boost/atomic/detail/pause.hpp> + +namespace boost { +namespace atomics { +namespace detail { + +namespace { + +// This seems to be the maximum across all modern CPUs +// NOTE: This constant is made as a macro because some compilers (gcc 4.4 for one) don't allow enums or namespace scope constants in alignment attributes +#define BOOST_ATOMIC_CACHE_LINE_SIZE 64 + +template< unsigned int N > +struct padding +{ + char data[N]; +}; +template< > +struct padding< 0 > +{ +}; + +struct BOOST_ALIGNMENT(BOOST_ATOMIC_CACHE_LINE_SIZE) padded_lock +{ +#if defined(BOOST_ATOMIC_USE_PTHREAD) + typedef pthread_mutex_t lock_type; +#else + typedef atomics::detail::operations< 1u, false > operations; + typedef operations::storage_type lock_type; +#endif + + lock_type lock; + // The additional padding is needed to avoid false sharing between locks + enum { padding_size = (sizeof(lock_type) <= BOOST_ATOMIC_CACHE_LINE_SIZE ? + (BOOST_ATOMIC_CACHE_LINE_SIZE - sizeof(lock_type)) : + (BOOST_ATOMIC_CACHE_LINE_SIZE - sizeof(lock_type) % BOOST_ATOMIC_CACHE_LINE_SIZE)) }; + padding< padding_size > pad; +}; + +static padded_lock g_lock_pool[41] +#if defined(BOOST_ATOMIC_USE_PTHREAD) += +{ + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER +} +#endif +; + +} // namespace + + +#if !defined(BOOST_ATOMIC_USE_PTHREAD) + +// NOTE: This function must NOT be inline. Otherwise MSVC 9 will sometimes generate broken code for modulus operation which result in crashes. +BOOST_ATOMIC_DECL lockpool::scoped_lock::scoped_lock(const volatile void* addr) BOOST_NOEXCEPT : + m_lock(&g_lock_pool[reinterpret_cast< std::size_t >(addr) % (sizeof(g_lock_pool) / sizeof(*g_lock_pool))].lock) +{ + while (padded_lock::operations::test_and_set(*static_cast< padded_lock::lock_type* >(m_lock), memory_order_acquire)) + { + atomics::detail::pause(); + } +} + +BOOST_ATOMIC_DECL lockpool::scoped_lock::~scoped_lock() BOOST_NOEXCEPT +{ + padded_lock::operations::clear(*static_cast< padded_lock::lock_type* >(m_lock), memory_order_release); +} + +BOOST_ATOMIC_DECL void signal_fence() BOOST_NOEXCEPT; + +#else // !defined(BOOST_ATOMIC_USE_PTHREAD) + +BOOST_ATOMIC_DECL lockpool::scoped_lock::scoped_lock(const volatile void* addr) BOOST_NOEXCEPT : + m_lock(&g_lock_pool[reinterpret_cast< std::size_t >(addr) % (sizeof(g_lock_pool) / sizeof(*g_lock_pool))].lock) +{ + BOOST_VERIFY(pthread_mutex_lock(static_cast< pthread_mutex_t* >(m_lock)) == 0); +} + +BOOST_ATOMIC_DECL lockpool::scoped_lock::~scoped_lock() BOOST_NOEXCEPT +{ + BOOST_VERIFY(pthread_mutex_unlock(static_cast< pthread_mutex_t* >(m_lock)) == 0); +} + +#endif // !defined(BOOST_ATOMIC_USE_PTHREAD) + +BOOST_ATOMIC_DECL void lockpool::thread_fence() BOOST_NOEXCEPT +{ +#if BOOST_ATOMIC_THREAD_FENCE > 0 + atomics::detail::thread_fence(memory_order_seq_cst); +#else + // Emulate full fence by locking/unlocking a mutex + scoped_lock lock(0); +#endif +} + +BOOST_ATOMIC_DECL void lockpool::signal_fence() BOOST_NOEXCEPT +{ + // This function is intentionally non-inline, even if empty. This forces the compiler to treat its call as a compiler barrier. +#if BOOST_ATOMIC_SIGNAL_FENCE > 0 + atomics::detail::signal_fence(memory_order_seq_cst); +#endif +} + +} // namespace detail +} // namespace atomics +} // namespace boost diff --git a/3rdParty/Boost/src/libs/date_time/src/gregorian/date_generators.cpp b/3rdParty/Boost/src/libs/date_time/src/gregorian/date_generators.cpp index 4669065..32a58c1 100644 --- a/3rdParty/Boost/src/libs/date_time/src/gregorian/date_generators.cpp +++ b/3rdParty/Boost/src/libs/date_time/src/gregorian/date_generators.cpp @@ -3,7 +3,7 @@ * Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst - * $Date: 2012-09-24 11:08:16 -0700 (Mon, 24 Sep 2012) $ + * $Date$ */ diff --git a/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_month.cpp b/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_month.cpp index cce04f0..8232378 100644 --- a/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_month.cpp +++ b/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_month.cpp @@ -3,7 +3,7 @@ * Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst - * $Date: 2012-09-30 16:25:22 -0700 (Sun, 30 Sep 2012) $ + * $Date$ */ diff --git a/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_names.hpp b/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_names.hpp index 44aa8b8..f20b320 100644 --- a/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_names.hpp +++ b/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_names.hpp @@ -3,7 +3,7 @@ * Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst - * $Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $ + * $Date$ */ diff --git a/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_weekday.cpp b/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_weekday.cpp index fe83c15..ffdc96f 100644 --- a/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_weekday.cpp +++ b/3rdParty/Boost/src/libs/date_time/src/gregorian/greg_weekday.cpp @@ -3,7 +3,7 @@ * Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland, Bart Garst - * $Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $ + * $Date$ */ diff --git a/3rdParty/Boost/src/libs/date_time/src/gregorian/gregorian_types.cpp b/3rdParty/Boost/src/libs/date_time/src/gregorian/gregorian_types.cpp index 341731f..7dd7f22 100644 --- a/3rdParty/Boost/src/libs/date_time/src/gregorian/gregorian_types.cpp +++ b/3rdParty/Boost/src/libs/date_time/src/gregorian/gregorian_types.cpp @@ -3,7 +3,7 @@ * Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland - * $Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $ + * $Date$ */ diff --git a/3rdParty/Boost/src/libs/date_time/src/posix_time/posix_time_types.cpp b/3rdParty/Boost/src/libs/date_time/src/posix_time/posix_time_types.cpp index 4916d36..4395301 100644 --- a/3rdParty/Boost/src/libs/date_time/src/posix_time/posix_time_types.cpp +++ b/3rdParty/Boost/src/libs/date_time/src/posix_time/posix_time_types.cpp @@ -4,7 +4,7 @@ * Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * Author: Jeff Garland - * $Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $ + * $Date$ */ diff --git a/3rdParty/Boost/src/libs/filesystem/src/codecvt_error_category.cpp b/3rdParty/Boost/src/libs/filesystem/src/codecvt_error_category.cpp index 245c3f3..165c6ea 100644 --- a/3rdParty/Boost/src/libs/filesystem/src/codecvt_error_category.cpp +++ b/3rdParty/Boost/src/libs/filesystem/src/codecvt_error_category.cpp @@ -35,11 +35,11 @@ namespace { public: codecvt_error_cat(){} - const char* name() const; + const char* name() const BOOST_SYSTEM_NOEXCEPT; std::string message(int ev) const; }; - const char* codecvt_error_cat::name() const + const char* codecvt_error_cat::name() const BOOST_SYSTEM_NOEXCEPT { return "codecvt"; } diff --git a/3rdParty/Boost/src/libs/filesystem/src/operations.cpp b/3rdParty/Boost/src/libs/filesystem/src/operations.cpp index d066e40..09b8853 100644 --- a/3rdParty/Boost/src/libs/filesystem/src/operations.cpp +++ b/3rdParty/Boost/src/libs/filesystem/src/operations.cpp @@ -73,17 +73,15 @@ using std::wstring; const fs::path dot_dot_path(".."); # include <sys/types.h> # include <sys/stat.h> -# if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(ANDROID) +# if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__ANDROID__) # include <sys/statvfs.h> # define BOOST_STATVFS statvfs # define BOOST_STATVFS_F_FRSIZE vfs.f_frsize -# elif defined (ANDROID) -# include <sys/vfs.h> -# define BOOST_STATVFS statfs -# define BOOST_STATVFS_F_FRSIZE static_cast<boost::uintmax_t>(vfs.f_bsize) # else # ifdef __OpenBSD__ # include <sys/param.h> +# elif defined(__ANDROID__) +# include <sys/vfs.h> # endif # include <sys/mount.h> # define BOOST_STATVFS statfs @@ -777,6 +775,7 @@ namespace detail path canonical(const path& p, const path& base, system::error_code* ec) { path source (p.is_absolute() ? p : absolute(p, base)); + path root(source.root_path()); path result; system::error_code local_ec; @@ -811,7 +810,8 @@ namespace detail continue; if (*itr == dot_dot_path) { - result.remove_filename(); + if (result != root) + result.remove_filename(); continue; } @@ -931,6 +931,7 @@ namespace detail } path parent = p.parent_path(); + BOOST_ASSERT_MSG(parent != p, "internal error: p == p.parent_path()"); if (!parent.empty()) { // determine if the parent exists @@ -1411,7 +1412,7 @@ namespace detail // - See the fchmodat() Linux man page: // "http://man7.org/linux/man-pages/man2/fchmodat.2.html" # if defined(AT_FDCWD) && defined(AT_SYMLINK_NOFOLLOW) \ - && !(defined(__SUNPRO_CC) || defined(sun)) \ + && !(defined(__SUNPRO_CC) || defined(__sun) || defined(sun)) \ && !(defined(linux) || defined(__linux) || defined(__linux__)) if (::fchmodat(AT_FDCWD, p.c_str(), mode_cast(prms), !(prms & symlink_perms) ? 0 : AT_SYMLINK_NOFOLLOW)) diff --git a/3rdParty/Boost/src/libs/filesystem/src/path.cpp b/3rdParty/Boost/src/libs/filesystem/src/path.cpp index c740dec..a3b3710 100644 --- a/3rdParty/Boost/src/libs/filesystem/src/path.cpp +++ b/3rdParty/Boost/src/libs/filesystem/src/path.cpp @@ -27,6 +27,10 @@ #include <boost/scoped_array.hpp> #include <boost/system/error_code.hpp> #include <boost/assert.hpp> +//#include <boost/detail/lightweight_mutex.hpp> +// fails on VC++ static builds because the runtime does not permit use of locks in +// staticly initialized code, and VC++ 2010 (and probably other versions) statically +// initializes some instances of class path. #include <algorithm> #include <cstddef> #include <cstring> @@ -35,7 +39,7 @@ #ifdef BOOST_WINDOWS_API # include "windows_file_codecvt.hpp" # include <windows.h> -#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) || defined(__FreeBSD__) # include <boost/filesystem/detail/utf8_codecvt_facet.hpp> #endif @@ -98,7 +102,6 @@ namespace const char* const separators = "/"; const char* separator_string = "/"; const char* preferred_separator_string = "/"; - const char colon = ':'; const char dot = '.'; const fs::path dot_path("."); const fs::path dot_dot_path(".."); @@ -510,7 +513,7 @@ namespace size_type pos(str.find_last_of(separators, end_pos-1)); # ifdef BOOST_WINDOWS_API - if (pos == string_type::npos) + if (pos == string_type::npos && end_pos > 1) pos = str.find_last_of(colon, end_pos-2); # endif @@ -783,147 +786,103 @@ namespace filesystem } // namespace filesystem } // namespace boost -//--------------------------------------------------------------------------------------// -// // -// detail helpers // -// // -//--------------------------------------------------------------------------------------// - namespace { //------------------------------------------------------------------------------------// - // locale helpers // + // locale helpers // //------------------------------------------------------------------------------------// -#if defined(BOOST_WINDOWS_API) && defined(BOOST_FILESYSTEM_STATIC_LINK) + // Prior versions of these locale and codecvt implementations tried to take advantage + // of static initialization where possible, kept a local copy of the current codecvt + // facet (to avoid codecvt() having to call use_facet()), and was not multi-threading + // safe (again for efficiency). + // + // This was error prone, and required different implementation techniques depending + // on the compiler and also whether static or dynamic linking was used. Furthermore, + // users could not easily provide their multi-threading safe wrappers because the + // path interface requires the implementation itself to call codecvt() to obtain the + // default facet, and the initialization of the static within path_locale() could race. + // + // The code below is portable to all platforms, is much simpler, and hopefully will be + // much more robust. Timing tests (on Windows, using a Visual C++ release build) + // indicated the current code is roughly 9% slower than the previous code, and that + // seems a small price to pay for better code that is easier to use. + + //boost::detail::lightweight_mutex locale_mutex; inline std::locale default_locale() { +# if defined(BOOST_WINDOWS_API) std::locale global_loc = std::locale(); - std::locale loc(global_loc, new windows_file_codecvt); - return loc; + return std::locale(global_loc, new windows_file_codecvt); +# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) || defined(__FreeBSD__) + // "All BSD system functions expect their string parameters to be in UTF-8 encoding + // and nothing else." See + // http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPInternational/Articles/FileEncodings.html + // + // "The kernel will reject any filename that is not a valid UTF-8 string, and it will + // even be normalized (to Unicode NFD) before stored on disk, at least when using HFS. + // The right way to deal with it would be to always convert the filename to UTF-8 + // before trying to open/create a file." See + // http://lists.apple.com/archives/unix-porting/2007/Sep/msg00023.html + // + // "How a file name looks at the API level depends on the API. Current Carbon APIs + // handle file names as an array of UTF-16 characters; POSIX ones handle them as an + // array of UTF-8, which is why UTF-8 works well in Terminal. How it's stored on disk + // depends on the disk format; HFS+ uses UTF-16, but that's not important in most + // cases." See + // http://lists.apple.com/archives/applescript-users/2002/Sep/msg00319.html + // + // Many thanks to Peter Dimov for digging out the above references! + + std::locale global_loc = std::locale(); + return std::locale(global_loc, new boost::filesystem::detail::utf8_codecvt_facet); +# else // Other POSIX + // ISO C calls std::locale("") "the locale-specific native environment", and this + // locale is the default for many POSIX-based operating systems such as Linux. + return std::locale(""); +# endif } inline std::locale& path_locale() + // std::locale("") construction, needed on non-Apple POSIX systems, can throw + // (if environmental variables LC_MESSAGES or LANG are wrong, for example), so + // path_locale() provides lazy initialization via a local static to ensure that any + // exceptions occur after main() starts and so can be caught. Furthermore, + // path_locale() is only called if path::codecvt() or path::imbue() are themselves + // actually called, ensuring that an exception will only be thrown if std::locale("") + // is really needed. { static std::locale loc(default_locale()); return loc; } - - inline const path::codecvt_type*& codecvt_facet_ptr() - { - static const std::codecvt<wchar_t, char, std::mbstate_t>* - facet( - &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> > - (path_locale())); - return facet; - } - -#elif defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_STATIC_LINK) - - std::locale path_locale(std::locale(), new windows_file_codecvt); - - const std::codecvt<wchar_t, char, std::mbstate_t>* - codecvt_facet_ptr(&std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> > - (path_locale)); - -#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) - - // "All BSD system functions expect their string parameters to be in UTF-8 encoding - // and nothing else." See - // http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPInternational/Articles/FileEncodings.html - // - // "The kernel will reject any filename that is not a valid UTF-8 string, and it will - // even be normalized (to Unicode NFD) before stored on disk, at least when using HFS. - // The right way to deal with it would be to always convert the filename to UTF-8 - // before trying to open/create a file." See - // http://lists.apple.com/archives/unix-porting/2007/Sep/msg00023.html - // - // "How a file name looks at the API level depends on the API. Current Carbon APIs - // handle file names as an array of UTF-16 characters; POSIX ones handle them as an - // array of UTF-8, which is why UTF-8 works well in Terminal. How it's stored on disk - // depends on the disk format; HFS+ uses UTF-16, but that's not important in most - // cases." See - // http://lists.apple.com/archives/applescript-users/2002/Sep/msg00319.html - // - // Many thanks to Peter Dimov for digging out the above references! - - std::locale path_locale(std::locale(), - new boost::filesystem::detail::utf8_codecvt_facet); - - const std::codecvt<wchar_t, char, std::mbstate_t>* - codecvt_facet_ptr(&std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> > - (path_locale)); - -#else // Other POSIX - - // ISO C calls std::locale("") "the locale-specific native environment", and this - // locale is the default for many POSIX-based operating systems such as Linux. - - // std::locale("") construction can throw (if environmental variables LC_MESSAGES or - // or LANG are wrong, for example), so lazy initialization is used to ensure - // that exceptions occur after main() starts and so can be caught. - - std::locale path_locale; // initialized by path::codecvt() below - const std::codecvt<wchar_t, char, std::mbstate_t>* codecvt_facet_ptr; // ditto - -# endif - } // unnamed namespace //--------------------------------------------------------------------------------------// -// path::imbue implementation // +// path::codecvt() and path::imbue() implementation // //--------------------------------------------------------------------------------------// namespace boost { namespace filesystem { - -#if defined(BOOST_WINDOWS_API) && defined(BOOST_FILESYSTEM_STATIC_LINK) + // See comments above const path::codecvt_type& path::codecvt() { - BOOST_ASSERT_MSG(codecvt_facet_ptr(), "codecvt_facet_ptr() facet hasn't been properly initialized"); - return *codecvt_facet_ptr(); + BOOST_ASSERT_MSG(&path_locale(), "boost::filesystem::path locale initialization error"); +// boost::detail::lightweight_mutex::scoped_lock lock(locale_mutex); + return std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(path_locale()); } - std::locale path::imbue(const std::locale & loc) + std::locale path::imbue(const std::locale& loc) { +// boost::detail::lightweight_mutex::scoped_lock lock(locale_mutex); std::locale temp(path_locale()); path_locale() = loc; - codecvt_facet_ptr() = - &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(path_locale()); - return temp; - } - -#else - - const path::codecvt_type& path::codecvt() - { -# if defined(BOOST_POSIX_API) && \ - !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) - // A local static initialized by calling path::imbue ensures that std::locale(""), - // which may throw, is called only if path_locale and condecvt_facet will actually - // be used. Thus misconfigured environmental variables will only cause an - // exception if a valid std::locale("") is actually needed. - static std::locale posix_lazy_initialization(path::imbue(std::locale(""))); -# endif - return *codecvt_facet_ptr; - } - - std::locale path::imbue(const std::locale& loc) - { - std::locale temp(path_locale); - path_locale = loc; - codecvt_facet_ptr = - &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(path_locale); return temp; } - -#endif - } // namespace filesystem } // namespace boost diff --git a/3rdParty/Boost/src/libs/program_options/src/cmdline.cpp b/3rdParty/Boost/src/libs/program_options/src/cmdline.cpp index cd9a5fe..d7910c2 100644 --- a/3rdParty/Boost/src/libs/program_options/src/cmdline.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/cmdline.cpp @@ -455,7 +455,7 @@ namespace boost { namespace program_options { namespace detail { // if they look like options if (opt.value.size() <= min_tokens) { - min_tokens -= static_cast<unsigned>(opt.value.size()); + min_tokens -= static_cast<unsigned>(opt.value.size()); } else { diff --git a/3rdParty/Boost/src/libs/program_options/src/options_description.cpp b/3rdParty/Boost/src/libs/program_options/src/options_description.cpp index 343bd30..9d51ce9 100644 --- a/3rdParty/Boost/src/libs/program_options/src/options_description.cpp +++ b/3rdParty/Boost/src/libs/program_options/src/options_description.cpp @@ -604,12 +604,9 @@ namespace boost { namespace program_options { } } - void - options_description::print(std::ostream& os) const + unsigned + options_description::get_option_column_width() const { - if (!m_caption.empty()) - os << m_caption << ":\n"; - /* Find the maximum width of the option column */ unsigned width(23); unsigned i; // vc6 has broken for loop scoping @@ -620,6 +617,11 @@ namespace boost { namespace program_options { ss << " " << opt.format_name() << ' ' << opt.format_parameter(); width = (max)(width, static_cast<unsigned>(ss.str().size())); } + + /* Get width of groups as well*/ + for (unsigned j = 0; j < groups.size(); ++j) + width = max(width, groups[j]->get_option_column_width()); + /* this is the column were description should start, if first column is longer, we go to a new line */ const unsigned start_of_description_column = m_line_length - m_min_description_length; @@ -628,9 +630,20 @@ namespace boost { namespace program_options { /* add an additional space to improve readability */ ++width; - + return width; + } + + void + options_description::print(std::ostream& os, unsigned width) const + { + if (!m_caption.empty()) + os << m_caption << ":\n"; + + if (!width) + width = get_option_column_width(); + /* The options formatting style is stolen from Subversion. */ - for (i = 0; i < m_options.size(); ++i) + for (unsigned i = 0; i < m_options.size(); ++i) { if (belong_to_group[i]) continue; @@ -643,7 +656,8 @@ namespace boost { namespace program_options { } for (unsigned j = 0; j < groups.size(); ++j) { - os << "\n" << *groups[j]; + os << "\n"; + groups[j]->print(os, width); } } diff --git a/3rdParty/Boost/src/libs/regex/src/c_regex_traits.cpp b/3rdParty/Boost/src/libs/regex/src/c_regex_traits.cpp index 6701020..23ec324 100644 --- a/3rdParty/Boost/src/libs/regex/src/c_regex_traits.cpp +++ b/3rdParty/Boost/src/libs/regex/src/c_regex_traits.cpp @@ -54,6 +54,19 @@ c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::transfo std::string src(p1, p2); while(s < (r = std::strxfrm(&*result.begin(), src.c_str(), s))) { +#if defined(_CPPLIB_VER) + // + // A bug in VC11 and 12 causes the program to hang if we pass a null-string + // to std::strxfrm, but only for certain locales :-( + // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware). + // + if(r == INT_MAX) + { + result.erase(); + result.insert(result.begin(), static_cast<char>(0)); + return result; + } +#endif result.append(r - s + 3, ' '); s = result.size(); } diff --git a/3rdParty/Boost/src/libs/regex/src/posix_api.cpp b/3rdParty/Boost/src/libs/regex/src/posix_api.cpp index e59c19e..8a803b3 100644 --- a/3rdParty/Boost/src/libs/regex/src/posix_api.cpp +++ b/3rdParty/Boost/src/libs/regex/src/posix_api.cpp @@ -125,7 +125,7 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA* expression, const char #endif expression->re_magic = magic_value; static_cast<c_regex_type*>(expression->guts)->set_expression(ptr, p2, flags); - expression->re_nsub = static_cast<c_regex_type*>(expression->guts)->mark_count() - 1; + expression->re_nsub = static_cast<c_regex_type*>(expression->guts)->mark_count(); result = static_cast<c_regex_type*>(expression->guts)->error_code(); #ifndef BOOST_NO_EXCEPTIONS } diff --git a/3rdParty/Boost/src/libs/regex/src/static_mutex.cpp b/3rdParty/Boost/src/libs/regex/src/static_mutex.cpp index d14feb1..d02b01f 100644 --- a/3rdParty/Boost/src/libs/regex/src/static_mutex.cpp +++ b/3rdParty/Boost/src/libs/regex/src/static_mutex.cpp @@ -18,6 +18,7 @@ #define BOOST_REGEX_SOURCE #include <boost/config.hpp> +#include <boost/assert.hpp> #ifdef BOOST_HAS_THREADS @@ -54,8 +55,8 @@ void scoped_static_mutex_lock::lock() { if(0 == m_have_lock) { - pthread_mutex_lock(&(m_mutex.m_mutex)); - m_have_lock = true; + // Client code will throw if this fails: + m_have_lock = (pthread_mutex_lock(&(m_mutex.m_mutex)) == 0); } } @@ -63,7 +64,10 @@ void scoped_static_mutex_lock::unlock() { if(m_have_lock) { - pthread_mutex_unlock(&(m_mutex.m_mutex)); + // If this fails there's nothing we can do except assert, + // exceptions are out of the question as this code is called + // from the lock's destructor: + BOOST_VERIFY(pthread_mutex_unlock(&(m_mutex.m_mutex)) == 0); m_have_lock = false; } } @@ -157,7 +161,7 @@ void scoped_static_mutex_lock::lock() { boost::call_once(static_mutex::m_once,&static_mutex::init); if(0 == m_plock) - m_plock = new boost::recursive_mutex::scoped_lock(*static_mutex::m_pmutex, boost::defer_lock); + m_plock = new boost::unique_lock<boost::recursive_mutex>(*static_mutex::m_pmutex, boost::defer_lock); m_plock->lock(); m_have_lock = true; } diff --git a/3rdParty/Boost/src/libs/regex/src/w32_regex_traits.cpp b/3rdParty/Boost/src/libs/regex/src/w32_regex_traits.cpp index 8c22214..cf4dc10 100644 --- a/3rdParty/Boost/src/libs/regex/src/w32_regex_traits.cpp +++ b/3rdParty/Boost/src/libs/regex/src/w32_regex_traits.cpp @@ -283,9 +283,11 @@ BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, l if (r == 0) return def; - LPSTR buf = (LPSTR)_alloca( (r + 1) * 2 ); - if (::WideCharToMultiByte(CP_ACP, 0, wbuf, r, buf, (r + 1) * 2, NULL, NULL) == 0) - return def; + + int buf_size = 1 + ::WideCharToMultiByte(CP_ACP, 0, wbuf, r, NULL, 0, NULL, NULL); + LPSTR buf = (LPSTR)_alloca(buf_size); + if (::WideCharToMultiByte(CP_ACP, 0, wbuf, r, buf, buf_size, NULL, NULL) == 0) + return def; // failed conversion. #endif return std::string(buf); } @@ -485,7 +487,7 @@ BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type idx) return c; if (::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0) - return c; + return c; // No single byte lower case equivalent available #endif return result[0]; } @@ -556,7 +558,7 @@ BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type idx) return c; if (::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0) - return c; + return c; // No single byte upper case equivalent available. #endif return result[0]; } diff --git a/3rdParty/Boost/src/libs/regex/src/wc_regex_traits.cpp b/3rdParty/Boost/src/libs/regex/src/wc_regex_traits.cpp index b3d2c5a..7815a09 100644 --- a/3rdParty/Boost/src/libs/regex/src/wc_regex_traits.cpp +++ b/3rdParty/Boost/src/libs/regex/src/wc_regex_traits.cpp @@ -94,6 +94,19 @@ c_regex_traits<wchar_t>::string_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::t std::wstring result(s, L' '); while(s < (r = std::wcsxfrm(&*result.begin(), src.c_str(), s))) { +#if defined(_CPPLIB_VER) + // + // A bug in VC11 and 12 causes the program to hang if we pass a null-string + // to std::strxfrm, but only for certain locales :-( + // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware). + // + if(r == INT_MAX) + { + result.erase(); + result.insert(result.begin(), static_cast<wchar_t>(0)); + return result; + } +#endif result.append(r - s + 3, L' '); s = result.size(); } diff --git a/3rdParty/Boost/src/libs/regex/src/wide_posix_api.cpp b/3rdParty/Boost/src/libs/regex/src/wide_posix_api.cpp index ff5c90d..41704cd 100644 --- a/3rdParty/Boost/src/libs/regex/src/wide_posix_api.cpp +++ b/3rdParty/Boost/src/libs/regex/src/wide_posix_api.cpp @@ -135,7 +135,7 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wcha #endif expression->re_magic = wmagic_value; static_cast<wc_regex_type*>(expression->guts)->set_expression(ptr, p2, flags); - expression->re_nsub = static_cast<wc_regex_type*>(expression->guts)->mark_count() - 1; + expression->re_nsub = static_cast<wc_regex_type*>(expression->guts)->mark_count(); result = static_cast<wc_regex_type*>(expression->guts)->error_code(); #ifndef BOOST_NO_EXCEPTIONS } diff --git a/3rdParty/Boost/src/libs/serialization/src/archive_exception.cpp b/3rdParty/Boost/src/libs/serialization/src/archive_exception.cpp index 50d326a..d06303f 100644 --- a/3rdParty/Boost/src/libs/serialization/src/archive_exception.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/archive_exception.cpp @@ -13,7 +13,7 @@ #endif #include <exception> -#include <boost/assert.hpp> +//#include <boost/assert.hpp> #include <string> #define BOOST_ARCHIVE_SOURCE @@ -22,6 +22,18 @@ namespace boost { namespace archive { +unsigned int +archive_exception::append(unsigned int l, const char * a){ + while(l < (sizeof(m_buffer) - 1)){ + char c = *a++; + if('\0' == c) + break; + m_buffer[l++] = c; + } + m_buffer[l] = '\0'; + return l; +} + BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) archive_exception::archive_exception( exception_code c, @@ -30,80 +42,81 @@ archive_exception::archive_exception( ) : code(c) { - m_msg = "programming error"; + unsigned int length = 0; switch(code){ case no_exception: - m_msg = "uninitialized exception"; + length = append(length, "uninitialized exception"); break; case unregistered_class: - m_msg = "unregistered class"; + length = append(length, "unregistered class"); if(NULL != e1){ - m_msg += " - "; - m_msg += e1; + length = append(length, " - "); + length = append(length, e1); } break; case invalid_signature: - m_msg = "invalid signature"; + length = append(length, "invalid signature"); break; case unsupported_version: - m_msg = "unsupported version"; + length = append(length, "unsupported version"); break; case pointer_conflict: - m_msg = "pointer conflict"; + length = append(length, "pointer conflict"); break; case incompatible_native_format: - m_msg = "incompatible native format"; + length = append(length, "incompatible native format"); if(NULL != e1){ - m_msg += " - "; - m_msg += e1; + length = append(length, " - "); + length = append(length, e1); } break; case array_size_too_short: - m_msg = "array size too short"; + length = append(length, "array size too short"); break; case input_stream_error: - m_msg = "input stream error"; + length = append(length, "input stream error"); break; case invalid_class_name: - m_msg = "class name too long"; + length = append(length, "class name too long"); break; case unregistered_cast: - m_msg = "unregistered void cast "; - m_msg += (NULL != e1) ? e1 : "?"; - m_msg += "<-"; - m_msg += (NULL != e2) ? e2 : "?"; + length = append(length, "unregistered void cast "); + length = append(length, (NULL != e1) ? e1 : "?"); + length = append(length, "<-"); + length = append(length, (NULL != e2) ? e2 : "?"); break; case unsupported_class_version: - m_msg = "class version "; - m_msg += (NULL != e1) ? e1 : "<unknown class>"; + length = append(length, "class version "); + length = append(length, (NULL != e1) ? e1 : "<unknown class>"); break; case other_exception: // if get here - it indicates a derived exception // was sliced by passing by value in catch - m_msg = "unknown derived exception"; + length = append(length, "unknown derived exception"); break; case multiple_code_instantiation: - m_msg = "code instantiated in more than one module"; + length = append(length, "code instantiated in more than one module"); if(NULL != e1){ - m_msg += " - "; - m_msg += e1; + length = append(length, " - "); + length = append(length, e1); } break; case output_stream_error: - m_msg = "output stream error"; + length = append(length, "output stream error"); break; default: BOOST_ASSERT(false); + length = append(length, "programming error"); break; } } BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) -archive_exception::~archive_exception() throw () {} +archive_exception::~archive_exception() throw() {} BOOST_ARCHIVE_DECL(const char *) archive_exception::what( ) const throw() { - return m_msg.c_str(); + return m_buffer; } BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) archive_exception::archive_exception() : diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_archive.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_archive.cpp index 23e5702..8baf178 100644 --- a/3rdParty/Boost/src/libs/serialization/src/basic_archive.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/basic_archive.cpp @@ -70,10 +70,11 @@ BOOST_ARCHIVE_SIGNATURE(){ // 8 - Boost 1.44 // separated version_type into library_version_type and class_version_type // changed version_type to be stored as 8 bits. +// 10- fixed base64 output/input. BOOST_ARCHIVE_DECL(library_version_type) BOOST_ARCHIVE_VERSION(){ - return library_version_type(9); + return library_version_type(11); } } // namespace archive diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_iarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_iarchive.cpp index e9baddd..3a24690 100644 --- a/3rdParty/Boost/src/libs/serialization/src/basic_iarchive.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/basic_iarchive.cpp @@ -81,9 +81,18 @@ class basic_iarchive_impl { ////////////////////////////////////////////////////////////////////// // used to implement the reset_object_address operation. - object_id_type moveable_objects_start; - object_id_type moveable_objects_end; - object_id_type moveable_objects_recent; + struct moveable_objects { + object_id_type start; + object_id_type end; + object_id_type recent; + bool is_pointer; + moveable_objects() : + start(0), + end(0), + recent(0), + is_pointer(false) + {} + } m_moveable_objects; void reset_object_address( const void * new_address, @@ -159,19 +168,20 @@ class basic_iarchive_impl { ////////////////////////////////////////////////////////////////////// // address of the most recent object serialized as a poiner // whose data itself is now pending serialization - void * pending_object; - const basic_iserializer * pending_bis; - version_type pending_version; + struct pending { + void * object; + const basic_iserializer * bis; + version_type version; + pending() : + object(NULL), + bis(NULL), + version(0) + {} + } m_pending; basic_iarchive_impl(unsigned int flags) : m_archive_library_version(BOOST_ARCHIVE_VERSION()), - m_flags(flags), - moveable_objects_start(0), - moveable_objects_end(0), - moveable_objects_recent(0), - pending_object(NULL), - pending_bis(NULL), - pending_version(0) + m_flags(flags) {} ~basic_iarchive_impl(){} void set_library_version(library_version_type archive_library_version){ @@ -200,7 +210,7 @@ class basic_iarchive_impl { //public: void next_object_pointer(void * t){ - pending_object = t; + m_pending.object = t; } void delete_created_pointers(); class_id_type register_type( @@ -224,9 +234,12 @@ class basic_iarchive_impl { inline void basic_iarchive_impl::reset_object_address( - const void * new_address, - const void *old_address + void const * const new_address, + void const * const old_address ){ + if(m_moveable_objects.is_pointer) + return; + // this code handles a couple of situations. // a) where reset_object_address is applied to an untracked object. // In such a case the call is really superfluous and its really an @@ -240,18 +253,18 @@ basic_iarchive_impl::reset_object_address( // of the programmer but we can't detect it - as above. So maybe we // can save a few more people from themselves as above. object_id_type i; - for(i = moveable_objects_recent; i < moveable_objects_end; ++i){ + for(i = m_moveable_objects.recent; i < m_moveable_objects.end; ++i){ if(old_address == object_id_vector[i].address) break; } - for(; i < moveable_objects_end; ++i){ - + for(; i < m_moveable_objects.end; ++i){ + void const * const this_address = object_id_vector[i].address; // calculate displacement from this level // warning - pointer arithmetic on void * is in herently non-portable // but expected to work on all platforms in current usage - if(object_id_vector[i].address > old_address){ + if(this_address > old_address){ std::size_t member_displacement - = reinterpret_cast<std::size_t>(object_id_vector[i].address) + = reinterpret_cast<std::size_t>(this_address) - reinterpret_cast<std::size_t>(old_address); object_id_vector[i].address = reinterpret_cast<void *>( reinterpret_cast<std::size_t>(new_address) + member_displacement @@ -260,7 +273,7 @@ basic_iarchive_impl::reset_object_address( else{ std::size_t member_displacement = reinterpret_cast<std::size_t>(old_address) - - reinterpret_cast<std::size_t>(object_id_vector[i].address); + - reinterpret_cast<std::size_t>(this_address); object_id_vector[i].address = reinterpret_cast<void *>( reinterpret_cast<std::size_t>(new_address) - member_displacement ); @@ -356,10 +369,12 @@ basic_iarchive_impl::load_object( void * t, const basic_iserializer & bis ){ + m_moveable_objects.is_pointer = false; + serialization::state_saver<bool> ss_is_pointer(m_moveable_objects.is_pointer); // if its been serialized through a pointer and the preamble's been done - if(t == pending_object && & bis == pending_bis){ + if(t == m_pending.object && & bis == m_pending.bis){ // read data - (bis.load_object_data)(ar, t, pending_version); + (bis.load_object_data)(ar, t, m_pending.version); return; } @@ -370,13 +385,13 @@ basic_iarchive_impl::load_object( load_preamble(ar, co); // save the current move stack position in case we want to truncate it - boost::serialization::state_saver<object_id_type> w(moveable_objects_start); + boost::serialization::state_saver<object_id_type> ss_start(m_moveable_objects.start); // note: extra line used to evade borland issue const bool tracking = co.tracking_level; object_id_type this_id; - moveable_objects_start = + m_moveable_objects.start = this_id = object_id_type(object_id_vector.size()); // if we tracked this object when the archive was saved @@ -388,11 +403,11 @@ basic_iarchive_impl::load_object( // add a new enty into the tracking list object_id_vector.push_back(aobject(t, cid)); // and add an entry for this object - moveable_objects_end = object_id_type(object_id_vector.size()); + m_moveable_objects.end = object_id_type(object_id_vector.size()); } // read data (bis.load_object_data)(ar, t, co.file_version); - moveable_objects_recent = this_id; + m_moveable_objects.recent = this_id; } inline const basic_pointer_iserializer * @@ -403,8 +418,10 @@ basic_iarchive_impl::load_pointer( const basic_pointer_iserializer * (*finder)( const boost::serialization::extended_type_info & type_ ) - ){ + m_moveable_objects.is_pointer = true; + serialization::state_saver<bool> w(m_moveable_objects.is_pointer); + class_id_type cid; load(ar, cid); @@ -434,10 +451,10 @@ basic_iarchive_impl::load_pointer( bpis_ptr = (*finder)(*eti); } BOOST_ASSERT(NULL != bpis_ptr); - class_id_type new_cid = register_type(bpis_ptr->get_basic_serializer()); + // class_id_type new_cid = register_type(bpis_ptr->get_basic_serializer()); + BOOST_VERIFY(register_type(bpis_ptr->get_basic_serializer()) == cid); int i = cid; cobject_id_vector[i].bpis_ptr = bpis_ptr; - BOOST_ASSERT(new_cid == cid); } int i = cid; cobject_id & co = cobject_id_vector[i]; @@ -453,38 +470,41 @@ basic_iarchive_impl::load_pointer( return bpis_ptr; // save state - serialization::state_saver<object_id_type> w_start(moveable_objects_start); + serialization::state_saver<object_id_type> w_start(m_moveable_objects.start); + + // allocate space on the heap for the object - to be constructed later + t = bpis_ptr->heap_allocation(); + BOOST_ASSERT(NULL != t); if(! tracking){ bpis_ptr->load_object_ptr(ar, t, co.file_version); } else{ - serialization::state_saver<void *> x(pending_object); - serialization::state_saver<const basic_iserializer *> y(pending_bis); - serialization::state_saver<version_type> z(pending_version); + serialization::state_saver<void *> x(m_pending.object); + serialization::state_saver<const basic_iserializer *> y(m_pending.bis); + serialization::state_saver<version_type> z(m_pending.version); - pending_bis = & bpis_ptr->get_basic_serializer(); - pending_version = co.file_version; + m_pending.bis = & bpis_ptr->get_basic_serializer(); + m_pending.version = co.file_version; // predict next object id to be created const unsigned int ui = object_id_vector.size(); - serialization::state_saver<object_id_type> w_end(moveable_objects_end); + serialization::state_saver<object_id_type> w_end(m_moveable_objects.end); - // because the following operation could move the items - // don't use co after this + // add to list of serialized objects so that we can properly handle // cyclic strucures object_id_vector.push_back(aobject(t, cid)); + // remember that that the address of these elements could change + // when we make another call so don't use the address bpis_ptr->load_object_ptr( - ar, - object_id_vector[ui].address, - co.file_version + ar, + t, + m_pending.version ); - t = object_id_vector[ui].address; object_id_vector[ui].loaded_as_pointer = true; - BOOST_ASSERT(NULL != t); } return bpis_ptr; diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_oarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_oarchive.cpp index 33f33f8..840955b 100644 --- a/3rdParty/Boost/src/libs/serialization/src/basic_oarchive.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/basic_oarchive.cpp @@ -331,6 +331,12 @@ basic_oarchive_impl::save_pointer( // makes a copy when passing a non-const to a const. This // is permitted by the standard but rarely seen in practice const class_name_type cn(key); + if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) + boost::serialization::throw_exception( + boost::archive::archive_exception( + boost::archive::archive_exception:: + invalid_class_name) + ); // write out the external class identifier ar.vsave(cn); } diff --git a/3rdParty/Boost/src/libs/serialization/src/basic_serializer_map.cpp b/3rdParty/Boost/src/libs/serialization/src/basic_serializer_map.cpp index 80e805f..7df0b3d 100644 --- a/3rdParty/Boost/src/libs/serialization/src/basic_serializer_map.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/basic_serializer_map.cpp @@ -43,11 +43,12 @@ basic_serializer_map::type_info_pointer_compare::operator()( BOOST_ARCHIVE_DECL(bool) basic_serializer_map::insert(const basic_serializer * bs){ // attempt to insert serializer into it's map - const std::pair<map_type::iterator, bool> result = - m_map.insert(bs); // the following is commented out - rather than being just // deleted as a reminder not to try this. + // const std::pair<map_type::iterator, bool> result = + m_map.insert(bs); + // At first it seemed like a good idea. It enforced the // idea that a type be exported from at most one code module // (DLL or mainline). This would enforce a "one definition rule" diff --git a/3rdParty/Boost/src/libs/serialization/src/binary_iarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/binary_iarchive.cpp index 7bb0435..c1117e9 100644 --- a/3rdParty/Boost/src/libs/serialization/src/binary_iarchive.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/binary_iarchive.cpp @@ -22,20 +22,6 @@ namespace boost { namespace archive { // explicitly instantiate for this type of stream -template class detail::archive_serializer_map<naked_binary_iarchive>; -template class basic_binary_iprimitive< - naked_binary_iarchive, - std::istream::char_type, - std::istream::traits_type ->; -template class basic_binary_iarchive<naked_binary_iarchive> ; -template class binary_iarchive_impl< - naked_binary_iarchive, - std::istream::char_type, - std::istream::traits_type ->; - -// explicitly instantiate for this type of stream template class detail::archive_serializer_map<binary_iarchive>; template class basic_binary_iprimitive< binary_iarchive, diff --git a/3rdParty/Boost/src/libs/serialization/src/binary_wiarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/binary_wiarchive.cpp index a6135c8..720d469 100644 --- a/3rdParty/Boost/src/libs/serialization/src/binary_wiarchive.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/binary_wiarchive.cpp @@ -26,19 +26,6 @@ namespace boost { namespace archive { -template class detail::archive_serializer_map<naked_binary_wiarchive>; -template class basic_binary_iprimitive< - naked_binary_wiarchive, - wchar_t, - std::char_traits<wchar_t> ->; -template class basic_binary_iarchive<naked_binary_wiarchive> ; -template class binary_iarchive_impl< - naked_binary_wiarchive, - wchar_t, - std::char_traits<wchar_t> ->; - // explicitly instantiate for this type of text stream template class detail::archive_serializer_map<binary_wiarchive>; template class basic_binary_iprimitive< diff --git a/3rdParty/Boost/src/libs/serialization/src/shared_ptr_helper.cpp b/3rdParty/Boost/src/libs/serialization/src/shared_ptr_helper.cpp index b155cd9..15102e2 100644 --- a/3rdParty/Boost/src/libs/serialization/src/shared_ptr_helper.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/shared_ptr_helper.cpp @@ -1,8 +1,3 @@ -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // shared_ptr_helper.hpp: serialization for boost shared pointern @@ -17,6 +12,7 @@ #include <list> #include <utility> #include <cstddef> // NULL +#include <cassert> #define BOOST_ARCHIVE_SOURCE // include this to prevent linker errors when the @@ -26,113 +22,42 @@ #include <boost/serialization/throw_exception.hpp> #include <boost/serialization/void_cast.hpp> #include <boost/serialization/extended_type_info.hpp> -#include <boost/archive/shared_ptr_helper.hpp> +#include <boost/serialization/shared_ptr_helper.hpp> #include <boost/archive/archive_exception.hpp> namespace boost { -namespace archive{ -namespace detail { +namespace serialization { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // a common class for holding various types of shared pointers -// returns pointer to object and an indicator whether this is a -// new entry (true) or a previous one (false) -BOOST_ARCHIVE_DECL(shared_ptr<void>) -shared_ptr_helper::get_od( - const void * t, - const boost::serialization::extended_type_info * true_type, - const boost::serialization::extended_type_info * this_type -){ - // get void pointer to the most derived type - // this uniquely identifies the object referred to - const void * od = void_downcast( - *true_type, - *this_type, - t - ); - if(NULL == od) - boost::serialization::throw_exception( - archive_exception( - archive_exception::unregistered_cast, - true_type->get_debug_info(), - this_type->get_debug_info() - ) - ); - - // make tracking array if necessary - if(NULL == m_pointers) - m_pointers = new collection_type; - - //shared_ptr<const void> sp(od, null_deleter()); - shared_ptr<const void> sp(od, null_deleter()); - collection_type::iterator i = m_pointers->find(sp); - - if(i == m_pointers->end()){ - shared_ptr<void> np; - return np; - } - od = void_upcast( - *true_type, - *this_type, - i->get() - ); - if(NULL == od) - boost::serialization::throw_exception( - archive_exception( - archive_exception::unregistered_cast, - true_type->get_debug_info(), - this_type->get_debug_info() - ) - ); - - return shared_ptr<void>( - const_pointer_cast<void>(*i), - const_cast<void *>(od) - ); -} - -BOOST_ARCHIVE_DECL(void) -shared_ptr_helper::append(const boost::shared_ptr<const void> &sp){ - // make tracking array if necessary - if(NULL == m_pointers) - m_pointers = new collection_type; - - collection_type::iterator i = m_pointers->find(sp); - - if(i == m_pointers->end()){ - std::pair<collection_type::iterator, bool> result; - result = m_pointers->insert(sp); - BOOST_ASSERT(result.second); - } -} - // #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP BOOST_ARCHIVE_DECL(void) -shared_ptr_helper::append(const boost_132::shared_ptr<const void> & t){ +shared_ptr_helper_base::append(const boost_132::shared_ptr<const void> & t){ if(NULL == m_pointers_132) m_pointers_132 = new std::list<boost_132::shared_ptr<const void> >; m_pointers_132->push_back(t); } // #endif + BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) -shared_ptr_helper::shared_ptr_helper() : - m_pointers(NULL) +shared_ptr_helper_base::shared_ptr_helper_base() : + m_o_sp(NULL) #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP , m_pointers_132(NULL) #endif {} + BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY()) -shared_ptr_helper::~shared_ptr_helper(){ - if(NULL != m_pointers) - delete m_pointers; +shared_ptr_helper_base::~shared_ptr_helper_base(){ + if(NULL != m_o_sp) + delete m_o_sp; #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP if(NULL != m_pointers_132) delete m_pointers_132; #endif } -} // namespace detail } // namespace serialization } // namespace boost diff --git a/3rdParty/Boost/src/libs/serialization/src/text_iarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/text_iarchive.cpp index cb9017f..9520ca2 100644 --- a/3rdParty/Boost/src/libs/serialization/src/text_iarchive.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/text_iarchive.cpp @@ -24,10 +24,6 @@ namespace boost { namespace archive { -template class detail::archive_serializer_map<naked_text_iarchive>; -template class basic_text_iarchive<naked_text_iarchive> ; -template class text_iarchive_impl<naked_text_iarchive> ; - template class detail::archive_serializer_map<text_iarchive>; template class basic_text_iarchive<text_iarchive> ; template class text_iarchive_impl<text_iarchive> ; diff --git a/3rdParty/Boost/src/libs/serialization/src/text_wiarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/text_wiarchive.cpp index a6630c0..a0c68a8 100644 --- a/3rdParty/Boost/src/libs/serialization/src/text_wiarchive.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/text_wiarchive.cpp @@ -26,10 +26,6 @@ namespace boost { namespace archive { -template class detail::archive_serializer_map<naked_text_wiarchive>; -template class basic_text_iarchive<naked_text_wiarchive> ; -template class text_wiarchive_impl<naked_text_wiarchive> ; - template class detail::archive_serializer_map<text_wiarchive>; template class basic_text_iarchive<text_wiarchive> ; template class text_wiarchive_impl<text_wiarchive> ; diff --git a/3rdParty/Boost/src/libs/serialization/src/utf8_codecvt_facet.cpp b/3rdParty/Boost/src/libs/serialization/src/utf8_codecvt_facet.cpp index d064c63..07deada 100644 --- a/3rdParty/Boost/src/libs/serialization/src/utf8_codecvt_facet.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/utf8_codecvt_facet.cpp @@ -7,15 +7,14 @@ #ifdef BOOST_NO_STD_WSTREAMBUF #error "wide char i/o not supported on this platform" #else - -#define BOOST_UTF8_BEGIN_NAMESPACE \ - namespace boost { namespace archive { namespace detail { -#define BOOST_UTF8_DECL -#define BOOST_UTF8_END_NAMESPACE }}} -#include <boost/detail/utf8_codecvt_facet.ipp> -#undef BOOST_UTF8_END_NAMESPACE -#undef BOOST_UTF8_DECL -#undef BOOST_UTF8_BEGIN_NAMESPACE - + #ifdef BOOST_NO_CXX11_HDR_CODECVT + #define BOOST_UTF8_BEGIN_NAMESPACE \ + namespace boost { namespace archive { namespace detail { + #define BOOST_UTF8_DECL + #define BOOST_UTF8_END_NAMESPACE }}} + #include <boost/detail/utf8_codecvt_facet.ipp> + #undef BOOST_UTF8_END_NAMESPACE + #undef BOOST_UTF8_DECL + #undef BOOST_UTF8_BEGIN_NAMESPACE + #endif // BOOST_NO_CXX11_HDR_CODECVT #endif // BOOST_NO_STD_WSTREAMBUF - diff --git a/3rdParty/Boost/src/libs/serialization/src/xml_archive_exception.cpp b/3rdParty/Boost/src/libs/serialization/src/xml_archive_exception.cpp index ea78916..41d33fd 100644 --- a/3rdParty/Boost/src/libs/serialization/src/xml_archive_exception.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/xml_archive_exception.cpp @@ -31,23 +31,23 @@ xml_archive_exception::xml_archive_exception( ) : archive_exception(other_exception, e1, e2) { - m_msg = "programming error"; switch(c){ case xml_archive_parsing_error: - m_msg = "unrecognized XML syntax"; + archive_exception::append(0, "unrecognized XML syntax"); break; case xml_archive_tag_mismatch: - m_msg = "XML start/end tag mismatch"; + archive_exception::append(0, "XML start/end tag mismatch"); if(NULL != e1){ - m_msg += " - "; - m_msg += e1; + archive_exception::append(0, " - "); + archive_exception::append(0, e1); } break; case xml_archive_tag_name_error: - m_msg = "Invalid XML tag name"; + archive_exception::append(0, "Invalid XML tag name"); break; default: BOOST_ASSERT(false); + archive_exception::append(0, "programming error"); break; } } diff --git a/3rdParty/Boost/src/libs/serialization/src/xml_iarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/xml_iarchive.cpp index 6d0de77..4311893 100644 --- a/3rdParty/Boost/src/libs/serialization/src/xml_iarchive.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/xml_iarchive.cpp @@ -34,10 +34,6 @@ namespace boost { namespace archive { -template class detail::archive_serializer_map<naked_xml_iarchive>; -template class basic_xml_iarchive<naked_xml_iarchive> ; -template class xml_iarchive_impl<naked_xml_iarchive> ; - template class detail::archive_serializer_map<xml_iarchive>; template class basic_xml_iarchive<xml_iarchive> ; template class xml_iarchive_impl<xml_iarchive> ; diff --git a/3rdParty/Boost/src/libs/serialization/src/xml_wiarchive.cpp b/3rdParty/Boost/src/libs/serialization/src/xml_wiarchive.cpp index 2e10947..0266548 100644 --- a/3rdParty/Boost/src/libs/serialization/src/xml_wiarchive.cpp +++ b/3rdParty/Boost/src/libs/serialization/src/xml_wiarchive.cpp @@ -39,10 +39,6 @@ namespace boost { namespace archive { -template class detail::archive_serializer_map<naked_xml_wiarchive>; -template class basic_xml_iarchive<naked_xml_wiarchive> ; -template class xml_wiarchive_impl<naked_xml_wiarchive> ; - template class detail::archive_serializer_map<xml_wiarchive>; template class basic_xml_iarchive<xml_wiarchive> ; template class xml_wiarchive_impl<xml_wiarchive> ; diff --git a/3rdParty/Boost/src/libs/signals/src/named_slot_map.cpp b/3rdParty/Boost/src/libs/signals/src/named_slot_map.cpp index ac9a292..2fe2790 100644 --- a/3rdParty/Boost/src/libs/signals/src/named_slot_map.cpp +++ b/3rdParty/Boost/src/libs/signals/src/named_slot_map.cpp @@ -24,7 +24,7 @@ typedef slot_container_type::iterator group_iterator; typedef slot_container_type::const_iterator const_group_iterator; -#if BOOST_WORKAROUND(_MSC_VER, <= 1700) +#if BOOST_WORKAROUND(_MSC_VER, <= 1900) void named_slot_map_iterator::decrement() { assert(false); } void named_slot_map_iterator::advance(difference_type) { assert(false); } #endif diff --git a/3rdParty/Boost/src/libs/system/src/error_code.cpp b/3rdParty/Boost/src/libs/system/src/error_code.cpp index 6772d15..aa628ab 100644 --- a/3rdParty/Boost/src/libs/system/src/error_code.cpp +++ b/3rdParty/Boost/src/libs/system/src/error_code.cpp @@ -9,422 +9,12 @@ //----------------------------------------------------------------------------// -#include <boost/config/warning_disable.hpp> - // define BOOST_SYSTEM_SOURCE so that <boost/system/config.hpp> knows // the library is being built (possibly exporting rather than importing code) -#define BOOST_SYSTEM_SOURCE +#define BOOST_SYSTEM_SOURCE -#include <boost/system/config.hpp> #include <boost/system/error_code.hpp> -#include <boost/cerrno.hpp> -#include <vector> -#include <cstdlib> -#include <cassert> - -using namespace boost::system; -using namespace boost::system::errc; - -#include <cstring> // for strerror/strerror_r - -# if defined( BOOST_WINDOWS_API ) -# include <windows.h> -# include "local_free_on_destruction.hpp" -# ifndef ERROR_INCORRECT_SIZE -# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS -# endif -# endif -//----------------------------------------------------------------------------// - -namespace -{ -#if defined(__PGI) - using boost::system::errc::invalid_argument; +#ifndef BOOST_ERROR_CODE_HEADER_ONLY +#include <boost/system/detail/error_code.ipp> #endif - // standard error categories ---------------------------------------------// - - class generic_error_category : public error_category - { - public: - generic_error_category(){} - const char * name() const; - std::string message( int ev ) const; - }; - - class system_error_category : public error_category - { - public: - system_error_category(){} - const char * name() const; - std::string message( int ev ) const; - error_condition default_error_condition( int ev ) const; - }; - - // generic_error_category implementation ---------------------------------// - - const char * generic_error_category::name() const - { - return "generic"; - } - - std::string generic_error_category::message( int ev ) const - { - static std::string unknown_err( "Unknown error" ); - // strerror_r is preferred because it is always thread safe, - // however, we fallback to strerror in certain cases because: - // -- Windows doesn't provide strerror_r. - // -- HP and Sun do provide strerror_r on newer systems, but there is - // no way to tell if is available at runtime and in any case their - // versions of strerror are thread safe anyhow. - // -- Linux only sometimes provides strerror_r. - // -- Tru64 provides strerror_r only when compiled -pthread. - // -- VMS doesn't provide strerror_r, but on this platform, strerror is - // thread safe. - # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\ - || (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\ - || (defined(__osf__) && !defined(_REENTRANT))\ - || (defined(__INTEGRITY))\ - || (defined(__vms))\ - || (defined(__QNXNTO__)) - const char * c_str = std::strerror( ev ); - return c_str - ? std::string( c_str ) - : unknown_err; - # else // use strerror_r - char buf[64]; - char * bp = buf; - std::size_t sz = sizeof(buf); - # if defined(__CYGWIN__) || defined(__USE_GNU) - // Oddball version of strerror_r - const char * c_str = strerror_r( ev, bp, sz ); - return c_str - ? std::string( c_str ) - : unknown_err; - # else - // POSIX version of strerror_r - int result; - for (;;) - { - // strerror_r returns 0 on success, otherwise ERANGE if buffer too small, - // invalid_argument if ev not a valid error number - # if defined (__sgi) - const char * c_str = strerror( ev ); - result = 0; - return c_str - ? std::string( c_str ) - : unknown_err; - # else - result = strerror_r( ev, bp, sz ); - # endif - if (result == 0 ) - break; - else - { - # if defined(__linux) - // Linux strerror_r returns -1 on error, with error number in errno - result = errno; - # endif - if ( result != ERANGE ) break; - if ( sz > sizeof(buf) ) std::free( bp ); - sz *= 2; - if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 ) - return std::string( "ENOMEM" ); - } - } - std::string msg; - try - { - msg = ( ( result == invalid_argument ) ? "Unknown error" : bp ); - } - -# ifndef BOOST_NO_EXCEPTIONS - // See ticket #2098 - catch(...) - { - // just eat the exception - } -# endif - - if ( sz > sizeof(buf) ) std::free( bp ); - sz = 0; - return msg; - # endif // else POSIX version of strerror_r - # endif // else use strerror_r - } - // system_error_category implementation --------------------------------// - - const char * system_error_category::name() const - { - return "system"; - } - - error_condition system_error_category::default_error_condition( int ev ) const - { - switch ( ev ) - { - case 0: return make_error_condition( success ); -# if defined(BOOST_POSIX_API) - // POSIX-like O/S -> posix_errno decode table ---------------------------// - case E2BIG: return make_error_condition( argument_list_too_long ); - case EACCES: return make_error_condition( permission_denied ); - case EADDRINUSE: return make_error_condition( address_in_use ); - case EADDRNOTAVAIL: return make_error_condition( address_not_available ); - case EAFNOSUPPORT: return make_error_condition( address_family_not_supported ); - case EAGAIN: return make_error_condition( resource_unavailable_try_again ); -# if EALREADY != EBUSY // EALREADY and EBUSY are the same on QNX Neutrino - case EALREADY: return make_error_condition( connection_already_in_progress ); -# endif - case EBADF: return make_error_condition( bad_file_descriptor ); - case EBADMSG: return make_error_condition( bad_message ); - case EBUSY: return make_error_condition( device_or_resource_busy ); - case ECANCELED: return make_error_condition( operation_canceled ); - case ECHILD: return make_error_condition( no_child_process ); - case ECONNABORTED: return make_error_condition( connection_aborted ); - case ECONNREFUSED: return make_error_condition( connection_refused ); - case ECONNRESET: return make_error_condition( connection_reset ); - case EDEADLK: return make_error_condition( resource_deadlock_would_occur ); - case EDESTADDRREQ: return make_error_condition( destination_address_required ); - case EDOM: return make_error_condition( argument_out_of_domain ); - case EEXIST: return make_error_condition( file_exists ); - case EFAULT: return make_error_condition( bad_address ); - case EFBIG: return make_error_condition( file_too_large ); - case EHOSTUNREACH: return make_error_condition( host_unreachable ); - case EIDRM: return make_error_condition( identifier_removed ); - case EILSEQ: return make_error_condition( illegal_byte_sequence ); - case EINPROGRESS: return make_error_condition( operation_in_progress ); - case EINTR: return make_error_condition( interrupted ); - case EINVAL: return make_error_condition( invalid_argument ); - case EIO: return make_error_condition( io_error ); - case EISCONN: return make_error_condition( already_connected ); - case EISDIR: return make_error_condition( is_a_directory ); - case ELOOP: return make_error_condition( too_many_symbolic_link_levels ); - case EMFILE: return make_error_condition( too_many_files_open ); - case EMLINK: return make_error_condition( too_many_links ); - case EMSGSIZE: return make_error_condition( message_size ); - case ENAMETOOLONG: return make_error_condition( filename_too_long ); - case ENETDOWN: return make_error_condition( network_down ); - case ENETRESET: return make_error_condition( network_reset ); - case ENETUNREACH: return make_error_condition( network_unreachable ); - case ENFILE: return make_error_condition( too_many_files_open_in_system ); - case ENOBUFS: return make_error_condition( no_buffer_space ); - case ENODATA: return make_error_condition( no_message_available ); - case ENODEV: return make_error_condition( no_such_device ); - case ENOENT: return make_error_condition( no_such_file_or_directory ); - case ENOEXEC: return make_error_condition( executable_format_error ); - case ENOLCK: return make_error_condition( no_lock_available ); - case ENOLINK: return make_error_condition( no_link ); - case ENOMEM: return make_error_condition( not_enough_memory ); - case ENOMSG: return make_error_condition( no_message ); - case ENOPROTOOPT: return make_error_condition( no_protocol_option ); - case ENOSPC: return make_error_condition( no_space_on_device ); - case ENOSR: return make_error_condition( no_stream_resources ); - case ENOSTR: return make_error_condition( not_a_stream ); - case ENOSYS: return make_error_condition( function_not_supported ); - case ENOTCONN: return make_error_condition( not_connected ); - case ENOTDIR: return make_error_condition( not_a_directory ); - # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value - case ENOTEMPTY: return make_error_condition( directory_not_empty ); - # endif // ENOTEMPTY != EEXIST - # if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips - case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable ); - # endif // ENOTRECOVERABLE != ECONNRESET - case ENOTSOCK: return make_error_condition( not_a_socket ); - case ENOTSUP: return make_error_condition( not_supported ); - case ENOTTY: return make_error_condition( inappropriate_io_control_operation ); - case ENXIO: return make_error_condition( no_such_device_or_address ); - # if EOPNOTSUPP != ENOTSUP - case EOPNOTSUPP: return make_error_condition( operation_not_supported ); - # endif // EOPNOTSUPP != ENOTSUP - case EOVERFLOW: return make_error_condition( value_too_large ); - # if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips - case EOWNERDEAD: return make_error_condition( owner_dead ); - # endif // EOWNERDEAD != ECONNABORTED - case EPERM: return make_error_condition( operation_not_permitted ); - case EPIPE: return make_error_condition( broken_pipe ); - case EPROTO: return make_error_condition( protocol_error ); - case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); - case EPROTOTYPE: return make_error_condition( wrong_protocol_type ); - case ERANGE: return make_error_condition( result_out_of_range ); - case EROFS: return make_error_condition( read_only_file_system ); - case ESPIPE: return make_error_condition( invalid_seek ); - case ESRCH: return make_error_condition( no_such_process ); - case ETIME: return make_error_condition( stream_timeout ); - case ETIMEDOUT: return make_error_condition( timed_out ); - case ETXTBSY: return make_error_condition( text_file_busy ); - # if EAGAIN != EWOULDBLOCK - case EWOULDBLOCK: return make_error_condition( operation_would_block ); - # endif // EAGAIN != EWOULDBLOCK - case EXDEV: return make_error_condition( cross_device_link ); - #else - // Windows system -> posix_errno decode table ---------------------------// - // see WinError.h comments for descriptions of errors - case ERROR_ACCESS_DENIED: return make_error_condition( permission_denied ); - case ERROR_ALREADY_EXISTS: return make_error_condition( file_exists ); - case ERROR_BAD_UNIT: return make_error_condition( no_such_device ); - case ERROR_BUFFER_OVERFLOW: return make_error_condition( filename_too_long ); - case ERROR_BUSY: return make_error_condition( device_or_resource_busy ); - case ERROR_BUSY_DRIVE: return make_error_condition( device_or_resource_busy ); - case ERROR_CANNOT_MAKE: return make_error_condition( permission_denied ); - case ERROR_CANTOPEN: return make_error_condition( io_error ); - case ERROR_CANTREAD: return make_error_condition( io_error ); - case ERROR_CANTWRITE: return make_error_condition( io_error ); - case ERROR_CURRENT_DIRECTORY: return make_error_condition( permission_denied ); - case ERROR_DEV_NOT_EXIST: return make_error_condition( no_such_device ); - case ERROR_DEVICE_IN_USE: return make_error_condition( device_or_resource_busy ); - case ERROR_DIR_NOT_EMPTY: return make_error_condition( directory_not_empty ); - case ERROR_DIRECTORY: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid" - case ERROR_DISK_FULL: return make_error_condition( no_space_on_device ); - case ERROR_FILE_EXISTS: return make_error_condition( file_exists ); - case ERROR_FILE_NOT_FOUND: return make_error_condition( no_such_file_or_directory ); - case ERROR_HANDLE_DISK_FULL: return make_error_condition( no_space_on_device ); - case ERROR_INVALID_ACCESS: return make_error_condition( permission_denied ); - case ERROR_INVALID_DRIVE: return make_error_condition( no_such_device ); - case ERROR_INVALID_FUNCTION: return make_error_condition( function_not_supported ); - case ERROR_INVALID_HANDLE: return make_error_condition( invalid_argument ); - case ERROR_INVALID_NAME: return make_error_condition( invalid_argument ); - case ERROR_LOCK_VIOLATION: return make_error_condition( no_lock_available ); - case ERROR_LOCKED: return make_error_condition( no_lock_available ); - case ERROR_NEGATIVE_SEEK: return make_error_condition( invalid_argument ); - case ERROR_NOACCESS: return make_error_condition( permission_denied ); - case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( not_enough_memory ); - case ERROR_NOT_READY: return make_error_condition( resource_unavailable_try_again ); - case ERROR_NOT_SAME_DEVICE: return make_error_condition( cross_device_link ); - case ERROR_OPEN_FAILED: return make_error_condition( io_error ); - case ERROR_OPEN_FILES: return make_error_condition( device_or_resource_busy ); - case ERROR_OPERATION_ABORTED: return make_error_condition( operation_canceled ); - case ERROR_OUTOFMEMORY: return make_error_condition( not_enough_memory ); - case ERROR_PATH_NOT_FOUND: return make_error_condition( no_such_file_or_directory ); - case ERROR_READ_FAULT: return make_error_condition( io_error ); - case ERROR_RETRY: return make_error_condition( resource_unavailable_try_again ); - case ERROR_SEEK: return make_error_condition( io_error ); - case ERROR_SHARING_VIOLATION: return make_error_condition( permission_denied ); - case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( too_many_files_open ); - case ERROR_WRITE_FAULT: return make_error_condition( io_error ); - case ERROR_WRITE_PROTECT: return make_error_condition( permission_denied ); - case WSAEACCES: return make_error_condition( permission_denied ); - case WSAEADDRINUSE: return make_error_condition( address_in_use ); - case WSAEADDRNOTAVAIL: return make_error_condition( address_not_available ); - case WSAEAFNOSUPPORT: return make_error_condition( address_family_not_supported ); - case WSAEALREADY: return make_error_condition( connection_already_in_progress ); - case WSAEBADF: return make_error_condition( bad_file_descriptor ); - case WSAECONNABORTED: return make_error_condition( connection_aborted ); - case WSAECONNREFUSED: return make_error_condition( connection_refused ); - case WSAECONNRESET: return make_error_condition( connection_reset ); - case WSAEDESTADDRREQ: return make_error_condition( destination_address_required ); - case WSAEFAULT: return make_error_condition( bad_address ); - case WSAEHOSTUNREACH: return make_error_condition( host_unreachable ); - case WSAEINPROGRESS: return make_error_condition( operation_in_progress ); - case WSAEINTR: return make_error_condition( interrupted ); - case WSAEINVAL: return make_error_condition( invalid_argument ); - case WSAEISCONN: return make_error_condition( already_connected ); - case WSAEMFILE: return make_error_condition( too_many_files_open ); - case WSAEMSGSIZE: return make_error_condition( message_size ); - case WSAENAMETOOLONG: return make_error_condition( filename_too_long ); - case WSAENETDOWN: return make_error_condition( network_down ); - case WSAENETRESET: return make_error_condition( network_reset ); - case WSAENETUNREACH: return make_error_condition( network_unreachable ); - case WSAENOBUFS: return make_error_condition( no_buffer_space ); - case WSAENOPROTOOPT: return make_error_condition( no_protocol_option ); - case WSAENOTCONN: return make_error_condition( not_connected ); - case WSAENOTSOCK: return make_error_condition( not_a_socket ); - case WSAEOPNOTSUPP: return make_error_condition( operation_not_supported ); - case WSAEPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); - case WSAEPROTOTYPE: return make_error_condition( wrong_protocol_type ); - case WSAETIMEDOUT: return make_error_condition( timed_out ); - case WSAEWOULDBLOCK: return make_error_condition( operation_would_block ); - #endif - default: return error_condition( ev, system_category() ); - } - } - -# if !defined( BOOST_WINDOWS_API ) - - std::string system_error_category::message( int ev ) const - { - return generic_category().message( ev ); - } -# else - - std::string system_error_category::message( int ev ) const - { -# ifndef BOOST_NO_ANSI_APIS - LPVOID lpMsgBuf = 0; - DWORD retval = ::FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - ev, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPSTR) &lpMsgBuf, - 0, - NULL - ); - detail::local_free_on_destruction lfod(lpMsgBuf); - if (retval == 0) - return std::string("Unknown error"); - - std::string str( static_cast<LPCSTR>(lpMsgBuf) ); -# else // WinCE workaround - LPVOID lpMsgBuf = 0; - DWORD retval = ::FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - ev, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPWSTR) &lpMsgBuf, - 0, - NULL - ); - detail::local_free_on_destruction lfod(lpMsgBuf); - if (retval == 0) - return std::string("Unknown error"); - - int num_chars = (wcslen( static_cast<LPCWSTR>(lpMsgBuf) ) + 1) * 2; - LPSTR narrow_buffer = (LPSTR)_alloca( num_chars ); - if (::WideCharToMultiByte(CP_ACP, 0, static_cast<LPCWSTR>(lpMsgBuf), -1, narrow_buffer, num_chars, NULL, NULL) == 0) - return std::string("Unknown error"); - - std::string str( narrow_buffer ); -# endif - while ( str.size() - && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) - str.erase( str.size()-1 ); - if ( str.size() && str[str.size()-1] == '.' ) - { str.erase( str.size()-1 ); } - return str; - } -# endif - -} // unnamed namespace - -namespace boost -{ - namespace system - { - -# ifndef BOOST_SYSTEM_NO_DEPRECATED - BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code; - // note that it doesn't matter if this - // isn't initialized before use since - // the only use is to take its - // address for comparison purposes -# endif - - BOOST_SYSTEM_DECL const error_category & system_category() - { - static const system_error_category system_category_const; - return system_category_const; - } - - BOOST_SYSTEM_DECL const error_category & generic_category() - { - static const generic_error_category generic_category_const; - return generic_category_const; - } - - } // namespace system -} // namespace boost diff --git a/3rdParty/Boost/src/libs/system/src/local_free_on_destruction.hpp b/3rdParty/Boost/src/libs/system/src/local_free_on_destruction.hpp deleted file mode 100644 index 110024f..0000000 --- a/3rdParty/Boost/src/libs/system/src/local_free_on_destruction.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// local_free_on_exit.hpp ------------------------------------------------------------// - -// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2010 Beman Dawes - -// Distributed under the Boost Software License, Version 1.0. -// See http://www.boost.org/LICENSE_1_0.txt - -// This is derived from boost/asio/detail/local_free_on_block_exit.hpp to avoid -// a dependency on asio. Thanks to Chris Kohlhoff for pointing it out. - -#ifndef BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP -#define BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP - -namespace boost { -namespace system { -namespace detail { - -class local_free_on_destruction -{ -public: - explicit local_free_on_destruction(void* p) - : p_(p) {} - - ~local_free_on_destruction() - { - ::LocalFree(p_); - } - -private: - void* p_; - local_free_on_destruction(const local_free_on_destruction&); // = deleted - local_free_on_destruction& operator=(const local_free_on_destruction&); // = deleted -}; - -} // namespace detail -} // namespace system -} // namespace boost - -#endif // BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP diff --git a/3rdParty/Boost/src/libs/thread/src/future.cpp b/3rdParty/Boost/src/libs/thread/src/future.cpp index 33980f5..0b990c1 100755..100644 --- a/3rdParty/Boost/src/libs/thread/src/future.cpp +++ b/3rdParty/Boost/src/libs/thread/src/future.cpp @@ -7,7 +7,8 @@ #ifndef BOOST_NO_EXCEPTIONS -#include <boost/thread/future.hpp> +#include <boost/thread/future_error_code.hpp> +#include <string> namespace boost { @@ -19,12 +20,12 @@ namespace boost public boost::system::error_category { public: - virtual const char* name() const; //BOOST_NOEXCEPT; + virtual const char* name() const BOOST_NOEXCEPT; virtual std::string message(int ev) const; }; const char* - future_error_category::name() const //BOOST_NOEXCEPT + future_error_category::name() const BOOST_NOEXCEPT { return "future"; } @@ -48,14 +49,16 @@ namespace boost } return std::string("unspecified future_errc value\n"); } + future_error_category future_error_category_var; } + BOOST_THREAD_DECL const system::error_category& future_category() BOOST_NOEXCEPT { - static thread_detail::future_error_category f; - return f; + return thread_detail::future_error_category_var; } } #endif + diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp b/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp index d5fd656..2cfe7cd 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp +++ b/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp @@ -3,18 +3,24 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#include <boost/thread/detail/config.hpp> +#ifdef BOOST_THREAD_ONCE_ATOMIC +#include "./once_atomic.cpp" +#else #define __STDC_CONSTANT_MACROS +#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> #include <boost/thread/once.hpp> #include <boost/assert.hpp> +#include <boost/throw_exception.hpp> #include <pthread.h> #include <stdlib.h> #include <memory> namespace boost { - namespace detail + namespace thread_detail { - BOOST_THREAD_DECL thread_detail::uintmax_atomic_t once_global_epoch=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C; + BOOST_THREAD_DECL uintmax_atomic_t once_global_epoch=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C; BOOST_THREAD_DECL pthread_mutex_t once_epoch_mutex=PTHREAD_MUTEX_INITIALIZER; BOOST_THREAD_DECL pthread_cond_t once_epoch_cv = PTHREAD_COND_INITIALIZER; @@ -55,13 +61,14 @@ namespace boost #endif } - thread_detail::uintmax_atomic_t& get_once_per_thread_epoch() + uintmax_atomic_t& get_once_per_thread_epoch() { BOOST_VERIFY(!pthread_once(&epoch_tss_key_flag,create_epoch_tss_key)); void* data=pthread_getspecific(epoch_tss_key); if(!data) { data=malloc(sizeof(thread_detail::uintmax_atomic_t)); + if(!data) BOOST_THROW_EXCEPTION(std::bad_alloc()); BOOST_VERIFY(!pthread_setspecific(epoch_tss_key,data)); *static_cast<thread_detail::uintmax_atomic_t*>(data)=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C; } @@ -70,3 +77,4 @@ namespace boost } } +#endif // diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/once_atomic.cpp b/3rdParty/Boost/src/libs/thread/src/pthread/once_atomic.cpp new file mode 100644 index 0000000..b7ee1dc --- /dev/null +++ b/3rdParty/Boost/src/libs/thread/src/pthread/once_atomic.cpp @@ -0,0 +1,90 @@ +// (C) Copyright 2013 Andrey Semashev +// (C) Copyright 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +//#define __STDC_CONSTANT_MACROS +#include <boost/thread/detail/config.hpp> +#include <boost/thread/once.hpp> +#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> +#include <boost/assert.hpp> +#include <boost/static_assert.hpp> +#include <boost/atomic.hpp> +#include <boost/memory_order.hpp> +#include <pthread.h> + +namespace boost +{ + namespace thread_detail + { + + enum flag_states + { + uninitialized, in_progress, initialized + }; + + +#ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11 + BOOST_STATIC_ASSERT_MSG(sizeof(atomic_int_type) == sizeof(atomic_type), "Boost.Thread: unsupported platform"); +#endif + + static pthread_mutex_t once_mutex = PTHREAD_MUTEX_INITIALIZER; + static pthread_cond_t once_cv = PTHREAD_COND_INITIALIZER; + + BOOST_THREAD_DECL bool enter_once_region(once_flag& flag) BOOST_NOEXCEPT + { + atomic_type& f = get_atomic_storage(flag); + if (f.load(memory_order_acquire) != initialized) + { + pthread::pthread_mutex_scoped_lock lk(&once_mutex); + if (f.load(memory_order_acquire) != initialized) + { + while (true) + { + atomic_int_type expected = uninitialized; + if (f.compare_exchange_strong(expected, in_progress, memory_order_acq_rel, memory_order_acquire)) + { + // We have set the flag to in_progress + return true; + } + else if (expected == initialized) + { + // Another thread managed to complete the initialization + return false; + } + else + { + // Wait until the initialization is complete + //pthread::pthread_mutex_scoped_lock lk(&once_mutex); + BOOST_VERIFY(!pthread_cond_wait(&once_cv, &once_mutex)); + } + } + } + } + return false; + } + + BOOST_THREAD_DECL void commit_once_region(once_flag& flag) BOOST_NOEXCEPT + { + atomic_type& f = get_atomic_storage(flag); + { + pthread::pthread_mutex_scoped_lock lk(&once_mutex); + f.store(initialized, memory_order_release); + } + BOOST_VERIFY(!pthread_cond_broadcast(&once_cv)); + } + + BOOST_THREAD_DECL void rollback_once_region(once_flag& flag) BOOST_NOEXCEPT + { + atomic_type& f = get_atomic_storage(flag); + { + pthread::pthread_mutex_scoped_lock lk(&once_mutex); + f.store(uninitialized, memory_order_release); + } + BOOST_VERIFY(!pthread_cond_broadcast(&once_cv)); + } + + } // namespace thread_detail + +} // namespace boost diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp b/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp index c83eac1..f218fa8 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp +++ b/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp @@ -1,20 +1,22 @@ // Copyright (C) 2001-2003 // William E. Kempf // Copyright (C) 2007-8 Anthony Williams -// (C) Copyright 2011 Vicente J. Botet Escriba +// (C) Copyright 2011-2012 Vicente J. Botet Escriba // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include <boost/thread/detail/config.hpp> -#include <boost/thread/thread.hpp> +#include <boost/thread/thread_only.hpp> +#if defined BOOST_THREAD_USES_DATETIME #include <boost/thread/xtime.hpp> +#endif #include <boost/thread/condition_variable.hpp> #include <boost/thread/locks.hpp> #include <boost/thread/once.hpp> #include <boost/thread/tss.hpp> -#include <boost/throw_exception.hpp> +#include <boost/thread/future.hpp> #ifdef __GLIBC__ #include <sys/sysinfo.h> @@ -25,6 +27,15 @@ #include <unistd.h> #endif +#include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/trim.hpp> +#include <boost/lexical_cast.hpp> + +#include <fstream> +#include <string> +#include <set> +#include <vector> + #include "./timeconv.inl" #pragma GCC diagnostic ignored "-Wreturn-type" @@ -35,14 +46,17 @@ namespace boost { thread_data_base::~thread_data_base() { - { for (notify_list_t::iterator i = notify.begin(), e = notify.end(); i != e; ++i) { i->second->unlock(); i->first->notify_all(); } - } + for (async_states_t::iterator i = async_states_.begin(), e = async_states_.end(); + i != e; ++i) + { + (*i)->make_ready(); + } } struct thread_exit_callback_node @@ -74,6 +88,7 @@ namespace boost { while(!thread_info->tss_data.empty() || thread_info->thread_exit_callbacks) { + while(thread_info->thread_exit_callbacks) { detail::thread_exit_callback_node* const current_node=thread_info->thread_exit_callbacks; @@ -99,7 +114,10 @@ namespace boost thread_info->tss_data.erase(current); } } - thread_info->self.reset(); + if (thread_info) // fixme: should we test this? + { + thread_info->self.reset(); + } } } } @@ -150,38 +168,54 @@ namespace boost boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->self; thread_info->self.reset(); detail::set_current_thread_data(thread_info.get()); +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS BOOST_TRY { +#endif thread_info->run(); +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS + } BOOST_CATCH (thread_interrupted const&) { } - BOOST_CATCH_END // Removed as it stops the debugger identifying the cause of the exception // Unhandled exceptions still cause the application to terminate // BOOST_CATCH(...) // { +// throw; +// // std::terminate(); // } - + BOOST_CATCH_END +#endif detail::tls_destructor(thread_info.get()); detail::set_current_thread_data(0); boost::lock_guard<boost::mutex> lock(thread_info->data_mutex); thread_info->done=true; thread_info->done_condition.notify_all(); + return 0; } } - + } + namespace detail + { struct externally_launched_thread: detail::thread_data_base { externally_launched_thread() { +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS interrupt_enabled=false; +#endif + } + ~externally_launched_thread() { + BOOST_ASSERT(notify.empty()); + notify.clear(); + BOOST_ASSERT(async_states_.empty()); + async_states_.clear(); } - void run() {} void notify_all_at_thread_exit(condition_variable*, mutex*) @@ -192,18 +226,18 @@ namespace boost void operator=(externally_launched_thread&); }; - detail::thread_data_base* make_external_thread_data() + thread_data_base* make_external_thread_data() { - detail::thread_data_base* const me(new externally_launched_thread()); + thread_data_base* const me(detail::heap_new<externally_launched_thread>()); me->self.reset(me); set_current_thread_data(me); return me; } - detail::thread_data_base* get_or_make_current_thread_data() + thread_data_base* get_or_make_current_thread_data() { - detail::thread_data_base* current_thread_data(detail::get_current_thread_data()); + thread_data_base* current_thread_data(get_current_thread_data()); if(!current_thread_data) { current_thread_data=make_external_thread_data(); @@ -217,18 +251,20 @@ namespace boost thread::thread() BOOST_NOEXCEPT {} - void thread::start_thread() + bool thread::start_thread_noexcept() { thread_info->self=thread_info; int const res = pthread_create(&thread_info->thread_handle, 0, &thread_proxy, thread_info.get()); if (res != 0) { thread_info->self.reset(); - boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_create")); + return false; +// boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_create")); } + return true; } - void thread::start_thread(const attributes& attr) + bool thread::start_thread_noexcept(const attributes& attr) { thread_info->self=thread_info; const attributes::native_handle_type* h = attr.native_handle(); @@ -236,14 +272,16 @@ namespace boost if (res != 0) { thread_info->self.reset(); - boost::throw_exception(thread_resource_error()); + return false; +// boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_create")); } int detached_state; res = pthread_attr_getdetachstate(h, &detached_state); if (res != 0) { thread_info->self.reset(); - boost::throw_exception(thread_resource_error()); + return false; +// boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_attr_getdetachstate")); } if (PTHREAD_CREATE_DETACHED==detached_state) { @@ -261,6 +299,7 @@ namespace boost } } } + return true; } @@ -270,12 +309,8 @@ namespace boost return thread_info; } - void thread::join() + bool thread::join_noexcept() { - if (this_thread::get_id() == get_id()) - { - boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself")); - } detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { @@ -314,21 +349,16 @@ namespace boost { thread_info.reset(); } + return true; } else { -#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED - boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable")); -#endif + return false; } } - bool thread::do_try_join_until(struct timespec const &timeout) + bool thread::do_try_join_until_noexcept(struct timespec const &timeout, bool& res) { - if (this_thread::get_id() == get_id()) - { - boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself")); - } detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { @@ -338,9 +368,10 @@ namespace boost unique_lock<mutex> lock(local_thread_info->data_mutex); while(!local_thread_info->done) { - if(!local_thread_info->done_condition.do_timed_wait(lock,timeout)) + if(!local_thread_info->done_condition.do_wait_until(lock,timeout)) { - return false; + res=false; + return true; } } do_join=!local_thread_info->join_started; @@ -370,19 +401,18 @@ namespace boost { thread_info.reset(); } + res=true; return true; } else { -#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED - boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable")); -#endif + return false; } } bool thread::joinable() const BOOST_NOEXCEPT { - return (get_thread_info)(); + return (get_thread_info)()?true:false; } @@ -405,61 +435,121 @@ namespace boost namespace this_thread { + namespace no_interruption_point + { + namespace hiden + { + void BOOST_THREAD_DECL sleep_for(const timespec& ts) + { -#ifdef __DECXXX - /// Workaround of DECCXX issue of incorrect template substitution - template<> -#endif - void sleep(const system_time& st) + if (boost::detail::timespec_ge(ts, boost::detail::timespec_zero())) + { + + # if defined(BOOST_HAS_PTHREAD_DELAY_NP) + # if defined(__IBMCPP__) || defined(_AIX) + BOOST_VERIFY(!pthread_delay_np(const_cast<timespec*>(&ts))); + # else + BOOST_VERIFY(!pthread_delay_np(&ts)); + # endif + # elif defined(BOOST_HAS_NANOSLEEP) + // nanosleep takes a timespec that is an offset, not + // an absolute time. + nanosleep(&ts, 0); + # else + mutex mx; + unique_lock<mutex> lock(mx); + condition_variable cond; + cond.do_wait_for(lock, ts); + # endif + } + } + + void BOOST_THREAD_DECL sleep_until(const timespec& ts) + { + timespec now = boost::detail::timespec_now(); + if (boost::detail::timespec_gt(ts, now)) + { + for (int foo=0; foo < 5; ++foo) + { + + # if defined(BOOST_HAS_PTHREAD_DELAY_NP) + timespec d = boost::detail::timespec_minus(ts, now); + BOOST_VERIFY(!pthread_delay_np(&d)); + # elif defined(BOOST_HAS_NANOSLEEP) + // nanosleep takes a timespec that is an offset, not + // an absolute time. + timespec d = boost::detail::timespec_minus(ts, now); + nanosleep(&d, 0); + # else + mutex mx; + unique_lock<mutex> lock(mx); + condition_variable cond; + cond.do_wait_until(lock, ts); + # endif + timespec now2 = boost::detail::timespec_now(); + if (boost::detail::timespec_ge(now2, ts)) + { + return; + } + } + } + } + + } + } + namespace hiden + { + void BOOST_THREAD_DECL sleep_for(const timespec& ts) { - detail::thread_data_base* const thread_info=detail::get_current_thread_data(); + boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data(); if(thread_info) { - unique_lock<mutex> lk(thread_info->sleep_mutex); - while(thread_info->sleep_condition.timed_wait(lk,st)) {} + unique_lock<mutex> lk(thread_info->sleep_mutex); + while( thread_info->sleep_condition.do_wait_for(lk,ts)) {} } else { - xtime const xt=get_xtime(st); + boost::this_thread::no_interruption_point::hiden::sleep_for(ts); + } + } - for (int foo=0; foo < 5; ++foo) - { -# if defined(BOOST_HAS_PTHREAD_DELAY_NP) - timespec ts; - to_timespec_duration(xt, ts); - BOOST_VERIFY(!pthread_delay_np(&ts)); -# elif defined(BOOST_HAS_NANOSLEEP) - timespec ts; - to_timespec_duration(xt, ts); + void BOOST_THREAD_DECL sleep_until(const timespec& ts) + { + boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data(); - // nanosleep takes a timespec that is an offset, not - // an absolute time. - nanosleep(&ts, 0); -# else - mutex mx; - mutex::scoped_lock lock(mx); - condition cond; - cond.timed_wait(lock, xt); -# endif - xtime cur; - xtime_get(&cur, TIME_UTC_); - if (xtime_cmp(xt, cur) <= 0) - return; - } + if(thread_info) + { + unique_lock<mutex> lk(thread_info->sleep_mutex); + while(thread_info->sleep_condition.do_wait_until(lk,ts)) {} + } + else + { + boost::this_thread::no_interruption_point::hiden::sleep_until(ts); } } + } // hiden + } // this_thread + namespace this_thread + { void yield() BOOST_NOEXCEPT { # if defined(BOOST_HAS_SCHED_YIELD) BOOST_VERIFY(!sched_yield()); # elif defined(BOOST_HAS_PTHREAD_YIELD) BOOST_VERIFY(!pthread_yield()); +//# elif defined BOOST_THREAD_USES_DATETIME +// xtime xt; +// xtime_get(&xt, TIME_UTC_); +// sleep(xt); +// sleep_for(chrono::milliseconds(0)); # else - xtime xt; - xtime_get(&xt, TIME_UTC_); - sleep(xt); +#error + timespec ts; + ts.tv_sec= 0; + ts.tv_nsec= 0; + hiden::sleep_for(ts); # endif } } @@ -481,24 +571,65 @@ namespace boost #endif } - thread::id thread::get_id() const BOOST_NOEXCEPT + unsigned thread::physical_concurrency() BOOST_NOEXCEPT { - #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID - //return local_thread_info->thread_handle; - return const_cast<thread*>(this)->native_handle(); - #else - detail::thread_data_ptr const local_thread_info=(get_thread_info)(); - if(local_thread_info) - { - return id(local_thread_info); - } - else - { - return id(); +#ifdef __linux__ + try { + using namespace std; + + ifstream proc_cpuinfo ("/proc/cpuinfo"); + + const string physical_id("physical id"), core_id("core id"); + + typedef std::pair<unsigned, unsigned> core_entry; // [physical ID, core id] + + std::set<core_entry> cores; + + core_entry current_core_entry; + + string line; + while ( getline(proc_cpuinfo, line) ) { + if (line.empty()) + continue; + + vector<string> key_val(2); + boost::split(key_val, line, boost::is_any_of(":")); + + if (key_val.size() != 2) + return hardware_concurrency(); + + string key = key_val[0]; + string value = key_val[1]; + boost::trim(key); + boost::trim(value); + + if (key == physical_id) { + current_core_entry.first = boost::lexical_cast<unsigned>(value); + continue; + } + + if (key == core_id) { + current_core_entry.second = boost::lexical_cast<unsigned>(value); + cores.insert(current_core_entry); + continue; + } + } + // Fall back to hardware_concurrency() in case + // /proc/cpuinfo is formatted differently than we expect. + return cores.size() != 0 ? cores.size() : hardware_concurrency(); + } catch(...) { + return hardware_concurrency(); } - #endif +#elif defined(__APPLE__) + int count; + size_t size=sizeof(count); + return sysctlbyname("hw.physicalcpu",&count,&size,NULL,0)?0:count; +#else + return hardware_concurrency(); +#endif } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS void thread::interrupt() { detail::thread_data_ptr const local_thread_info=(get_thread_info)(); @@ -527,6 +658,7 @@ namespace boost return false; } } +#endif thread::native_handle_type thread::native_handle() { @@ -544,18 +676,9 @@ namespace boost +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS namespace this_thread { - thread::id get_id() BOOST_NOEXCEPT - { - #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID - return pthread_self(); - #else - boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data(); - return thread::id(thread_info?thread_info->shared_from_this():detail::thread_data_ptr()); - #endif - } - void interruption_point() { #ifndef BOOST_NO_EXCEPTIONS @@ -625,6 +748,7 @@ namespace boost } } } +#endif namespace detail { @@ -632,7 +756,7 @@ namespace boost { detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); thread_exit_callback_node* const new_node= - new thread_exit_callback_node(func,current_thread_data->thread_exit_callbacks); + heap_new<thread_exit_callback_node>(func,current_thread_data->thread_exit_callbacks); current_thread_data->thread_exit_callbacks=new_node; } @@ -670,8 +794,11 @@ namespace boost void erase_tss_node(void const* key) { - detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); - current_thread_data->tss_data.erase(key); + detail::thread_data_base* const current_thread_data(get_current_thread_data()); + if(current_thread_data) + { + current_thread_data->tss_data.erase(key); + } } void set_tss_data(void const* key, @@ -700,6 +827,7 @@ namespace boost } } } + BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) { detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); @@ -708,6 +836,17 @@ namespace boost current_thread_data->notify_all_at_thread_exit(&cond, lk.release()); } } +namespace detail { + + void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as) + { + detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); + if(current_thread_data) + { + current_thread_data->make_ready_at_thread_exit(as); + } + } +} diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl b/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl index cab7c55..d81f31b 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl +++ b/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl @@ -17,6 +17,7 @@ const int NANOSECONDS_PER_MILLISECOND = 1000000; const int MICROSECONDS_PER_SECOND = 1000000; const int NANOSECONDS_PER_MICROSECOND = 1000; +#if defined BOOST_THREAD_USES_DATETIME inline void to_time(int milliseconds, boost::xtime& xt) { int res = 0; @@ -33,7 +34,9 @@ inline void to_time(int milliseconds, boost::xtime& xt) xt.nsec -= NANOSECONDS_PER_SECOND; } } +#endif #if defined(BOOST_HAS_PTHREADS) +#if defined BOOST_THREAD_USES_DATETIME inline void to_timespec(const boost::xtime& xt, timespec& ts) { ts.tv_sec = static_cast<int>(xt.sec); @@ -44,14 +47,27 @@ inline void to_timespec(const boost::xtime& xt, timespec& ts) ts.tv_nsec %= NANOSECONDS_PER_SECOND; } } - +#endif inline void to_time(int milliseconds, timespec& ts) { +#if defined BOOST_THREAD_USES_DATETIME boost::xtime xt; to_time(milliseconds, xt); to_timespec(xt, ts); +#else + ts.tv_sec += (milliseconds / MILLISECONDS_PER_SECOND); + ts.tv_nsec += ((milliseconds % MILLISECONDS_PER_SECOND) * + NANOSECONDS_PER_MILLISECOND); + + if (ts.tv_nsec >= NANOSECONDS_PER_SECOND) + { + ++ts.tv_sec; + ts.tv_nsec -= NANOSECONDS_PER_SECOND; + } +#endif } +#if defined BOOST_THREAD_USES_DATETIME inline void to_timespec_duration(const boost::xtime& xt, timespec& ts) { boost::xtime cur; @@ -82,7 +98,9 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts) } } #endif +#endif +#if defined BOOST_THREAD_USES_DATETIME inline void to_duration(boost::xtime xt, int& milliseconds) { boost::xtime cur; @@ -126,6 +144,7 @@ inline void to_microduration(boost::xtime xt, int& microseconds) NANOSECONDS_PER_MICROSECOND); } } +#endif } // Change Log: diff --git a/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp b/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp index 5a26f5e..54ebbf3 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp +++ b/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp @@ -3,6 +3,7 @@ // http://www.boost.org/LICENSE_1_0.txt) // (C) Copyright 2007 Anthony Williams // (C) Copyright 2007 David Deakins +// (C) Copyright 2011-2013 Vicente J. Botet Escriba #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x400 @@ -11,17 +12,20 @@ #ifndef WINVER #define WINVER 0x400 #endif +//#define BOOST_THREAD_VERSION 3 -#include <boost/thread/thread.hpp> +#include <boost/thread/thread_only.hpp> #include <boost/thread/once.hpp> #include <boost/thread/tss.hpp> #include <boost/thread/condition_variable.hpp> #include <boost/thread/detail/tss_hooks.hpp> +#include <boost/thread/future.hpp> #include <boost/assert.hpp> -#include <boost/throw_exception.hpp> +#include <boost/cstdint.hpp> +#if defined BOOST_THREAD_USES_DATETIME #include <boost/date_time/posix_time/conversion.hpp> - +#endif #include <memory> #include <algorithm> #ifndef UNDER_CE @@ -36,16 +40,20 @@ namespace boost { thread_data_base::~thread_data_base() { - { for (notify_list_t::iterator i = notify.begin(), e = notify.end(); i != e; ++i) { i->second->unlock(); i->first->notify_all(); } - } + for (async_states_t::iterator i = async_states_.begin(), e = async_states_.end(); + i != e; ++i) + { + (*i)->make_ready(); + } } } + namespace { #ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 @@ -75,24 +83,34 @@ namespace boost } } - detail::thread_data_base* get_current_thread_data() - { - if(current_thread_tls_key==TLS_OUT_OF_INDEXES) - { - return 0; - } - return (detail::thread_data_base*)TlsGetValue(current_thread_tls_key); - } - void set_current_thread_data(detail::thread_data_base* new_data) { boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key); - if(current_thread_tls_key!=TLS_OUT_OF_INDEXES) + if (current_thread_tls_key!=TLS_OUT_OF_INDEXES) + { BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data)); + } else - boost::throw_exception(thread_resource_error()); + { + BOOST_VERIFY(false); + //boost::throw_exception(thread_resource_error()); + } } + } + namespace detail + { + thread_data_base* get_current_thread_data() + { + if(current_thread_tls_key==TLS_OUT_OF_INDEXES) + { + return 0; + } + return (detail::thread_data_base*)TlsGetValue(current_thread_tls_key); + } + } + namespace + { #ifndef BOOST_HAS_THREADEX // Windows CE doesn't define _beginthreadex @@ -111,7 +129,7 @@ namespace boost return ret; } - typedef void* uintptr_t; + //typedef void* uintptr_t; inline uintptr_t _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*), void* arglist, unsigned initflag, unsigned* thrdaddr) @@ -151,7 +169,7 @@ namespace boost { void run_thread_exit_callbacks() { - detail::thread_data_ptr current_thread_data(get_current_thread_data(),false); + detail::thread_data_ptr current_thread_data(detail::get_current_thread_data(),false); if(current_thread_data) { while(! current_thread_data->tss_data.empty() || current_thread_data->thread_exit_callbacks) @@ -190,23 +208,24 @@ namespace boost { detail::thread_data_base* const thread_info(reinterpret_cast<detail::thread_data_base*>(param)); set_current_thread_data(thread_info); -#ifndef BOOST_NO_EXCEPTIONS - try // BOOST_NO_EXCEPTIONS protected -#endif +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS + BOOST_TRY { +#endif thread_info->run(); +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS } -#ifndef BOOST_NO_EXCEPTIONS - catch(thread_interrupted const&) // BOOST_NO_EXCEPTIONS protected + BOOST_CATCH(thread_interrupted const&) { } -#endif // Removed as it stops the debugger identifying the cause of the exception // Unhandled exceptions still cause the application to terminate -// catch(...) // BOOST_NO_EXCEPTIONS protected +// BOOST_CATCH(...) // { // std::terminate(); // } + BOOST_CATCH_END +#endif run_thread_exit_callbacks(); return 0; } @@ -215,29 +234,33 @@ namespace boost thread::thread() BOOST_NOEXCEPT {} - void thread::start_thread() + bool thread::start_thread_noexcept() { uintptr_t const new_thread=_beginthreadex(0,0,&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id); if(!new_thread) { - boost::throw_exception(thread_resource_error()); + return false; +// boost::throw_exception(thread_resource_error()); } intrusive_ptr_add_ref(thread_info.get()); thread_info->thread_handle=(detail::win32::handle)(new_thread); ResumeThread(thread_info->thread_handle); + return true; } - void thread::start_thread(const attributes& attr) + bool thread::start_thread_noexcept(const attributes& attr) { //uintptr_t const new_thread=_beginthreadex(attr.get_security(),attr.get_stack_size(),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id); uintptr_t const new_thread=_beginthreadex(0,static_cast<unsigned int>(attr.get_stack_size()),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id); if(!new_thread) { - boost::throw_exception(thread_resource_error()); + return false; +// boost::throw_exception(thread_resource_error()); } intrusive_ptr_add_ref(thread_info.get()); thread_info->thread_handle=(detail::win32::handle)(new_thread); ResumeThread(thread_info->thread_handle); + return true; } thread::thread(detail::thread_data_ptr data): @@ -252,7 +275,15 @@ namespace boost externally_launched_thread() { ++count; +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS interruption_enabled=false; +#endif + } + ~externally_launched_thread() { + BOOST_ASSERT(notify.empty()); + notify.clear(); + BOOST_ASSERT(async_states_.empty()); + async_states_.clear(); } void run() @@ -268,28 +299,25 @@ namespace boost void make_external_thread_data() { externally_launched_thread* me=detail::heap_new<externally_launched_thread>(); -#ifndef BOOST_NO_EXCEPTIONS - try // BOOST_NO_EXCEPTIONS protected -#endif + BOOST_TRY { set_current_thread_data(me); } -#ifndef BOOST_NO_EXCEPTIONS - catch(...) // BOOST_NO_EXCEPTIONS protected + BOOST_CATCH(...) { detail::heap_delete(me); - throw; // BOOST_NO_EXCEPTIONS protected + BOOST_RETHROW } -#endif + BOOST_CATCH_END } detail::thread_data_base* get_or_make_current_thread_data() { - detail::thread_data_base* current_thread_data(get_current_thread_data()); + detail::thread_data_base* current_thread_data(detail::get_current_thread_data()); if(!current_thread_data) { make_external_thread_data(); - current_thread_data=get_current_thread_data(); + current_thread_data=detail::get_current_thread_data(); } return current_thread_data; } @@ -309,54 +337,47 @@ namespace boost bool thread::joinable() const BOOST_NOEXCEPT { - return (get_thread_info)(); + return (get_thread_info)() ? true : false; } - void thread::join() + bool thread::join_noexcept() { - if (this_thread::get_id() == get_id()) - { - boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself")); - } + detail::thread_data_ptr local_thread_info=(get_thread_info)(); if(local_thread_info) { this_thread::interruptible_wait(local_thread_info->thread_handle,detail::timeout::sentinel()); release_handle(); + return true; } else { -#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED - boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable")); -#endif + return false; } } +#if defined BOOST_THREAD_USES_DATETIME bool thread::timed_join(boost::system_time const& wait_until) { return do_try_join_until(get_milliseconds_until(wait_until)); } - - bool thread::do_try_join_until(uintmax_t milli) +#endif + bool thread::do_try_join_until_noexcept(uintmax_t milli, bool& res) { - if (this_thread::get_id() == get_id()) - { - boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself")); - } detail::thread_data_ptr local_thread_info=(get_thread_info)(); if(local_thread_info) { if(!this_thread::interruptible_wait(local_thread_info->thread_handle,milli)) { - return false; + res=false; + return true; } release_handle(); + res=true; return true; } else { -#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED - boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable")); -#endif + return false; } } @@ -370,6 +391,7 @@ namespace boost thread_info=0; } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS void thread::interrupt() { detail::thread_data_ptr local_thread_info=(get_thread_info)(); @@ -385,13 +407,40 @@ namespace boost return local_thread_info.get() && (detail::win32::WaitForSingleObject(local_thread_info->interruption_handle,0)==0); } +#endif + unsigned thread::hardware_concurrency() BOOST_NOEXCEPT { - SYSTEM_INFO info={{0}}; + //SYSTEM_INFO info={{0}}; + SYSTEM_INFO info; GetSystemInfo(&info); return info.dwNumberOfProcessors; } + unsigned thread::physical_concurrency() BOOST_NOEXCEPT + { + unsigned cores = 0; +#if !(defined(__MINGW32__) || defined (__MINGW64__)) + DWORD size = 0; + + GetLogicalProcessorInformation(NULL, &size); + if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) + return 0; + + std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(size); + if (GetLogicalProcessorInformation(&buffer.front(), &size) == FALSE) + return 0; + + const size_t Elements = size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); + + for (size_t i = 0; i < Elements; ++i) { + if (buffer[i].Relationship == RelationProcessorCore) + ++cores; + } +#endif + return cores; + } + thread::native_handle_type thread::native_handle() { detail::thread_data_ptr local_thread_info=(get_thread_info)(); @@ -409,10 +458,10 @@ namespace boost { LARGE_INTEGER get_due_time(detail::timeout const& target_time) { - LARGE_INTEGER due_time={{0}}; + LARGE_INTEGER due_time={{0,0}}; if(target_time.relative) { - unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start; + detail::win32::ticks_type const elapsed_milliseconds=detail::win32::GetTickCount64()()-target_time.start; LONGLONG const remaining_milliseconds=(target_time.milliseconds-elapsed_milliseconds); LONGLONG const hundred_nanoseconds_in_one_millisecond=10000; @@ -423,7 +472,7 @@ namespace boost } else { - SYSTEMTIME target_system_time={0}; + SYSTEMTIME target_system_time={0,0,0,0,0,0,0,0}; target_system_time.wYear=target_time.abs_time.date().year(); target_system_time.wMonth=target_time.abs_time.date().month(); target_system_time.wDay=target_time.abs_time.date().day(); @@ -467,19 +516,22 @@ namespace boost detail::win32::handle handles[3]={0}; unsigned handle_count=0; unsigned wait_handle_index=~0U; +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS unsigned interruption_index=~0U; +#endif unsigned timeout_index=~0U; if(handle_to_wait_for!=detail::win32::invalid_handle_value) { wait_handle_index=handle_count; handles[handle_count++]=handle_to_wait_for; } - if(get_current_thread_data() && get_current_thread_data()->interruption_enabled) +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS + if(detail::get_current_thread_data() && detail::get_current_thread_data()->interruption_enabled) { interruption_index=handle_count; - handles[handle_count++]=get_current_thread_data()->interruption_handle; + handles[handle_count++]=detail::get_current_thread_data()->interruption_handle; } - +#endif detail::win32::handle_manager timer_handle; #ifndef UNDER_CE @@ -531,11 +583,13 @@ namespace boost { return true; } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS else if(notified_index==interruption_index) { - detail::win32::ResetEvent(get_current_thread_data()->interruption_handle); + detail::win32::ResetEvent(detail::get_current_thread_data()->interruption_handle); throw thread_interrupted(); } +#endif else if(notified_index==timeout_index) { return false; @@ -555,54 +609,140 @@ namespace boost return false; } + namespace no_interruption_point + { + bool non_interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time) + { + detail::win32::handle handles[3]={0}; + unsigned handle_count=0; + unsigned wait_handle_index=~0U; + unsigned timeout_index=~0U; + if(handle_to_wait_for!=detail::win32::invalid_handle_value) + { + wait_handle_index=handle_count; + handles[handle_count++]=handle_to_wait_for; + } + detail::win32::handle_manager timer_handle; + +#ifndef UNDER_CE + unsigned const min_timer_wait_period=20; + + if(!target_time.is_sentinel()) + { + detail::timeout::remaining_time const time_left=target_time.remaining_milliseconds(); + if(time_left.milliseconds > min_timer_wait_period) + { + // for a long-enough timeout, use a waitable timer (which tracks clock changes) + timer_handle=CreateWaitableTimer(NULL,false,NULL); + if(timer_handle!=0) + { + LARGE_INTEGER due_time=get_due_time(target_time); + + bool const set_time_succeeded=SetWaitableTimer(timer_handle,&due_time,0,0,0,false)!=0; + if(set_time_succeeded) + { + timeout_index=handle_count; + handles[handle_count++]=timer_handle; + } + } + } + else if(!target_time.relative) + { + // convert short absolute-time timeouts into relative ones, so we don't race against clock changes + target_time=detail::timeout(time_left.milliseconds); + } + } +#endif + + bool const using_timer=timeout_index!=~0u; + detail::timeout::remaining_time time_left(0); + + do + { + if(!using_timer) + { + time_left=target_time.remaining_milliseconds(); + } + + if(handle_count) + { + unsigned long const notified_index=detail::win32::WaitForMultipleObjects(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds); + if(notified_index<handle_count) + { + if(notified_index==wait_handle_index) + { + return true; + } + else if(notified_index==timeout_index) + { + return false; + } + } + } + else + { + detail::win32::Sleep(time_left.milliseconds); + } + if(target_time.relative) + { + target_time.milliseconds-=detail::timeout::max_non_infinite_wait; + } + } + while(time_left.more); + return false; + } + } + thread::id get_id() BOOST_NOEXCEPT { #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID - //return detail::win32::GetCurrentThread(); return detail::win32::GetCurrentThreadId(); #else return thread::id(get_or_make_current_thread_data()); #endif } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS void interruption_point() { if(interruption_enabled() && interruption_requested()) { - detail::win32::ResetEvent(get_current_thread_data()->interruption_handle); + detail::win32::ResetEvent(detail::get_current_thread_data()->interruption_handle); throw thread_interrupted(); } } bool interruption_enabled() BOOST_NOEXCEPT { - return get_current_thread_data() && get_current_thread_data()->interruption_enabled; + return detail::get_current_thread_data() && detail::get_current_thread_data()->interruption_enabled; } bool interruption_requested() BOOST_NOEXCEPT { - return get_current_thread_data() && (detail::win32::WaitForSingleObject(get_current_thread_data()->interruption_handle,0)==0); + return detail::get_current_thread_data() && (detail::win32::WaitForSingleObject(detail::get_current_thread_data()->interruption_handle,0)==0); } +#endif void yield() BOOST_NOEXCEPT { detail::win32::Sleep(0); } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS disable_interruption::disable_interruption() BOOST_NOEXCEPT: interruption_was_enabled(interruption_enabled()) { if(interruption_was_enabled) { - get_current_thread_data()->interruption_enabled=false; + detail::get_current_thread_data()->interruption_enabled=false; } } disable_interruption::~disable_interruption() BOOST_NOEXCEPT { - if(get_current_thread_data()) + if(detail::get_current_thread_data()) { - get_current_thread_data()->interruption_enabled=interruption_was_enabled; + detail::get_current_thread_data()->interruption_enabled=interruption_was_enabled; } } @@ -610,17 +750,18 @@ namespace boost { if(d.interruption_was_enabled) { - get_current_thread_data()->interruption_enabled=true; + detail::get_current_thread_data()->interruption_enabled=true; } } restore_interruption::~restore_interruption() BOOST_NOEXCEPT { - if(get_current_thread_data()) + if(detail::get_current_thread_data()) { - get_current_thread_data()->interruption_enabled=false; + detail::get_current_thread_data()->interruption_enabled=false; } } +#endif } namespace detail @@ -716,12 +857,22 @@ namespace boost BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) { - detail::thread_data_base* const current_thread_data(get_current_thread_data()); + detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); if(current_thread_data) { current_thread_data->notify_all_at_thread_exit(&cond, lk.release()); } } +//namespace detail { +// +// void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as) +// { +// detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); +// if(current_thread_data) +// { +// current_thread_data->make_ready_at_thread_exit(as); +// } +// } +//} } - diff --git a/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp b/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp index 1654b19..5fd53b6 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp +++ b/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp @@ -1,4 +1,4 @@ -// $Id: tss_pe.cpp 79373 2012-07-09 05:55:01Z viboes $ +// $Id$ // (C) Copyright Aaron W. LaFramboise, Roland Schwarz, Michael Glassford 2004. // (C) Copyright 2007 Roland Schwarz // (C) Copyright 2007 Anthony Williams @@ -80,6 +80,36 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata #define WIN32_LEAN_AND_MEAN #include <windows.h> + +// _pRawDllMainOrig can be defined by including boost/thread/win32/mfc_thread_init.hpp +// into your dll; it ensures that MFC-Dll-initialization will be done properly +// The following code is adapted from the MFC-Dll-init code +/* + * _pRawDllMainOrig MUST be an extern const variable, which will be aliased to + * _pDefaultRawDllMainOrig if no real user definition is present, thanks to the + * alternatename directive. + */ + +// work at least with _MSC_VER 1500 (MSVC++ 9.0, VS 2008) +#if (_MSC_VER >= 1500) + +extern "C" { +extern BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID); +extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NULL; +#if defined (_M_IX86) +#pragma comment(linker, "/alternatename:__pRawDllMainOrig=__pDefaultRawDllMainOrig") +#elif defined (_M_X64) || defined (_M_ARM) +#pragma comment(linker, "/alternatename:_pRawDllMainOrig=_pDefaultRawDllMainOrig") +#else /* defined (_M_X64) || defined (_M_ARM) */ +#error Unsupported platform +#endif /* defined (_M_X64) || defined (_M_ARM) */ +} + +#endif + + + + //Definitions required by implementation #if (_MSC_VER < 1300) // 1300 == VC++ 7.0 @@ -240,7 +270,11 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata } } +#if (_MSC_VER >= 1500) + BOOL WINAPI dll_callback(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved) +#else BOOL WINAPI dll_callback(HANDLE, DWORD dwReason, LPVOID) +#endif { switch (dwReason) { @@ -251,6 +285,13 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata boost::on_process_exit(); break; } + +#if (_MSC_VER >= 1500) + if( _pRawDllMainOrig ) + { + return _pRawDllMainOrig(hInstance, dwReason, lpReserved); + } +#endif return true; } } //namespace |