passenger 4.0.20 → 4.0.21
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/.gitignore +1 -0
- data/.travis.yml +1 -1
- data/NEWS +15 -0
- data/README.md +5 -3
- data/Rakefile +1 -0
- data/bin/passenger-config +1 -5
- data/bin/passenger-install-apache2-module +53 -5
- data/bin/passenger-install-nginx-module +19 -6
- data/bin/passenger-memory-stats +3 -3
- data/build/agents.rb +11 -8
- data/build/apache2.rb +9 -5
- data/build/basics.rb +15 -21
- data/build/common_library.rb +16 -6
- data/build/cplusplus_support.rb +5 -5
- data/build/cxx_tests.rb +3 -3
- data/build/documentation.rb +1 -1
- data/build/misc.rb +4 -37
- data/build/node_tests.rb +29 -0
- data/build/oxt_tests.rb +1 -1
- data/build/packaging.rb +29 -10
- data/build/preprocessor.rb +2 -1
- data/build/test_basics.rb +15 -6
- data/debian.template/locations.ini.template +1 -0
- data/debian.template/passenger.install.template +1 -0
- data/dev/copy_boost_headers.rb +7 -3
- data/dev/run_travis.sh +32 -16
- data/doc/Users guide Apache.idmap.txt +22 -34
- data/doc/Users guide Apache.txt +20 -234
- data/doc/Users guide Nginx.idmap.txt +84 -66
- data/doc/Users guide Nginx.txt +50 -1
- data/doc/Users guide Standalone.idmap.txt +74 -0
- data/doc/Users guide Standalone.txt +22 -9
- data/doc/Users guide.txt +51 -0
- data/doc/users_guide_snippets/environment_variables.txt +0 -3
- data/doc/users_guide_snippets/installation.txt +337 -380
- data/doc/users_guide_snippets/installation/run_installer.txt +58 -0
- data/doc/users_guide_snippets/installation/verify_running_epilogue.txt +6 -0
- data/doc/users_guide_snippets/support_information.txt +2 -9
- data/doc/users_guide_snippets/troubleshooting/default.txt +112 -0
- data/doc/users_guide_snippets/troubleshooting/rails.txt +56 -0
- data/doc/users_guide_snippets/where_to_get_support.txt +9 -0
- data/ext/apache2/Bucket.h +1 -1
- data/ext/apache2/Configuration.hpp +0 -44
- data/ext/apache2/CreateDirConfig.cpp +1 -1
- data/ext/apache2/CreateDirConfig.cpp.erb +1 -1
- data/ext/apache2/Hooks.cpp +28 -21
- data/ext/apache2/MergeDirConfig.cpp +1 -0
- data/ext/apache2/MergeDirConfig.cpp.erb +1 -1
- data/ext/apache2/SetHeaders.cpp +73 -0
- data/ext/apache2/SetHeaders.cpp.erb +88 -0
- data/ext/boost/algorithm/string/detail/find_format.hpp +5 -5
- data/ext/boost/algorithm/string/detail/find_format_all.hpp +5 -5
- data/ext/boost/algorithm/string/detail/finder.hpp +1 -1
- data/ext/boost/algorithm/string/formatter.hpp +2 -2
- data/ext/boost/assert.hpp +6 -1
- data/ext/boost/atomic.hpp +18 -0
- data/ext/boost/atomic/atomic.hpp +241 -0
- data/ext/boost/atomic/detail/base.hpp +585 -0
- data/ext/boost/atomic/detail/cas32strong.hpp +885 -0
- data/ext/boost/atomic/detail/cas32weak.hpp +947 -0
- data/ext/boost/atomic/detail/cas64strong.hpp +443 -0
- data/ext/boost/atomic/detail/config.hpp +54 -0
- data/ext/boost/atomic/detail/gcc-alpha.hpp +368 -0
- data/ext/boost/atomic/detail/gcc-armv6plus.hpp +252 -0
- data/ext/boost/atomic/detail/gcc-cas.hpp +157 -0
- data/ext/boost/atomic/detail/gcc-ppc.hpp +2850 -0
- data/ext/boost/atomic/detail/gcc-sparcv9.hpp +1259 -0
- data/ext/boost/atomic/detail/gcc-x86.hpp +1766 -0
- data/ext/boost/atomic/detail/generic-cas.hpp +206 -0
- data/ext/boost/atomic/detail/interlocked.hpp +200 -0
- data/ext/boost/atomic/detail/linux-arm.hpp +189 -0
- data/ext/boost/atomic/detail/lockpool.hpp +97 -0
- data/ext/boost/atomic/detail/platform.hpp +62 -0
- data/ext/boost/atomic/detail/type-classification.hpp +45 -0
- data/ext/boost/chrono/config.hpp +8 -3
- data/ext/boost/chrono/duration.hpp +9 -10
- data/ext/boost/chrono/system_clocks.hpp +1 -1
- data/ext/boost/chrono/time_point.hpp +4 -3
- data/ext/boost/config/auto_link.hpp +53 -52
- data/ext/boost/config/compiler/borland.hpp +1 -0
- data/ext/boost/config/compiler/clang.hpp +24 -1
- data/ext/boost/config/compiler/codegear.hpp +1 -0
- data/ext/boost/config/compiler/common_edg.hpp +1 -0
- data/ext/boost/config/compiler/cray.hpp +1 -0
- data/ext/boost/config/compiler/digitalmars.hpp +1 -0
- data/ext/boost/config/compiler/gcc.hpp +29 -3
- data/ext/boost/config/compiler/gcc_xml.hpp +2 -1
- data/ext/boost/config/compiler/hp_acc.hpp +1 -0
- data/ext/boost/config/compiler/intel.hpp +1 -1
- data/ext/boost/config/compiler/metrowerks.hpp +1 -0
- data/ext/boost/config/compiler/mpw.hpp +1 -0
- data/ext/boost/config/compiler/pathscale.hpp +1 -0
- data/ext/boost/config/compiler/pgi.hpp +1 -0
- data/ext/boost/config/compiler/sunpro_cc.hpp +1 -0
- data/ext/boost/config/compiler/vacpp.hpp +3 -2
- data/ext/boost/config/compiler/visualc.hpp +25 -11
- data/ext/boost/config/platform/vxworks.hpp +353 -15
- data/ext/boost/config/select_compiler_config.hpp +4 -4
- data/ext/boost/config/stdlib/dinkumware.hpp +10 -3
- data/ext/boost/config/stdlib/libstdcpp3.hpp +2 -1
- data/ext/boost/config/suffix.hpp +45 -19
- data/ext/boost/date_time/format_date_parser.hpp +1 -11
- data/ext/boost/date_time/strings_from_facet.hpp +5 -3
- data/ext/boost/detail/atomic_redef_macros.hpp +19 -0
- data/ext/boost/detail/atomic_undef_macros.hpp +39 -0
- data/ext/boost/detail/endian.hpp +52 -4
- data/ext/boost/detail/scoped_enum_emulation.hpp +10 -10
- data/ext/boost/detail/select_type.hpp +36 -0
- data/ext/boost/exception/current_exception_cast.hpp +1 -1
- data/ext/boost/exception/detail/error_info_impl.hpp +3 -5
- data/ext/boost/exception/detail/exception_ptr.hpp +3 -3
- data/ext/boost/exception/detail/is_output_streamable.hpp +1 -1
- data/ext/boost/exception/detail/object_hex_dump.hpp +1 -1
- data/ext/boost/exception/detail/type_info.hpp +1 -1
- data/ext/boost/exception/diagnostic_information.hpp +15 -14
- data/ext/boost/exception/exception.hpp +1 -1
- data/ext/boost/exception/get_error_info.hpp +1 -1
- data/ext/boost/exception/info.hpp +12 -13
- data/ext/boost/exception/to_string.hpp +6 -1
- data/ext/boost/exception/to_string_stub.hpp +9 -1
- data/ext/boost/foreach.hpp +5 -5
- data/ext/boost/function/function_template.hpp +6 -6
- data/ext/boost/functional/hash/detail/float_functions.hpp +90 -0
- data/ext/boost/functional/hash/detail/hash_float.hpp +11 -2
- data/ext/boost/functional/hash/extensions.hpp +14 -2
- data/ext/boost/functional/hash/hash.hpp +26 -5
- data/ext/boost/get_pointer.hpp +17 -2
- data/ext/boost/integer_traits.hpp +1 -1
- data/ext/boost/lexical_cast.hpp +615 -395
- data/ext/boost/libs/atomic/lockpool.cpp +24 -0
- data/ext/boost/libs/system/src/error_code.cpp +25 -18
- data/ext/boost/libs/thread/src/future.cpp +7 -5
- data/ext/boost/libs/thread/src/pthread/once.cpp +9 -3
- data/ext/boost/libs/thread/src/pthread/once_atomic.cpp +90 -0
- data/ext/boost/libs/thread/src/pthread/thread.cpp +129 -95
- data/ext/boost/libs/thread/src/pthread/timeconv.inl +20 -1
- data/ext/boost/limits.hpp +1 -1
- data/ext/boost/math/policies/policy.hpp +10 -0
- data/ext/boost/math/special_functions/detail/round_fwd.hpp +17 -4
- data/ext/boost/math/special_functions/fpclassify.hpp +114 -45
- data/ext/boost/math/special_functions/math_fwd.hpp +195 -83
- data/ext/boost/math/special_functions/sign.hpp +13 -8
- data/ext/boost/math/tools/config.hpp +38 -16
- data/ext/boost/move/algorithm.hpp +275 -0
- data/ext/boost/move/core.hpp +332 -0
- data/ext/boost/move/detail/config_begin.hpp +23 -0
- data/ext/boost/move/detail/config_end.hpp +20 -0
- data/ext/boost/move/detail/meta_utils.hpp +158 -0
- data/ext/boost/move/iterator.hpp +298 -0
- data/ext/boost/move/move.hpp +10 -1256
- data/ext/boost/move/traits.hpp +142 -0
- data/ext/boost/move/utility.hpp +194 -0
- data/ext/boost/mpl/assert.hpp +72 -4
- data/ext/boost/noncopyable.hpp +15 -3
- data/ext/boost/pointer_to_other.hpp +55 -0
- data/ext/boost/range/concepts.hpp +4 -4
- data/ext/boost/range/detail/extract_optional_type.hpp +1 -1
- data/ext/boost/range/empty.hpp +1 -1
- data/ext/boost/range/iterator_range_core.hpp +4 -1
- data/ext/boost/range/iterator_range_io.hpp +2 -2
- data/ext/boost/ratio/config.hpp +6 -0
- data/ext/boost/ratio/detail/overflow_helpers.hpp +2 -2
- data/ext/boost/smart_ptr/allocate_shared_array.hpp +250 -0
- data/ext/boost/smart_ptr/detail/allocate_array_helper.hpp +169 -0
- data/ext/boost/smart_ptr/detail/array_deleter.hpp +124 -0
- data/ext/boost/smart_ptr/detail/array_traits.hpp +53 -0
- data/ext/boost/smart_ptr/detail/array_utility.hpp +178 -0
- data/ext/boost/smart_ptr/detail/make_array_helper.hpp +157 -0
- data/ext/boost/smart_ptr/detail/operator_bool.hpp +16 -9
- data/ext/boost/smart_ptr/detail/shared_count.hpp +78 -7
- data/ext/boost/smart_ptr/detail/sp_convertible.hpp +15 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +12 -6
- data/ext/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_aix.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_nt.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_pt.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +162 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_solaris.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_spin.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_sync.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp +1 -0
- data/ext/boost/smart_ptr/detail/sp_counted_impl.hpp +15 -0
- data/ext/boost/smart_ptr/detail/sp_forward.hpp +39 -0
- data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +19 -3
- data/ext/boost/smart_ptr/detail/sp_if_array.hpp +31 -0
- data/ext/boost/smart_ptr/detail/sp_nullptr_t.hpp +45 -0
- data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +5 -12
- data/ext/boost/smart_ptr/enable_shared_from_this.hpp +4 -4
- data/ext/boost/smart_ptr/make_shared.hpp +5 -1060
- data/ext/boost/smart_ptr/make_shared_array.hpp +247 -0
- data/ext/boost/smart_ptr/make_shared_object.hpp +1128 -0
- data/ext/boost/smart_ptr/scoped_array.hpp +32 -7
- data/ext/boost/smart_ptr/scoped_ptr.hpp +31 -5
- data/ext/boost/smart_ptr/shared_array.hpp +135 -20
- data/ext/boost/smart_ptr/shared_ptr.hpp +444 -126
- data/ext/boost/smart_ptr/weak_ptr.hpp +39 -28
- data/ext/boost/static_assert.hpp +74 -17
- data/ext/boost/system/error_code.hpp +76 -68
- data/ext/boost/system/system_error.hpp +5 -1
- data/ext/boost/thread/barrier.hpp +6 -2
- data/ext/boost/thread/completion_latch.hpp +233 -0
- data/ext/boost/thread/condition.hpp +6 -1
- data/ext/boost/thread/detail/async_func.hpp +571 -0
- data/ext/boost/thread/detail/config.hpp +248 -40
- data/ext/boost/thread/detail/counter.hpp +93 -0
- data/ext/boost/thread/detail/delete.hpp +12 -0
- data/ext/boost/thread/detail/invoke.hpp +1351 -0
- data/ext/boost/thread/detail/is_convertible.hpp +48 -0
- data/ext/boost/thread/detail/lockable_wrapper.hpp +45 -0
- data/ext/boost/thread/detail/log.hpp +83 -0
- data/ext/boost/thread/detail/make_tuple_indices.hpp +224 -0
- data/ext/boost/thread/detail/move.hpp +32 -16
- data/ext/boost/thread/detail/thread.hpp +236 -41
- data/ext/boost/thread/detail/thread_group.hpp +55 -9
- data/ext/boost/thread/detail/thread_interruption.hpp +4 -1
- data/ext/boost/thread/exceptions.hpp +2 -0
- data/ext/boost/thread/externally_locked.hpp +351 -0
- data/ext/boost/thread/externally_locked_stream.hpp +170 -0
- data/ext/boost/thread/future.hpp +2517 -455
- data/ext/boost/thread/future_error_code.hpp +61 -0
- data/ext/boost/thread/is_locked_by_this_thread.hpp +39 -0
- data/ext/boost/thread/latch.hpp +142 -0
- data/ext/boost/thread/lock_algorithms.hpp +468 -0
- data/ext/boost/thread/lock_concepts.hpp +197 -0
- data/ext/boost/thread/lock_factories.hpp +78 -0
- data/ext/boost/thread/lock_guard.hpp +88 -0
- data/ext/boost/thread/lock_options.hpp +31 -0
- data/ext/boost/thread/lock_traits.hpp +45 -0
- data/ext/boost/thread/lock_types.hpp +1226 -0
- data/ext/boost/thread/lockable_adapter.hpp +226 -0
- data/ext/boost/thread/lockable_concepts.hpp +157 -0
- data/ext/boost/thread/lockable_traits.hpp +207 -0
- data/ext/boost/thread/locks.hpp +5 -1816
- data/ext/boost/thread/mutex.hpp +33 -1
- data/ext/boost/thread/null_mutex.hpp +243 -0
- data/ext/boost/thread/once.hpp +10 -1
- data/ext/boost/thread/poly_lockable.hpp +68 -0
- data/ext/boost/thread/poly_lockable_adapter.hpp +89 -0
- data/ext/boost/thread/poly_shared_lockable.hpp +135 -0
- data/ext/boost/thread/poly_shared_lockable_adapter.hpp +170 -0
- data/ext/boost/thread/pthread/condition_variable.hpp +74 -26
- data/ext/boost/thread/pthread/condition_variable_fwd.hpp +54 -27
- data/ext/boost/thread/pthread/mutex.hpp +101 -38
- data/ext/boost/thread/pthread/once.hpp +459 -44
- data/ext/boost/thread/pthread/once_atomic.hpp +313 -0
- data/ext/boost/thread/pthread/recursive_mutex.hpp +19 -10
- data/ext/boost/thread/pthread/shared_mutex.hpp +226 -61
- data/ext/boost/thread/pthread/shared_mutex_assert.hpp +724 -0
- data/ext/boost/thread/pthread/thread_data.hpp +53 -50
- data/ext/boost/thread/pthread/timespec.hpp +96 -12
- data/ext/boost/thread/recursive_mutex.hpp +44 -1
- data/ext/boost/thread/reverse_lock.hpp +3 -2
- data/ext/boost/thread/scoped_thread.hpp +285 -0
- data/ext/boost/thread/shared_lock_guard.hpp +2 -1
- data/ext/boost/thread/shared_mutex.hpp +23 -0
- data/ext/boost/thread/strict_lock.hpp +235 -0
- data/ext/boost/thread/sync_bounded_queue.hpp +594 -0
- data/ext/boost/thread/sync_queue.hpp +516 -0
- data/ext/boost/thread/synchronized_value.hpp +1001 -0
- data/ext/boost/thread/testable_mutex.hpp +148 -0
- data/ext/boost/thread/thread.hpp +1 -13
- data/ext/boost/thread/thread_functors.hpp +57 -0
- data/ext/boost/thread/thread_guard.hpp +46 -0
- data/ext/boost/thread/thread_only.hpp +29 -0
- data/ext/boost/thread/v2/shared_mutex.hpp +1062 -0
- data/ext/boost/thread/v2/thread.hpp +37 -10
- data/ext/boost/thread/xtime.hpp +2 -1
- data/ext/boost/token_functions.hpp +16 -16
- data/ext/boost/type_traits/add_lvalue_reference.hpp +26 -0
- data/ext/boost/type_traits/add_reference.hpp +1 -1
- data/ext/boost/type_traits/add_rvalue_reference.hpp +4 -4
- data/ext/boost/type_traits/aligned_storage.hpp +13 -0
- data/ext/boost/type_traits/common_type.hpp +11 -12
- data/ext/boost/type_traits/config.hpp +1 -1
- data/ext/boost/type_traits/detail/common_type_imp.hpp +1 -1
- data/ext/boost/type_traits/detail/has_binary_operator.hpp +1 -1
- data/ext/boost/type_traits/detail/is_function_ptr_tester.hpp +1 -1
- data/ext/boost/type_traits/has_left_shift.hpp +49 -0
- data/ext/boost/type_traits/has_right_shift.hpp +49 -0
- data/ext/boost/type_traits/has_trivial_move_assign.hpp +57 -0
- data/ext/boost/type_traits/has_trivial_move_constructor.hpp +57 -0
- data/ext/boost/type_traits/intrinsics.hpp +18 -2
- data/ext/boost/type_traits/is_abstract.hpp +1 -1
- data/ext/boost/type_traits/is_array.hpp +1 -1
- data/ext/boost/type_traits/is_const.hpp +1 -1
- data/ext/boost/type_traits/is_convertible.hpp +78 -17
- data/ext/boost/type_traits/is_function.hpp +6 -1
- data/ext/boost/type_traits/is_integral.hpp +6 -1
- data/ext/boost/type_traits/is_nothrow_move_assignable.hpp +84 -0
- data/ext/boost/type_traits/is_nothrow_move_constructible.hpp +84 -0
- data/ext/boost/type_traits/is_pod.hpp +3 -1
- data/ext/boost/type_traits/is_rvalue_reference.hpp +1 -1
- data/ext/boost/type_traits/is_volatile.hpp +1 -1
- data/ext/boost/type_traits/make_signed.hpp +153 -0
- data/ext/boost/type_traits/make_unsigned.hpp +16 -0
- data/ext/boost/type_traits/remove_const.hpp +1 -1
- data/ext/boost/type_traits/remove_cv.hpp +1 -1
- data/ext/boost/type_traits/remove_reference.hpp +1 -1
- data/ext/boost/type_traits/remove_volatile.hpp +1 -1
- data/ext/boost/unordered/detail/allocate.hpp +1120 -0
- data/ext/boost/unordered/detail/buckets.hpp +876 -0
- data/ext/boost/unordered/detail/equivalent.hpp +680 -0
- data/ext/boost/unordered/detail/extract_key.hpp +183 -0
- data/ext/boost/unordered/detail/fwd.hpp +23 -0
- data/ext/boost/unordered/detail/table.hpp +861 -0
- data/ext/boost/unordered/detail/unique.hpp +622 -0
- data/ext/boost/unordered/detail/util.hpp +260 -0
- data/ext/boost/unordered/unordered_map.hpp +1652 -0
- data/ext/boost/unordered/unordered_map_fwd.hpp +65 -0
- data/ext/boost/unordered/unordered_set.hpp +1549 -0
- data/ext/boost/unordered/unordered_set_fwd.hpp +63 -0
- data/ext/boost/unordered_map.hpp +18 -0
- data/ext/boost/unordered_set.hpp +18 -0
- data/ext/boost/utility/addressof.hpp +2 -2
- data/ext/boost/utility/result_of.hpp +8 -1
- data/ext/boost/version.hpp +2 -2
- data/ext/common/Account.h +1 -1
- data/ext/common/AccountsDatabase.h +1 -1
- data/ext/common/AgentsStarter.cpp +3 -1
- data/ext/common/AgentsStarter.h +2 -2
- data/ext/common/ApplicationPool2/AppTypes.cpp +24 -6
- data/ext/common/ApplicationPool2/AppTypes.h +17 -8
- data/ext/common/ApplicationPool2/Common.h +12 -12
- data/ext/common/ApplicationPool2/DirectSpawner.h +2 -2
- data/ext/common/ApplicationPool2/DummySpawner.h +3 -3
- data/ext/common/ApplicationPool2/Group.h +6 -6
- data/ext/common/ApplicationPool2/Implementation.cpp +19 -19
- data/ext/common/ApplicationPool2/PipeWatcher.h +5 -5
- data/ext/common/ApplicationPool2/Pool.h +21 -21
- data/ext/common/ApplicationPool2/Process.h +6 -6
- data/ext/common/ApplicationPool2/Session.h +1 -1
- data/ext/common/ApplicationPool2/SmartSpawner.h +24 -12
- data/ext/common/ApplicationPool2/Socket.h +2 -2
- data/ext/common/ApplicationPool2/Spawner.h +64 -14
- data/ext/common/ApplicationPool2/SpawnerFactory.h +7 -7
- data/ext/common/ApplicationPool2/SuperGroup.h +5 -5
- data/ext/common/BackgroundEventLoop.cpp +4 -4
- data/ext/common/BackgroundEventLoop.h +1 -1
- data/ext/common/Constants.h +13 -1
- data/ext/common/EventedBufferedInput.h +8 -8
- data/ext/common/Exceptions.cpp +71 -0
- data/ext/common/Exceptions.h +60 -7
- data/ext/common/FileDescriptor.h +4 -4
- data/ext/common/MessageClient.h +1 -1
- data/ext/common/MessageServer.h +5 -5
- data/ext/common/MultiLibeio.cpp +3 -3
- data/ext/common/MultiLibeio.h +2 -2
- data/ext/common/RandomGenerator.h +11 -11
- data/ext/common/ResourceLocator.h +8 -1
- data/ext/common/SafeLibev.h +12 -12
- data/ext/common/ServerInstanceDir.h +11 -3
- data/ext/common/UnionStation.h +10 -10
- data/ext/common/Utils.cpp +11 -13
- data/ext/common/Utils.h +9 -9
- data/ext/common/Utils/BlockingQueue.h +10 -10
- data/ext/common/Utils/BufferedIO.h +1 -1
- data/ext/common/Utils/CachedFileStat.hpp +2 -2
- data/ext/common/Utils/FileChangeChecker.h +1 -1
- data/ext/common/Utils/HashMap.h +13 -4
- data/ext/common/Utils/IOUtils.cpp +33 -10
- data/ext/common/Utils/IniFile.h +3 -3
- data/ext/common/Utils/Lock.h +2 -2
- data/ext/common/Utils/MessagePassing.h +10 -10
- data/ext/common/Utils/ProcessMetricsCollector.h +24 -6
- data/ext/common/Utils/ScopeGuard.h +5 -5
- data/ext/common/Utils/jsoncpp.cpp +2 -0
- data/ext/common/agents/HelperAgent/FileBackedPipe.h +26 -26
- data/ext/common/agents/HelperAgent/Main.cpp +18 -18
- data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
- data/ext/common/agents/HelperAgent/RequestHandler.h +30 -21
- data/ext/common/agents/LoggingAgent/AdminController.h +1 -1
- data/ext/common/agents/LoggingAgent/FilterSupport.h +13 -11
- data/ext/common/agents/LoggingAgent/LoggingServer.h +11 -11
- data/ext/common/agents/LoggingAgent/Main.cpp +9 -9
- data/ext/common/agents/LoggingAgent/RemoteSender.h +3 -3
- data/ext/common/agents/SpawnPreparer.cpp +1 -0
- data/ext/common/agents/Watchdog/AgentWatcher.cpp +8 -7
- data/ext/common/agents/Watchdog/Main.cpp +81 -73
- data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +1 -1
- data/ext/libev/Changes +57 -0
- data/ext/libev/LICENSE +2 -1
- data/ext/libev/Makefile.in +110 -50
- data/ext/libev/README +8 -8
- data/ext/libev/aclocal.m4 +1503 -861
- data/ext/libev/config.guess +290 -304
- data/ext/libev/config.sub +77 -198
- data/ext/libev/configure +1735 -890
- data/ext/libev/configure.ac +3 -2
- data/ext/libev/ev++.h +6 -6
- data/ext/libev/ev.c +541 -214
- data/ext/libev/ev.h +106 -100
- data/ext/libev/ev_epoll.c +1 -1
- data/ext/libev/ev_kqueue.c +20 -4
- data/ext/libev/ev_vars.h +15 -16
- data/ext/libev/ev_win32.c +12 -2
- data/ext/libev/ev_wrap.h +162 -160
- data/ext/libev/event.c +29 -6
- data/ext/libev/event.h +9 -2
- data/ext/libev/ltmain.sh +2632 -1384
- data/ext/nginx/ConfigurationCommands.c +1 -1
- data/ext/nginx/ConfigurationCommands.c.erb +3 -1
- data/ext/nginx/ContentHandler.c +25 -2
- data/ext/nginx/CreateLocationConfig.c +1 -0
- data/ext/nginx/CreateLocationConfig.c.erb +1 -1
- data/ext/nginx/MergeLocationConfig.c +1 -0
- data/ext/nginx/MergeLocationConfig.c.erb +1 -1
- data/ext/nginx/config +12 -0
- data/ext/oxt/dynamic_thread_group.hpp +7 -4
- data/ext/oxt/system_calls.cpp +5 -1
- data/ext/oxt/system_calls.hpp +3 -0
- data/helper-scripts/node-loader.js +117 -249
- data/lib/phusion_passenger.rb +27 -5
- data/lib/phusion_passenger/abstract_installer.rb +104 -9
- data/lib/phusion_passenger/admin_tools/memory_stats.rb +10 -9
- data/lib/phusion_passenger/apache2/config_options.rb +6 -3
- data/lib/phusion_passenger/common_library.rb +7 -1
- data/lib/phusion_passenger/constants.rb +6 -0
- data/lib/phusion_passenger/loader_shared_helpers.rb +7 -4
- data/lib/phusion_passenger/nginx/config_options.rb +2 -1
- data/lib/phusion_passenger/packaging.rb +3 -0
- data/lib/phusion_passenger/platform_info/apache.rb +43 -6
- data/lib/phusion_passenger/platform_info/apache_detector.rb +15 -5
- data/lib/phusion_passenger/platform_info/compiler.rb +167 -32
- data/lib/phusion_passenger/platform_info/cxx_portability.rb +133 -77
- data/lib/phusion_passenger/platform_info/depcheck.rb +17 -7
- data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +3 -3
- data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
- data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +5 -6
- data/lib/phusion_passenger/platform_info/linux.rb +2 -1
- data/lib/phusion_passenger/platform_info/operating_system.rb +1 -1
- data/lib/phusion_passenger/platform_info/ruby.rb +18 -3
- data/lib/phusion_passenger/standalone/runtime_installer.rb +6 -2
- data/lib/phusion_passenger/standalone/start_command.rb +8 -2
- data/lib/phusion_passenger/utils/ansi_colors.rb +9 -0
- data/lib/phusion_passenger/utils/hosts_file_parser.rb +4 -2
- data/node_lib/phusion_passenger/httplib_emulation.js +141 -0
- data/node_lib/phusion_passenger/line_reader.js +154 -0
- data/node_lib/phusion_passenger/request_handler.js +65 -0
- data/node_lib/phusion_passenger/session_protocol_parser.js +113 -0
- data/resources/templates/apache2/deployment_example.txt.erb +2 -1
- data/resources/templates/apache2/installing_against_a_different_apache.txt.erb +14 -0
- data/resources/templates/apache2/multiple_apache_installations_detected.txt.erb +15 -0
- data/resources/templates/apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb +4 -5
- data/resources/templates/general_error_with_html.html.template +1 -1
- data/resources/templates/installer_common/gem_install_permission_problems.txt.erb +17 -0
- data/resources/templates/installer_common/low_amount_of_memory_warning.txt.erb +6 -4
- data/resources/templates/installer_common/world_inaccessible_directories.txt.erb +16 -0
- data/resources/templates/nginx/deployment_example.txt.erb +2 -1
- data/resources/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +4 -5
- data/resources/templates/standalone/config.erb +1 -0
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +3 -3
- data/test/cxx/ApplicationPool2/PoolTest.cpp +4 -4
- data/test/cxx/ApplicationPool2/ProcessTest.cpp +5 -5
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +5 -5
- data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +1 -1
- data/test/cxx/EventedBufferedInputTest.cpp +6 -6
- data/test/cxx/FileBackedPipeTest.cpp +1 -1
- data/test/cxx/MessagePassingTest.cpp +1 -1
- data/test/cxx/MessageServerTest.cpp +4 -4
- data/test/cxx/RequestHandlerTest.cpp +7 -7
- data/test/cxx/UnionStationTest.cpp +2 -2
- data/test/node/line_reader_spec.js +338 -0
- data/test/node/spec_helper.js +27 -0
- data/test/ruby/standalone/runtime_installer_spec.rb +2 -1
- metadata +131 -22
- metadata.gz.asc +7 -7
- data/ext/boost/functional/hash/detail/container_fwd_0x.hpp +0 -29
- data/ext/boost/lambda/core.hpp +0 -79
- data/ext/boost/lambda/detail/actions.hpp +0 -174
- data/ext/boost/lambda/detail/arity_code.hpp +0 -110
- data/ext/boost/lambda/detail/function_adaptors.hpp +0 -789
- data/ext/boost/lambda/detail/is_instance_of.hpp +0 -104
- data/ext/boost/lambda/detail/lambda_config.hpp +0 -48
- data/ext/boost/lambda/detail/lambda_functor_base.hpp +0 -615
- data/ext/boost/lambda/detail/lambda_functors.hpp +0 -324
- data/ext/boost/lambda/detail/lambda_fwd.hpp +0 -74
- data/ext/boost/lambda/detail/lambda_traits.hpp +0 -578
- data/ext/boost/lambda/detail/member_ptr.hpp +0 -737
- data/ext/boost/lambda/detail/operator_actions.hpp +0 -139
- data/ext/boost/lambda/detail/operator_lambda_func_base.hpp +0 -271
- data/ext/boost/lambda/detail/operator_return_type_traits.hpp +0 -917
- data/ext/boost/lambda/detail/operators.hpp +0 -370
- data/ext/boost/lambda/detail/ret.hpp +0 -325
- data/ext/boost/lambda/detail/return_type_traits.hpp +0 -282
- data/ext/boost/lambda/detail/select_functions.hpp +0 -74
- data/ext/boost/lambda/lambda.hpp +0 -34
@@ -0,0 +1,197 @@
|
|
1
|
+
// (C) Copyright 2012 Vicente Botet
|
2
|
+
//
|
3
|
+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
4
|
+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
5
|
+
|
6
|
+
#ifndef BOOST_THREAD_LOCK_CONCEPTS_HPP
|
7
|
+
#define BOOST_THREAD_LOCK_CONCEPTS_HPP
|
8
|
+
|
9
|
+
#include <boost/thread/lock_traits.hpp>
|
10
|
+
#include <boost/thread/lock_options.hpp>
|
11
|
+
#include <boost/thread/lockable_concepts.hpp>
|
12
|
+
#include <boost/thread/exceptions.hpp>
|
13
|
+
#include <boost/thread/detail/move.hpp>
|
14
|
+
|
15
|
+
#include <boost/chrono/chrono.hpp>
|
16
|
+
#include <boost/concept_check.hpp>
|
17
|
+
#include <boost/static_assert.hpp>
|
18
|
+
|
19
|
+
namespace boost
|
20
|
+
{
|
21
|
+
|
22
|
+
/**
|
23
|
+
* BasicLock object supports the basic features
|
24
|
+
* required to delimit a critical region
|
25
|
+
* Supports the basic lock, unlock and try_lock functions and
|
26
|
+
* defines the lock traits
|
27
|
+
*/
|
28
|
+
|
29
|
+
template <typename Lk>
|
30
|
+
struct BasicLock
|
31
|
+
{
|
32
|
+
typedef typename Lk::mutex_type mutex_type;
|
33
|
+
void cvt_mutex_ptr(mutex_type*) {}
|
34
|
+
BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
|
35
|
+
|
36
|
+
BOOST_CONCEPT_USAGE(BasicLock)
|
37
|
+
{
|
38
|
+
const Lk l1(mtx);
|
39
|
+
Lk l2(mtx, defer_lock);
|
40
|
+
Lk l3(mtx, adopt_lock);
|
41
|
+
Lk l4(( Lk()));
|
42
|
+
Lk l5(( boost::move(l2)));
|
43
|
+
cvt_mutex_ptr(l1.mutex());
|
44
|
+
if (l1.owns_lock()) return;
|
45
|
+
if (l1) return;
|
46
|
+
if (!l1) return;
|
47
|
+
|
48
|
+
l2.lock();
|
49
|
+
l2.unlock();
|
50
|
+
l2.release();
|
51
|
+
|
52
|
+
}
|
53
|
+
BasicLock() :
|
54
|
+
mtx(*static_cast<mutex_type*>(0))
|
55
|
+
{}
|
56
|
+
private:
|
57
|
+
BasicLock operator=(BasicLock const&);
|
58
|
+
mutex_type& mtx;
|
59
|
+
}
|
60
|
+
;
|
61
|
+
|
62
|
+
template <typename Lk>
|
63
|
+
struct Lock
|
64
|
+
{
|
65
|
+
BOOST_CONCEPT_ASSERT(( BasicLock<Lk> ));
|
66
|
+
typedef typename Lk::mutex_type mutex_type;
|
67
|
+
BOOST_CONCEPT_ASSERT(( Lockable<mutex_type> ));
|
68
|
+
|
69
|
+
BOOST_CONCEPT_USAGE(Lock)
|
70
|
+
{
|
71
|
+
Lk l1(mtx, try_to_lock);
|
72
|
+
if (l1.try_lock()) return;
|
73
|
+
}
|
74
|
+
Lock() :
|
75
|
+
mtx(*static_cast<mutex_type*>(0))
|
76
|
+
{}
|
77
|
+
private:
|
78
|
+
Lock operator=(Lock const&);
|
79
|
+
mutex_type& mtx;
|
80
|
+
};
|
81
|
+
|
82
|
+
template <typename Lk>
|
83
|
+
struct TimedLock
|
84
|
+
{
|
85
|
+
BOOST_CONCEPT_ASSERT(( Lock<Lk> ));
|
86
|
+
typedef typename Lk::mutex_type mutex_type;
|
87
|
+
BOOST_CONCEPT_ASSERT(( TimedLockable<mutex_type> ));
|
88
|
+
|
89
|
+
BOOST_CONCEPT_USAGE(TimedLock)
|
90
|
+
{
|
91
|
+
const Lk l1(mtx, t);
|
92
|
+
Lk l2(mtx, d);
|
93
|
+
if (l1.try_lock_until(t)) return;
|
94
|
+
if (l1.try_lock_for(d)) return;
|
95
|
+
}
|
96
|
+
TimedLock() :
|
97
|
+
mtx(*static_cast<mutex_type*>(0))
|
98
|
+
{}
|
99
|
+
private:
|
100
|
+
TimedLock operator=(TimedLock const&);
|
101
|
+
mutex_type& mtx;
|
102
|
+
boost::chrono::system_clock::time_point t;
|
103
|
+
boost::chrono::system_clock::duration d;
|
104
|
+
};
|
105
|
+
|
106
|
+
template <typename Lk>
|
107
|
+
struct UniqueLock
|
108
|
+
{
|
109
|
+
BOOST_CONCEPT_ASSERT(( TimedLock<Lk> ));
|
110
|
+
typedef typename Lk::mutex_type mutex_type;
|
111
|
+
|
112
|
+
BOOST_CONCEPT_USAGE(UniqueLock)
|
113
|
+
{
|
114
|
+
|
115
|
+
}
|
116
|
+
UniqueLock() :
|
117
|
+
mtx(*static_cast<mutex_type*>(0))
|
118
|
+
{}
|
119
|
+
private:
|
120
|
+
UniqueLock operator=(UniqueLock const&);
|
121
|
+
mutex_type& mtx;
|
122
|
+
};
|
123
|
+
|
124
|
+
template <typename Lk>
|
125
|
+
struct SharedLock
|
126
|
+
{
|
127
|
+
BOOST_CONCEPT_ASSERT(( TimedLock<Lk> ));
|
128
|
+
typedef typename Lk::mutex_type mutex_type;
|
129
|
+
|
130
|
+
BOOST_CONCEPT_USAGE(SharedLock)
|
131
|
+
{
|
132
|
+
}
|
133
|
+
SharedLock() :
|
134
|
+
mtx(*static_cast<mutex_type*>(0))
|
135
|
+
{}
|
136
|
+
private:
|
137
|
+
SharedLock operator=(SharedLock const&);
|
138
|
+
mutex_type& mtx;
|
139
|
+
|
140
|
+
};
|
141
|
+
|
142
|
+
template <typename Lk>
|
143
|
+
struct UpgradeLock
|
144
|
+
{
|
145
|
+
BOOST_CONCEPT_ASSERT(( SharedLock<Lk> ));
|
146
|
+
typedef typename Lk::mutex_type mutex_type;
|
147
|
+
|
148
|
+
BOOST_CONCEPT_USAGE(UpgradeLock)
|
149
|
+
{
|
150
|
+
}
|
151
|
+
UpgradeLock() :
|
152
|
+
mtx(*static_cast<mutex_type*>(0))
|
153
|
+
{}
|
154
|
+
private:
|
155
|
+
UpgradeLock operator=(UpgradeLock const&);
|
156
|
+
mutex_type& mtx;
|
157
|
+
};
|
158
|
+
|
159
|
+
/**
|
160
|
+
* An StrictLock is a scoped lock guard ensuring the mutex is locked on the
|
161
|
+
* scope of the lock, by locking the mutex on construction and unlocking it on
|
162
|
+
* destruction.
|
163
|
+
*
|
164
|
+
* Essentially, a StrictLock's role is only to live on the stack as an
|
165
|
+
* automatic variable. strict_lock must adhere to a non-copy and non-alias
|
166
|
+
* policy. StrictLock disables copying by making the copy constructor and the
|
167
|
+
* assignment operator private. While we're at it, let's disable operator new
|
168
|
+
* and operator delete; strict locks are not intended to be allocated on the
|
169
|
+
* heap. StrictLock avoids aliasing by using a slightly less orthodox and
|
170
|
+
* less well-known technique: disable address taking.
|
171
|
+
*/
|
172
|
+
|
173
|
+
template <typename Lk>
|
174
|
+
struct StrictLock
|
175
|
+
{
|
176
|
+
typedef typename Lk::mutex_type mutex_type;
|
177
|
+
BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
|
178
|
+
BOOST_STATIC_ASSERT(( is_strict_lock<Lk>::value ));
|
179
|
+
|
180
|
+
BOOST_CONCEPT_USAGE( StrictLock)
|
181
|
+
{
|
182
|
+
if (l1.owns_lock(&mtx)) return;
|
183
|
+
}
|
184
|
+
StrictLock() :
|
185
|
+
l1(*static_cast<Lk*>(0)),
|
186
|
+
mtx(*static_cast<mutex_type*>(0))
|
187
|
+
{}
|
188
|
+
private:
|
189
|
+
StrictLock operator=(StrictLock const&);
|
190
|
+
|
191
|
+
Lk const& l1;
|
192
|
+
mutex_type const& mtx;
|
193
|
+
|
194
|
+
};
|
195
|
+
|
196
|
+
}
|
197
|
+
#endif
|
@@ -0,0 +1,78 @@
|
|
1
|
+
// Distributed under the Boost Software License, Version 1.0. (See
|
2
|
+
// accompanying file LICENSE_1_0.txt or copy at
|
3
|
+
// http://www.boost.org/LICENSE_1_0.txt)
|
4
|
+
// (C) Copyright 2012 Vicente J. Botet Escriba
|
5
|
+
|
6
|
+
#ifndef BOOST_THREAD_LOCK_FACTORIES_HPP
|
7
|
+
#define BOOST_THREAD_LOCK_FACTORIES_HPP
|
8
|
+
|
9
|
+
#include <boost/thread/lock_types.hpp>
|
10
|
+
#include <boost/thread/lock_algorithms.hpp>
|
11
|
+
#if ! defined(BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS)
|
12
|
+
#include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics.
|
13
|
+
#endif
|
14
|
+
#include <boost/config/abi_prefix.hpp>
|
15
|
+
|
16
|
+
namespace boost
|
17
|
+
{
|
18
|
+
|
19
|
+
template <typename Lockable>
|
20
|
+
unique_lock<Lockable> make_unique_lock(Lockable& mtx)
|
21
|
+
{
|
22
|
+
return unique_lock<Lockable> (mtx);
|
23
|
+
}
|
24
|
+
|
25
|
+
template <typename Lockable>
|
26
|
+
unique_lock<Lockable> make_unique_lock(Lockable& mtx, adopt_lock_t)
|
27
|
+
{
|
28
|
+
return unique_lock<Lockable> (mtx, adopt_lock);
|
29
|
+
}
|
30
|
+
|
31
|
+
template <typename Lockable>
|
32
|
+
unique_lock<Lockable> make_unique_lock(Lockable& mtx, defer_lock_t)
|
33
|
+
{
|
34
|
+
return unique_lock<Lockable> (mtx, defer_lock);
|
35
|
+
}
|
36
|
+
|
37
|
+
template <typename Lockable>
|
38
|
+
unique_lock<Lockable> make_unique_lock(Lockable& mtx, try_to_lock_t)
|
39
|
+
{
|
40
|
+
return unique_lock<Lockable> (mtx, try_to_lock);
|
41
|
+
}
|
42
|
+
#if ! defined(BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS)
|
43
|
+
|
44
|
+
#if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
45
|
+
template <typename ...Lockable>
|
46
|
+
std::tuple<unique_lock<Lockable> ...> make_unique_locks(Lockable& ...mtx)
|
47
|
+
{
|
48
|
+
boost::lock(mtx...);
|
49
|
+
return std::tuple<unique_lock<Lockable> ...>(unique_lock<Lockable>(mtx, adopt_lock)...);
|
50
|
+
}
|
51
|
+
#else
|
52
|
+
template <typename L1, typename L2>
|
53
|
+
std::tuple<unique_lock<L1>, unique_lock<L2> > make_unique_locks(L1& m1, L2& m2)
|
54
|
+
{
|
55
|
+
boost::lock(m1, m2);
|
56
|
+
return std::tuple<unique_lock<L1>,unique_lock<L2> >(
|
57
|
+
unique_lock<L1>(m1, adopt_lock),
|
58
|
+
unique_lock<L2>(m2, adopt_lock)
|
59
|
+
);
|
60
|
+
}
|
61
|
+
template <typename L1, typename L2, typename L3>
|
62
|
+
std::tuple<unique_lock<L1>, unique_lock<L2>, unique_lock<L3> > make_unique_locks(L1& m1, L2& m2, L3& m3)
|
63
|
+
{
|
64
|
+
boost::lock(m1, m2, m3);
|
65
|
+
return std::tuple<unique_lock<L1>,unique_lock<L2>,unique_lock<L3> >(
|
66
|
+
unique_lock<L1>(m1, adopt_lock),
|
67
|
+
unique_lock<L2>(m2, adopt_lock),
|
68
|
+
unique_lock<L3>(m3, adopt_lock)
|
69
|
+
);
|
70
|
+
}
|
71
|
+
|
72
|
+
#endif
|
73
|
+
#endif
|
74
|
+
|
75
|
+
}
|
76
|
+
|
77
|
+
#include <boost/config/abi_suffix.hpp>
|
78
|
+
#endif
|
@@ -0,0 +1,88 @@
|
|
1
|
+
// Distributed under the Boost Software License, Version 1.0. (See
|
2
|
+
// accompanying file LICENSE_1_0.txt or copy at
|
3
|
+
// http://www.boost.org/LICENSE_1_0.txt)
|
4
|
+
// (C) Copyright 2007 Anthony Williams
|
5
|
+
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
|
6
|
+
|
7
|
+
#ifndef BOOST_THREAD_LOCK_GUARD_HPP
|
8
|
+
#define BOOST_THREAD_LOCK_GUARD_HPP
|
9
|
+
|
10
|
+
#include <boost/thread/detail/config.hpp>
|
11
|
+
#include <boost/thread/detail/delete.hpp>
|
12
|
+
#include <boost/thread/detail/move.hpp>
|
13
|
+
#include <boost/thread/detail/lockable_wrapper.hpp>
|
14
|
+
#include <boost/thread/lock_options.hpp>
|
15
|
+
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
|
16
|
+
#include <boost/thread/is_locked_by_this_thread.hpp>
|
17
|
+
#include <boost/assert.hpp>
|
18
|
+
#endif
|
19
|
+
|
20
|
+
#include <boost/config/abi_prefix.hpp>
|
21
|
+
|
22
|
+
namespace boost
|
23
|
+
{
|
24
|
+
|
25
|
+
template <typename Mutex>
|
26
|
+
class lock_guard
|
27
|
+
{
|
28
|
+
private:
|
29
|
+
Mutex& m;
|
30
|
+
|
31
|
+
public:
|
32
|
+
typedef Mutex mutex_type;
|
33
|
+
BOOST_THREAD_NO_COPYABLE( lock_guard )
|
34
|
+
|
35
|
+
explicit lock_guard(Mutex& m_) :
|
36
|
+
m(m_)
|
37
|
+
{
|
38
|
+
m.lock();
|
39
|
+
}
|
40
|
+
|
41
|
+
lock_guard(Mutex& m_, adopt_lock_t) :
|
42
|
+
m(m_)
|
43
|
+
{
|
44
|
+
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
|
45
|
+
BOOST_ASSERT(is_locked_by_this_thread(m));
|
46
|
+
#endif
|
47
|
+
}
|
48
|
+
|
49
|
+
#if ! defined BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST
|
50
|
+
lock_guard(std::initializer_list<thread_detail::lockable_wrapper<Mutex> > l_) :
|
51
|
+
m(*(const_cast<thread_detail::lockable_wrapper<Mutex>*>(l_.begin())->m))
|
52
|
+
{
|
53
|
+
m.lock();
|
54
|
+
}
|
55
|
+
|
56
|
+
lock_guard(std::initializer_list<thread_detail::lockable_adopt_wrapper<Mutex> > l_) :
|
57
|
+
m(*(const_cast<thread_detail::lockable_adopt_wrapper<Mutex>*>(l_.begin())->m))
|
58
|
+
{
|
59
|
+
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
|
60
|
+
BOOST_ASSERT(is_locked_by_this_thread(m));
|
61
|
+
#endif
|
62
|
+
}
|
63
|
+
|
64
|
+
#endif
|
65
|
+
~lock_guard()
|
66
|
+
{
|
67
|
+
m.unlock();
|
68
|
+
}
|
69
|
+
};
|
70
|
+
|
71
|
+
|
72
|
+
#if ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD
|
73
|
+
template <typename Lockable>
|
74
|
+
lock_guard<Lockable> make_lock_guard(Lockable& mtx)
|
75
|
+
{
|
76
|
+
return { thread_detail::lockable_wrapper<Lockable>(mtx) };
|
77
|
+
}
|
78
|
+
template <typename Lockable>
|
79
|
+
lock_guard<Lockable> make_lock_guard(Lockable& mtx, adopt_lock_t)
|
80
|
+
{
|
81
|
+
return { thread_detail::lockable_adopt_wrapper<Lockable>(mtx) };
|
82
|
+
}
|
83
|
+
#endif
|
84
|
+
}
|
85
|
+
|
86
|
+
#include <boost/config/abi_suffix.hpp>
|
87
|
+
|
88
|
+
#endif
|
@@ -0,0 +1,31 @@
|
|
1
|
+
// Distributed under the Boost Software License, Version 1.0. (See
|
2
|
+
// accompanying file LICENSE_1_0.txt or copy at
|
3
|
+
// http://www.boost.org/LICENSE_1_0.txt)
|
4
|
+
// (C) Copyright 2007 Anthony Williams
|
5
|
+
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
|
6
|
+
|
7
|
+
#ifndef BOOST_THREAD_LOCK_OPTIONS_HPP
|
8
|
+
#define BOOST_THREAD_LOCK_OPTIONS_HPP
|
9
|
+
|
10
|
+
#include <boost/config/abi_prefix.hpp>
|
11
|
+
|
12
|
+
namespace boost
|
13
|
+
{
|
14
|
+
struct defer_lock_t
|
15
|
+
{
|
16
|
+
};
|
17
|
+
struct try_to_lock_t
|
18
|
+
{
|
19
|
+
};
|
20
|
+
struct adopt_lock_t
|
21
|
+
{
|
22
|
+
};
|
23
|
+
|
24
|
+
BOOST_CONSTEXPR_OR_CONST defer_lock_t defer_lock = {};
|
25
|
+
BOOST_CONSTEXPR_OR_CONST try_to_lock_t try_to_lock = {};
|
26
|
+
BOOST_CONSTEXPR_OR_CONST adopt_lock_t adopt_lock = {};
|
27
|
+
|
28
|
+
}
|
29
|
+
#include <boost/config/abi_suffix.hpp>
|
30
|
+
|
31
|
+
#endif
|
@@ -0,0 +1,45 @@
|
|
1
|
+
// Distributed under the Boost Software License, Version 1.0. (See
|
2
|
+
// accompanying file LICENSE_1_0.txt or copy at
|
3
|
+
// http://www.boost.org/LICENSE_1_0.txt)
|
4
|
+
// (C) Copyright 2009-2012 Vicente J. Botet Escriba
|
5
|
+
|
6
|
+
#ifndef BOOST_THREAD_LOCK_TRAITS_HPP
|
7
|
+
#define BOOST_THREAD_LOCK_TRAITS_HPP
|
8
|
+
|
9
|
+
#include <boost/thread/detail/config.hpp>
|
10
|
+
//#include <boost/thread/detail/move.hpp>
|
11
|
+
//#include <boost/thread/exceptions.hpp>
|
12
|
+
//
|
13
|
+
//#ifdef BOOST_THREAD_USES_CHRONO
|
14
|
+
//#include <boost/chrono/time_point.hpp>
|
15
|
+
//#include <boost/chrono/duration.hpp>
|
16
|
+
//#endif
|
17
|
+
|
18
|
+
#include <boost/type_traits/integral_constant.hpp>
|
19
|
+
|
20
|
+
#include <boost/config/abi_prefix.hpp>
|
21
|
+
|
22
|
+
namespace boost
|
23
|
+
{
|
24
|
+
|
25
|
+
/**
|
26
|
+
* An strict lock is a lock ensuring the mutex is locked on the scope of the lock
|
27
|
+
* There is no single way to define a strict lock as the strict_lock and
|
28
|
+
* nesteed_strict_lock shows. So we need a metafunction that states if a
|
29
|
+
* lock is a strict lock "sur parole".
|
30
|
+
*/
|
31
|
+
|
32
|
+
template <typename Lock>
|
33
|
+
struct is_strict_lock_sur_parolle : false_type {};
|
34
|
+
|
35
|
+
|
36
|
+
template <typename Lock>
|
37
|
+
struct is_strict_lock_sur_parole : is_strict_lock_sur_parolle<Lock> {};
|
38
|
+
|
39
|
+
template <typename Lock>
|
40
|
+
struct is_strict_lock : is_strict_lock_sur_parole<Lock> {};
|
41
|
+
|
42
|
+
}
|
43
|
+
#include <boost/config/abi_suffix.hpp>
|
44
|
+
|
45
|
+
#endif
|
@@ -0,0 +1,1226 @@
|
|
1
|
+
// Distributed under the Boost Software License, Version 1.0. (See
|
2
|
+
// accompanying file LICENSE_1_0.txt or copy at
|
3
|
+
// http://www.boost.org/LICENSE_1_0.txt)
|
4
|
+
// (C) Copyright 2007 Anthony Williams
|
5
|
+
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
|
6
|
+
|
7
|
+
#ifndef BOOST_THREAD_LOCK_TYPES_HPP
|
8
|
+
#define BOOST_THREAD_LOCK_TYPES_HPP
|
9
|
+
|
10
|
+
#include <boost/thread/detail/config.hpp>
|
11
|
+
#include <boost/thread/detail/move.hpp>
|
12
|
+
#include <boost/thread/exceptions.hpp>
|
13
|
+
#include <boost/thread/lock_options.hpp>
|
14
|
+
#include <boost/thread/lockable_traits.hpp>
|
15
|
+
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
|
16
|
+
#include <boost/thread/is_locked_by_this_thread.hpp>
|
17
|
+
#endif
|
18
|
+
#include <boost/thread/thread_time.hpp>
|
19
|
+
|
20
|
+
#include <boost/assert.hpp>
|
21
|
+
#ifdef BOOST_THREAD_USES_CHRONO
|
22
|
+
#include <boost/chrono/time_point.hpp>
|
23
|
+
#include <boost/chrono/duration.hpp>
|
24
|
+
#endif
|
25
|
+
#include <boost/detail/workaround.hpp>
|
26
|
+
|
27
|
+
#include <boost/config/abi_prefix.hpp>
|
28
|
+
|
29
|
+
namespace boost
|
30
|
+
{
|
31
|
+
struct xtime;
|
32
|
+
|
33
|
+
template <typename Mutex>
|
34
|
+
class shared_lock;
|
35
|
+
|
36
|
+
template <typename Mutex>
|
37
|
+
class upgrade_lock;
|
38
|
+
|
39
|
+
template <typename Mutex>
|
40
|
+
class unique_lock;
|
41
|
+
|
42
|
+
namespace detail
|
43
|
+
{
|
44
|
+
template <typename Mutex>
|
45
|
+
class try_lock_wrapper;
|
46
|
+
}
|
47
|
+
|
48
|
+
#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
|
49
|
+
namespace sync
|
50
|
+
{
|
51
|
+
template<typename T>
|
52
|
+
struct is_basic_lockable<unique_lock<T> >
|
53
|
+
{
|
54
|
+
BOOST_STATIC_CONSTANT(bool, value = true);
|
55
|
+
};
|
56
|
+
template<typename T>
|
57
|
+
struct is_lockable<unique_lock<T> >
|
58
|
+
{
|
59
|
+
BOOST_STATIC_CONSTANT(bool, value = true);
|
60
|
+
};
|
61
|
+
|
62
|
+
template<typename T>
|
63
|
+
struct is_basic_lockable<shared_lock<T> >
|
64
|
+
{
|
65
|
+
BOOST_STATIC_CONSTANT(bool, value = true);
|
66
|
+
};
|
67
|
+
template<typename T>
|
68
|
+
struct is_lockable<shared_lock<T> >
|
69
|
+
{
|
70
|
+
BOOST_STATIC_CONSTANT(bool, value = true);
|
71
|
+
};
|
72
|
+
|
73
|
+
template<typename T>
|
74
|
+
struct is_basic_lockable<upgrade_lock<T> >
|
75
|
+
{
|
76
|
+
BOOST_STATIC_CONSTANT(bool, value = true);
|
77
|
+
};
|
78
|
+
template<typename T>
|
79
|
+
struct is_lockable<upgrade_lock<T> >
|
80
|
+
{
|
81
|
+
BOOST_STATIC_CONSTANT(bool, value = true);
|
82
|
+
};
|
83
|
+
|
84
|
+
template<typename T>
|
85
|
+
struct is_basic_lockable<detail::try_lock_wrapper<T> >
|
86
|
+
{
|
87
|
+
BOOST_STATIC_CONSTANT(bool, value = true);
|
88
|
+
};
|
89
|
+
template<typename T>
|
90
|
+
struct is_lockable<detail::try_lock_wrapper<T> >
|
91
|
+
{
|
92
|
+
BOOST_STATIC_CONSTANT(bool, value = true);
|
93
|
+
};
|
94
|
+
}
|
95
|
+
#endif
|
96
|
+
|
97
|
+
|
98
|
+
template <typename Mutex>
|
99
|
+
class unique_lock
|
100
|
+
{
|
101
|
+
private:
|
102
|
+
Mutex* m;
|
103
|
+
bool is_locked;
|
104
|
+
|
105
|
+
private:
|
106
|
+
explicit unique_lock(upgrade_lock<Mutex>&);
|
107
|
+
unique_lock& operator=(upgrade_lock<Mutex>& other);
|
108
|
+
public:
|
109
|
+
typedef Mutex mutex_type;
|
110
|
+
BOOST_THREAD_MOVABLE_ONLY( unique_lock)
|
111
|
+
|
112
|
+
#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
|
113
|
+
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
|
114
|
+
unique_lock(const volatile unique_lock&);
|
115
|
+
#endif
|
116
|
+
#endif
|
117
|
+
unique_lock()BOOST_NOEXCEPT :
|
118
|
+
m(0),is_locked(false)
|
119
|
+
{}
|
120
|
+
|
121
|
+
explicit unique_lock(Mutex& m_) :
|
122
|
+
m(&m_), is_locked(false)
|
123
|
+
{
|
124
|
+
lock();
|
125
|
+
}
|
126
|
+
unique_lock(Mutex& m_, adopt_lock_t) :
|
127
|
+
m(&m_), is_locked(true)
|
128
|
+
{
|
129
|
+
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
|
130
|
+
BOOST_ASSERT(is_locked_by_this_thread(m));
|
131
|
+
#endif
|
132
|
+
}
|
133
|
+
unique_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
|
134
|
+
m(&m_),is_locked(false)
|
135
|
+
{}
|
136
|
+
unique_lock(Mutex& m_, try_to_lock_t) :
|
137
|
+
m(&m_), is_locked(false)
|
138
|
+
{
|
139
|
+
try_lock();
|
140
|
+
}
|
141
|
+
#if defined BOOST_THREAD_USES_DATETIME
|
142
|
+
template<typename TimeDuration>
|
143
|
+
unique_lock(Mutex& m_,TimeDuration const& target_time):
|
144
|
+
m(&m_),is_locked(false)
|
145
|
+
{
|
146
|
+
timed_lock(target_time);
|
147
|
+
}
|
148
|
+
unique_lock(Mutex& m_,system_time const& target_time):
|
149
|
+
m(&m_),is_locked(false)
|
150
|
+
{
|
151
|
+
timed_lock(target_time);
|
152
|
+
}
|
153
|
+
#endif
|
154
|
+
#ifdef BOOST_THREAD_USES_CHRONO
|
155
|
+
template <class Clock, class Duration>
|
156
|
+
unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
|
157
|
+
: m(&mtx), is_locked(mtx.try_lock_until(t))
|
158
|
+
{
|
159
|
+
}
|
160
|
+
template <class Rep, class Period>
|
161
|
+
unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
|
162
|
+
: m(&mtx), is_locked(mtx.try_lock_for(d))
|
163
|
+
{
|
164
|
+
}
|
165
|
+
#endif
|
166
|
+
|
167
|
+
unique_lock(BOOST_THREAD_RV_REF(unique_lock) other) BOOST_NOEXCEPT:
|
168
|
+
m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
|
169
|
+
{
|
170
|
+
BOOST_THREAD_RV(other).is_locked=false;
|
171
|
+
BOOST_THREAD_RV(other).m=0;
|
172
|
+
}
|
173
|
+
|
174
|
+
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other);
|
175
|
+
|
176
|
+
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
|
177
|
+
//std-2104 unique_lock move-assignment should not be noexcept
|
178
|
+
unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
|
179
|
+
{
|
180
|
+
unique_lock temp(::boost::move(other));
|
181
|
+
swap(temp);
|
182
|
+
return *this;
|
183
|
+
}
|
184
|
+
#endif
|
185
|
+
|
186
|
+
//std-2104 unique_lock move-assignment should not be noexcept
|
187
|
+
unique_lock& operator=(BOOST_THREAD_RV_REF(unique_lock) other) //BOOST_NOEXCEPT
|
188
|
+
{
|
189
|
+
unique_lock temp(::boost::move(other));
|
190
|
+
swap(temp);
|
191
|
+
return *this;
|
192
|
+
}
|
193
|
+
#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
|
194
|
+
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
|
195
|
+
unique_lock& operator=(unique_lock<Mutex> other)
|
196
|
+
{
|
197
|
+
swap(other);
|
198
|
+
return *this;
|
199
|
+
}
|
200
|
+
#endif // BOOST_WORKAROUND
|
201
|
+
#endif
|
202
|
+
|
203
|
+
// Conversion from upgrade locking
|
204
|
+
unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, try_to_lock_t)
|
205
|
+
: m(0),is_locked(false)
|
206
|
+
{
|
207
|
+
if (BOOST_THREAD_RV(ul).owns_lock())
|
208
|
+
{
|
209
|
+
if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock())
|
210
|
+
{
|
211
|
+
m = BOOST_THREAD_RV(ul).release();
|
212
|
+
is_locked = true;
|
213
|
+
}
|
214
|
+
}
|
215
|
+
else
|
216
|
+
{
|
217
|
+
m = BOOST_THREAD_RV(ul).release();
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
221
|
+
#ifdef BOOST_THREAD_USES_CHRONO
|
222
|
+
template <class Clock, class Duration>
|
223
|
+
unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,
|
224
|
+
const chrono::time_point<Clock, Duration>& abs_time)
|
225
|
+
: m(0),is_locked(false)
|
226
|
+
{
|
227
|
+
if (BOOST_THREAD_RV(ul).owns_lock())
|
228
|
+
{
|
229
|
+
if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_until(abs_time))
|
230
|
+
{
|
231
|
+
m = BOOST_THREAD_RV(ul).release();
|
232
|
+
is_locked = true;
|
233
|
+
}
|
234
|
+
}
|
235
|
+
else
|
236
|
+
{
|
237
|
+
m = BOOST_THREAD_RV(ul).release();
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
template <class Rep, class Period>
|
242
|
+
unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul,
|
243
|
+
const chrono::duration<Rep, Period>& rel_time)
|
244
|
+
: m(0),is_locked(false)
|
245
|
+
{
|
246
|
+
if (BOOST_THREAD_RV(ul).owns_lock())
|
247
|
+
{
|
248
|
+
if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_for(rel_time))
|
249
|
+
{
|
250
|
+
m = BOOST_THREAD_RV(ul).release();
|
251
|
+
is_locked = true;
|
252
|
+
}
|
253
|
+
}
|
254
|
+
else
|
255
|
+
{
|
256
|
+
m = BOOST_THREAD_RV(ul).release();
|
257
|
+
}
|
258
|
+
}
|
259
|
+
#endif
|
260
|
+
|
261
|
+
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
262
|
+
// Conversion from shared locking
|
263
|
+
unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t)
|
264
|
+
: m(0),is_locked(false)
|
265
|
+
{
|
266
|
+
if (BOOST_THREAD_RV(sl).owns_lock())
|
267
|
+
{
|
268
|
+
if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock())
|
269
|
+
{
|
270
|
+
m = BOOST_THREAD_RV(sl).release();
|
271
|
+
is_locked = true;
|
272
|
+
}
|
273
|
+
}
|
274
|
+
else
|
275
|
+
{
|
276
|
+
m = BOOST_THREAD_RV(sl).release();
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
#ifdef BOOST_THREAD_USES_CHRONO
|
281
|
+
template <class Clock, class Duration>
|
282
|
+
unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
|
283
|
+
const chrono::time_point<Clock, Duration>& abs_time)
|
284
|
+
: m(0),is_locked(false)
|
285
|
+
{
|
286
|
+
if (BOOST_THREAD_RV(sl).owns_lock())
|
287
|
+
{
|
288
|
+
if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_until(abs_time))
|
289
|
+
{
|
290
|
+
m = BOOST_THREAD_RV(sl).release();
|
291
|
+
is_locked = true;
|
292
|
+
}
|
293
|
+
}
|
294
|
+
else
|
295
|
+
{
|
296
|
+
m = BOOST_THREAD_RV(sl).release();
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
300
|
+
template <class Rep, class Period>
|
301
|
+
unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
|
302
|
+
const chrono::duration<Rep, Period>& rel_time)
|
303
|
+
: m(0),is_locked(false)
|
304
|
+
{
|
305
|
+
if (BOOST_THREAD_RV(sl).owns_lock())
|
306
|
+
{
|
307
|
+
if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_for(rel_time))
|
308
|
+
{
|
309
|
+
m = BOOST_THREAD_RV(sl).release();
|
310
|
+
is_locked = true;
|
311
|
+
}
|
312
|
+
}
|
313
|
+
else
|
314
|
+
{
|
315
|
+
m = BOOST_THREAD_RV(sl).release();
|
316
|
+
}
|
317
|
+
}
|
318
|
+
#endif // BOOST_THREAD_USES_CHRONO
|
319
|
+
#endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
320
|
+
|
321
|
+
void swap(unique_lock& other)BOOST_NOEXCEPT
|
322
|
+
{
|
323
|
+
std::swap(m,other.m);
|
324
|
+
std::swap(is_locked,other.is_locked);
|
325
|
+
}
|
326
|
+
|
327
|
+
~unique_lock()
|
328
|
+
{
|
329
|
+
if (owns_lock())
|
330
|
+
{
|
331
|
+
m->unlock();
|
332
|
+
}
|
333
|
+
}
|
334
|
+
void lock()
|
335
|
+
{
|
336
|
+
if (m == 0)
|
337
|
+
{
|
338
|
+
boost::throw_exception(
|
339
|
+
boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
|
340
|
+
}
|
341
|
+
if (owns_lock())
|
342
|
+
{
|
343
|
+
boost::throw_exception(
|
344
|
+
boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
|
345
|
+
}
|
346
|
+
m->lock();
|
347
|
+
is_locked = true;
|
348
|
+
}
|
349
|
+
bool try_lock()
|
350
|
+
{
|
351
|
+
if (m == 0)
|
352
|
+
{
|
353
|
+
boost::throw_exception(
|
354
|
+
boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
|
355
|
+
}
|
356
|
+
if (owns_lock())
|
357
|
+
{
|
358
|
+
boost::throw_exception(
|
359
|
+
boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
|
360
|
+
}
|
361
|
+
is_locked = m->try_lock();
|
362
|
+
return is_locked;
|
363
|
+
}
|
364
|
+
#if defined BOOST_THREAD_USES_DATETIME
|
365
|
+
template<typename TimeDuration>
|
366
|
+
bool timed_lock(TimeDuration const& relative_time)
|
367
|
+
{
|
368
|
+
if(m==0)
|
369
|
+
{
|
370
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
|
371
|
+
}
|
372
|
+
if(owns_lock())
|
373
|
+
{
|
374
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
|
375
|
+
}
|
376
|
+
is_locked=m->timed_lock(relative_time);
|
377
|
+
return is_locked;
|
378
|
+
}
|
379
|
+
|
380
|
+
bool timed_lock(::boost::system_time const& absolute_time)
|
381
|
+
{
|
382
|
+
if(m==0)
|
383
|
+
{
|
384
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
|
385
|
+
}
|
386
|
+
if(owns_lock())
|
387
|
+
{
|
388
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
|
389
|
+
}
|
390
|
+
is_locked=m->timed_lock(absolute_time);
|
391
|
+
return is_locked;
|
392
|
+
}
|
393
|
+
bool timed_lock(::boost::xtime const& absolute_time)
|
394
|
+
{
|
395
|
+
if(m==0)
|
396
|
+
{
|
397
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
|
398
|
+
}
|
399
|
+
if(owns_lock())
|
400
|
+
{
|
401
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
|
402
|
+
}
|
403
|
+
is_locked=m->timed_lock(absolute_time);
|
404
|
+
return is_locked;
|
405
|
+
}
|
406
|
+
#endif
|
407
|
+
#ifdef BOOST_THREAD_USES_CHRONO
|
408
|
+
|
409
|
+
template <class Rep, class Period>
|
410
|
+
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
|
411
|
+
{
|
412
|
+
if(m==0)
|
413
|
+
{
|
414
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
|
415
|
+
}
|
416
|
+
if(owns_lock())
|
417
|
+
{
|
418
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
|
419
|
+
}
|
420
|
+
is_locked=m->try_lock_for(rel_time);
|
421
|
+
return is_locked;
|
422
|
+
}
|
423
|
+
template <class Clock, class Duration>
|
424
|
+
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
|
425
|
+
{
|
426
|
+
if(m==0)
|
427
|
+
{
|
428
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
|
429
|
+
}
|
430
|
+
if(owns_lock())
|
431
|
+
{
|
432
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));
|
433
|
+
}
|
434
|
+
is_locked=m->try_lock_until(abs_time);
|
435
|
+
return is_locked;
|
436
|
+
}
|
437
|
+
#endif
|
438
|
+
|
439
|
+
void unlock()
|
440
|
+
{
|
441
|
+
if (m == 0)
|
442
|
+
{
|
443
|
+
boost::throw_exception(
|
444
|
+
boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex"));
|
445
|
+
}
|
446
|
+
if (!owns_lock())
|
447
|
+
{
|
448
|
+
boost::throw_exception(
|
449
|
+
boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock doesn't own the mutex"));
|
450
|
+
}
|
451
|
+
m->unlock();
|
452
|
+
is_locked = false;
|
453
|
+
}
|
454
|
+
|
455
|
+
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
456
|
+
typedef void (unique_lock::*bool_type)();
|
457
|
+
operator bool_type() const BOOST_NOEXCEPT
|
458
|
+
{
|
459
|
+
return is_locked?&unique_lock::lock:0;
|
460
|
+
}
|
461
|
+
bool operator!() const BOOST_NOEXCEPT
|
462
|
+
{
|
463
|
+
return !owns_lock();
|
464
|
+
}
|
465
|
+
#else
|
466
|
+
explicit operator bool() const BOOST_NOEXCEPT
|
467
|
+
{
|
468
|
+
return owns_lock();
|
469
|
+
}
|
470
|
+
#endif
|
471
|
+
bool owns_lock() const BOOST_NOEXCEPT
|
472
|
+
{
|
473
|
+
return is_locked;
|
474
|
+
}
|
475
|
+
|
476
|
+
Mutex* mutex() const BOOST_NOEXCEPT
|
477
|
+
{
|
478
|
+
return m;
|
479
|
+
}
|
480
|
+
|
481
|
+
Mutex* release()BOOST_NOEXCEPT
|
482
|
+
{
|
483
|
+
Mutex* const res=m;
|
484
|
+
m=0;
|
485
|
+
is_locked=false;
|
486
|
+
return res;
|
487
|
+
}
|
488
|
+
|
489
|
+
friend class shared_lock<Mutex> ;
|
490
|
+
friend class upgrade_lock<Mutex> ;
|
491
|
+
};
|
492
|
+
|
493
|
+
template<typename Mutex>
|
494
|
+
void swap(unique_lock<Mutex>& lhs, unique_lock<Mutex>& rhs)
|
495
|
+
BOOST_NOEXCEPT
|
496
|
+
{
|
497
|
+
lhs.swap(rhs);
|
498
|
+
}
|
499
|
+
|
500
|
+
BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
|
501
|
+
|
502
|
+
template<typename Mutex>
|
503
|
+
class shared_lock
|
504
|
+
{
|
505
|
+
protected:
|
506
|
+
Mutex* m;
|
507
|
+
bool is_locked;
|
508
|
+
|
509
|
+
public:
|
510
|
+
typedef Mutex mutex_type;
|
511
|
+
BOOST_THREAD_MOVABLE_ONLY(shared_lock)
|
512
|
+
|
513
|
+
shared_lock() BOOST_NOEXCEPT:
|
514
|
+
m(0),is_locked(false)
|
515
|
+
{}
|
516
|
+
|
517
|
+
explicit shared_lock(Mutex& m_):
|
518
|
+
m(&m_),is_locked(false)
|
519
|
+
{
|
520
|
+
lock();
|
521
|
+
}
|
522
|
+
shared_lock(Mutex& m_,adopt_lock_t):
|
523
|
+
m(&m_),is_locked(true)
|
524
|
+
{
|
525
|
+
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
|
526
|
+
BOOST_ASSERT(is_locked_by_this_thread(m));
|
527
|
+
#endif
|
528
|
+
}
|
529
|
+
shared_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:
|
530
|
+
m(&m_),is_locked(false)
|
531
|
+
{}
|
532
|
+
shared_lock(Mutex& m_,try_to_lock_t):
|
533
|
+
m(&m_),is_locked(false)
|
534
|
+
{
|
535
|
+
try_lock();
|
536
|
+
}
|
537
|
+
#if defined BOOST_THREAD_USES_DATETIME
|
538
|
+
shared_lock(Mutex& m_,system_time const& target_time):
|
539
|
+
m(&m_),is_locked(false)
|
540
|
+
{
|
541
|
+
timed_lock(target_time);
|
542
|
+
}
|
543
|
+
#endif
|
544
|
+
#ifdef BOOST_THREAD_USES_CHRONO
|
545
|
+
template <class Clock, class Duration>
|
546
|
+
shared_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
|
547
|
+
: m(&mtx), is_locked(mtx.try_lock_shared_until(t))
|
548
|
+
{
|
549
|
+
}
|
550
|
+
template <class Rep, class Period>
|
551
|
+
shared_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
|
552
|
+
: m(&mtx), is_locked(mtx.try_lock_shared_for(d))
|
553
|
+
{
|
554
|
+
}
|
555
|
+
#endif
|
556
|
+
|
557
|
+
shared_lock(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
|
558
|
+
m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
|
559
|
+
{
|
560
|
+
BOOST_THREAD_RV(other).is_locked=false;
|
561
|
+
BOOST_THREAD_RV(other).m=0;
|
562
|
+
}
|
563
|
+
|
564
|
+
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other):
|
565
|
+
m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
|
566
|
+
{
|
567
|
+
if(is_locked)
|
568
|
+
{
|
569
|
+
m->unlock_and_lock_shared();
|
570
|
+
}
|
571
|
+
BOOST_THREAD_RV(other).is_locked=false;
|
572
|
+
BOOST_THREAD_RV(other).m=0;
|
573
|
+
}
|
574
|
+
|
575
|
+
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other):
|
576
|
+
m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
|
577
|
+
{
|
578
|
+
if(is_locked)
|
579
|
+
{
|
580
|
+
m->unlock_upgrade_and_lock_shared();
|
581
|
+
}
|
582
|
+
BOOST_THREAD_RV(other).is_locked=false;
|
583
|
+
BOOST_THREAD_RV(other).m=0;
|
584
|
+
}
|
585
|
+
|
586
|
+
//std-2104 unique_lock move-assignment should not be noexcept
|
587
|
+
shared_lock& operator=(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
|
588
|
+
{
|
589
|
+
shared_lock temp(::boost::move(other));
|
590
|
+
swap(temp);
|
591
|
+
return *this;
|
592
|
+
}
|
593
|
+
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
|
594
|
+
shared_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)
|
595
|
+
{
|
596
|
+
shared_lock temp(::boost::move(other));
|
597
|
+
swap(temp);
|
598
|
+
return *this;
|
599
|
+
}
|
600
|
+
|
601
|
+
shared_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)
|
602
|
+
{
|
603
|
+
shared_lock temp(::boost::move(other));
|
604
|
+
swap(temp);
|
605
|
+
return *this;
|
606
|
+
}
|
607
|
+
#endif
|
608
|
+
|
609
|
+
void swap(shared_lock& other) BOOST_NOEXCEPT
|
610
|
+
{
|
611
|
+
std::swap(m,other.m);
|
612
|
+
std::swap(is_locked,other.is_locked);
|
613
|
+
}
|
614
|
+
|
615
|
+
Mutex* mutex() const BOOST_NOEXCEPT
|
616
|
+
{
|
617
|
+
return m;
|
618
|
+
}
|
619
|
+
|
620
|
+
Mutex* release() BOOST_NOEXCEPT
|
621
|
+
{
|
622
|
+
Mutex* const res=m;
|
623
|
+
m=0;
|
624
|
+
is_locked=false;
|
625
|
+
return res;
|
626
|
+
}
|
627
|
+
|
628
|
+
~shared_lock()
|
629
|
+
{
|
630
|
+
if(owns_lock())
|
631
|
+
{
|
632
|
+
m->unlock_shared();
|
633
|
+
}
|
634
|
+
}
|
635
|
+
void lock()
|
636
|
+
{
|
637
|
+
if(m==0)
|
638
|
+
{
|
639
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
|
640
|
+
}
|
641
|
+
if(owns_lock())
|
642
|
+
{
|
643
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
|
644
|
+
}
|
645
|
+
m->lock_shared();
|
646
|
+
is_locked=true;
|
647
|
+
}
|
648
|
+
bool try_lock()
|
649
|
+
{
|
650
|
+
if(m==0)
|
651
|
+
{
|
652
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
|
653
|
+
}
|
654
|
+
if(owns_lock())
|
655
|
+
{
|
656
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
|
657
|
+
}
|
658
|
+
is_locked=m->try_lock_shared();
|
659
|
+
return is_locked;
|
660
|
+
}
|
661
|
+
#if defined BOOST_THREAD_USES_DATETIME
|
662
|
+
bool timed_lock(boost::system_time const& target_time)
|
663
|
+
{
|
664
|
+
if(m==0)
|
665
|
+
{
|
666
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
|
667
|
+
}
|
668
|
+
if(owns_lock())
|
669
|
+
{
|
670
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
|
671
|
+
}
|
672
|
+
is_locked=m->timed_lock_shared(target_time);
|
673
|
+
return is_locked;
|
674
|
+
}
|
675
|
+
template<typename Duration>
|
676
|
+
bool timed_lock(Duration const& target_time)
|
677
|
+
{
|
678
|
+
if(m==0)
|
679
|
+
{
|
680
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
|
681
|
+
}
|
682
|
+
if(owns_lock())
|
683
|
+
{
|
684
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
|
685
|
+
}
|
686
|
+
is_locked=m->timed_lock_shared(target_time);
|
687
|
+
return is_locked;
|
688
|
+
}
|
689
|
+
#endif
|
690
|
+
#ifdef BOOST_THREAD_USES_CHRONO
|
691
|
+
template <class Rep, class Period>
|
692
|
+
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
|
693
|
+
{
|
694
|
+
if(m==0)
|
695
|
+
{
|
696
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
|
697
|
+
}
|
698
|
+
if(owns_lock())
|
699
|
+
{
|
700
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
|
701
|
+
}
|
702
|
+
is_locked=m->try_lock_shared_for(rel_time);
|
703
|
+
return is_locked;
|
704
|
+
}
|
705
|
+
template <class Clock, class Duration>
|
706
|
+
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
|
707
|
+
{
|
708
|
+
if(m==0)
|
709
|
+
{
|
710
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
|
711
|
+
}
|
712
|
+
if(owns_lock())
|
713
|
+
{
|
714
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
|
715
|
+
}
|
716
|
+
is_locked=m->try_lock_shared_until(abs_time);
|
717
|
+
return is_locked;
|
718
|
+
}
|
719
|
+
#endif
|
720
|
+
void unlock()
|
721
|
+
{
|
722
|
+
if(m==0)
|
723
|
+
{
|
724
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
|
725
|
+
}
|
726
|
+
if(!owns_lock())
|
727
|
+
{
|
728
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock doesn't own the mutex"));
|
729
|
+
}
|
730
|
+
m->unlock_shared();
|
731
|
+
is_locked=false;
|
732
|
+
}
|
733
|
+
|
734
|
+
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
735
|
+
typedef void (shared_lock<Mutex>::*bool_type)();
|
736
|
+
operator bool_type() const BOOST_NOEXCEPT
|
737
|
+
{
|
738
|
+
return is_locked?&shared_lock::lock:0;
|
739
|
+
}
|
740
|
+
bool operator!() const BOOST_NOEXCEPT
|
741
|
+
{
|
742
|
+
return !owns_lock();
|
743
|
+
}
|
744
|
+
#else
|
745
|
+
explicit operator bool() const BOOST_NOEXCEPT
|
746
|
+
{
|
747
|
+
return owns_lock();
|
748
|
+
}
|
749
|
+
#endif
|
750
|
+
bool owns_lock() const BOOST_NOEXCEPT
|
751
|
+
{
|
752
|
+
return is_locked;
|
753
|
+
}
|
754
|
+
|
755
|
+
};
|
756
|
+
|
757
|
+
BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) shared_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
|
758
|
+
|
759
|
+
template<typename Mutex>
|
760
|
+
void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) BOOST_NOEXCEPT
|
761
|
+
{
|
762
|
+
lhs.swap(rhs);
|
763
|
+
}
|
764
|
+
|
765
|
+
template <typename Mutex>
|
766
|
+
class upgrade_lock
|
767
|
+
{
|
768
|
+
protected:
|
769
|
+
Mutex* m;
|
770
|
+
bool is_locked;
|
771
|
+
|
772
|
+
public:
|
773
|
+
typedef Mutex mutex_type;
|
774
|
+
BOOST_THREAD_MOVABLE_ONLY( upgrade_lock)
|
775
|
+
|
776
|
+
upgrade_lock()BOOST_NOEXCEPT:
|
777
|
+
m(0),is_locked(false)
|
778
|
+
{}
|
779
|
+
|
780
|
+
explicit upgrade_lock(Mutex& m_) :
|
781
|
+
m(&m_), is_locked(false)
|
782
|
+
{
|
783
|
+
lock();
|
784
|
+
}
|
785
|
+
upgrade_lock(Mutex& m_, adopt_lock_t) :
|
786
|
+
m(&m_), is_locked(true)
|
787
|
+
{
|
788
|
+
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
|
789
|
+
BOOST_ASSERT(is_locked_by_this_thread(m));
|
790
|
+
#endif
|
791
|
+
}
|
792
|
+
upgrade_lock(Mutex& m_, defer_lock_t)BOOST_NOEXCEPT:
|
793
|
+
m(&m_),is_locked(false)
|
794
|
+
{}
|
795
|
+
upgrade_lock(Mutex& m_, try_to_lock_t) :
|
796
|
+
m(&m_), is_locked(false)
|
797
|
+
{
|
798
|
+
try_lock();
|
799
|
+
}
|
800
|
+
|
801
|
+
#ifdef BOOST_THREAD_USES_CHRONO
|
802
|
+
template <class Clock, class Duration>
|
803
|
+
upgrade_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t)
|
804
|
+
: m(&mtx), is_locked(mtx.try_lock_upgrade_until(t))
|
805
|
+
{
|
806
|
+
}
|
807
|
+
template <class Rep, class Period>
|
808
|
+
upgrade_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d)
|
809
|
+
: m(&mtx), is_locked(mtx.try_lock_upgrade_for(d))
|
810
|
+
{
|
811
|
+
}
|
812
|
+
#endif
|
813
|
+
|
814
|
+
upgrade_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
|
815
|
+
m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
|
816
|
+
{
|
817
|
+
BOOST_THREAD_RV(other).is_locked=false;
|
818
|
+
BOOST_THREAD_RV(other).m=0;
|
819
|
+
}
|
820
|
+
|
821
|
+
BOOST_THREAD_EXPLICIT_LOCK_CONVERSION upgrade_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other):
|
822
|
+
m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
|
823
|
+
{
|
824
|
+
if(is_locked)
|
825
|
+
{
|
826
|
+
m->unlock_and_lock_upgrade();
|
827
|
+
}
|
828
|
+
BOOST_THREAD_RV(other).is_locked=false;
|
829
|
+
BOOST_THREAD_RV(other).m=0;
|
830
|
+
}
|
831
|
+
|
832
|
+
//std-2104 unique_lock move-assignment should not be noexcept
|
833
|
+
upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
|
834
|
+
{
|
835
|
+
upgrade_lock temp(::boost::move(other));
|
836
|
+
swap(temp);
|
837
|
+
return *this;
|
838
|
+
}
|
839
|
+
|
840
|
+
#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
|
841
|
+
upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)
|
842
|
+
{
|
843
|
+
upgrade_lock temp(::boost::move(other));
|
844
|
+
swap(temp);
|
845
|
+
return *this;
|
846
|
+
}
|
847
|
+
#endif
|
848
|
+
|
849
|
+
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
850
|
+
// Conversion from shared locking
|
851
|
+
upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t)
|
852
|
+
: m(0),is_locked(false)
|
853
|
+
{
|
854
|
+
if (BOOST_THREAD_RV(sl).owns_lock())
|
855
|
+
{
|
856
|
+
if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade())
|
857
|
+
{
|
858
|
+
m = BOOST_THREAD_RV(sl).release();
|
859
|
+
is_locked = true;
|
860
|
+
}
|
861
|
+
}
|
862
|
+
else
|
863
|
+
{
|
864
|
+
m = BOOST_THREAD_RV(sl).release();
|
865
|
+
}
|
866
|
+
}
|
867
|
+
|
868
|
+
#ifdef BOOST_THREAD_USES_CHRONO
|
869
|
+
template <class Clock, class Duration>
|
870
|
+
upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
|
871
|
+
const chrono::time_point<Clock, Duration>& abs_time)
|
872
|
+
: m(0),is_locked(false)
|
873
|
+
{
|
874
|
+
if (BOOST_THREAD_RV(sl).owns_lock())
|
875
|
+
{
|
876
|
+
if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
|
877
|
+
{
|
878
|
+
m = BOOST_THREAD_RV(sl).release();
|
879
|
+
is_locked = true;
|
880
|
+
}
|
881
|
+
}
|
882
|
+
else
|
883
|
+
{
|
884
|
+
m = BOOST_THREAD_RV(sl).release();
|
885
|
+
}
|
886
|
+
}
|
887
|
+
|
888
|
+
template <class Rep, class Period>
|
889
|
+
upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl,
|
890
|
+
const chrono::duration<Rep, Period>& rel_time)
|
891
|
+
: m(0),is_locked(false)
|
892
|
+
{
|
893
|
+
if (BOOST_THREAD_RV(sl).owns_lock())
|
894
|
+
{
|
895
|
+
if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
|
896
|
+
{
|
897
|
+
m = BOOST_THREAD_RV(sl).release();
|
898
|
+
is_locked = true;
|
899
|
+
}
|
900
|
+
}
|
901
|
+
else
|
902
|
+
{
|
903
|
+
m = BOOST_THREAD_RV(sl).release();
|
904
|
+
}
|
905
|
+
}
|
906
|
+
#endif // BOOST_THREAD_USES_CHRONO
|
907
|
+
#endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
908
|
+
void swap(upgrade_lock& other)BOOST_NOEXCEPT
|
909
|
+
{
|
910
|
+
std::swap(m,other.m);
|
911
|
+
std::swap(is_locked,other.is_locked);
|
912
|
+
}
|
913
|
+
Mutex* mutex() const BOOST_NOEXCEPT
|
914
|
+
{
|
915
|
+
return m;
|
916
|
+
}
|
917
|
+
|
918
|
+
Mutex* release()BOOST_NOEXCEPT
|
919
|
+
{
|
920
|
+
Mutex* const res=m;
|
921
|
+
m=0;
|
922
|
+
is_locked=false;
|
923
|
+
return res;
|
924
|
+
}
|
925
|
+
~upgrade_lock()
|
926
|
+
{
|
927
|
+
if (owns_lock())
|
928
|
+
{
|
929
|
+
m->unlock_upgrade();
|
930
|
+
}
|
931
|
+
}
|
932
|
+
void lock()
|
933
|
+
{
|
934
|
+
if (m == 0)
|
935
|
+
{
|
936
|
+
boost::throw_exception(
|
937
|
+
boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
|
938
|
+
}
|
939
|
+
if (owns_lock())
|
940
|
+
{
|
941
|
+
boost::throw_exception(
|
942
|
+
boost::lock_error(system::errc::resource_deadlock_would_occur, "boost upgrade_lock owns already the mutex"));
|
943
|
+
}
|
944
|
+
m->lock_upgrade();
|
945
|
+
is_locked = true;
|
946
|
+
}
|
947
|
+
bool try_lock()
|
948
|
+
{
|
949
|
+
if (m == 0)
|
950
|
+
{
|
951
|
+
boost::throw_exception(
|
952
|
+
boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
|
953
|
+
}
|
954
|
+
if (owns_lock())
|
955
|
+
{
|
956
|
+
boost::throw_exception(
|
957
|
+
boost::lock_error(system::errc::resource_deadlock_would_occur, "boost upgrade_lock owns already the mutex"));
|
958
|
+
}
|
959
|
+
is_locked = m->try_lock_upgrade();
|
960
|
+
return is_locked;
|
961
|
+
}
|
962
|
+
void unlock()
|
963
|
+
{
|
964
|
+
if (m == 0)
|
965
|
+
{
|
966
|
+
boost::throw_exception(
|
967
|
+
boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
|
968
|
+
}
|
969
|
+
if (!owns_lock())
|
970
|
+
{
|
971
|
+
boost::throw_exception(
|
972
|
+
boost::lock_error(system::errc::operation_not_permitted, "boost upgrade_lock doesn't own the mutex"));
|
973
|
+
}
|
974
|
+
m->unlock_upgrade();
|
975
|
+
is_locked = false;
|
976
|
+
}
|
977
|
+
#ifdef BOOST_THREAD_USES_CHRONO
|
978
|
+
template <class Rep, class Period>
|
979
|
+
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
|
980
|
+
{
|
981
|
+
if(m==0)
|
982
|
+
{
|
983
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
|
984
|
+
}
|
985
|
+
if(owns_lock())
|
986
|
+
{
|
987
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
|
988
|
+
}
|
989
|
+
is_locked=m->try_lock_upgrade_for(rel_time);
|
990
|
+
return is_locked;
|
991
|
+
}
|
992
|
+
template <class Clock, class Duration>
|
993
|
+
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
|
994
|
+
{
|
995
|
+
if(m==0)
|
996
|
+
{
|
997
|
+
boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex"));
|
998
|
+
}
|
999
|
+
if(owns_lock())
|
1000
|
+
{
|
1001
|
+
boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));
|
1002
|
+
}
|
1003
|
+
is_locked=m->try_lock_upgrade_until(abs_time);
|
1004
|
+
return is_locked;
|
1005
|
+
}
|
1006
|
+
#endif
|
1007
|
+
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
1008
|
+
typedef void (upgrade_lock::*bool_type)();
|
1009
|
+
operator bool_type() const BOOST_NOEXCEPT
|
1010
|
+
{
|
1011
|
+
return is_locked?&upgrade_lock::lock:0;
|
1012
|
+
}
|
1013
|
+
bool operator!() const BOOST_NOEXCEPT
|
1014
|
+
{
|
1015
|
+
return !owns_lock();
|
1016
|
+
}
|
1017
|
+
#else
|
1018
|
+
explicit operator bool() const BOOST_NOEXCEPT
|
1019
|
+
{
|
1020
|
+
return owns_lock();
|
1021
|
+
}
|
1022
|
+
#endif
|
1023
|
+
bool owns_lock() const BOOST_NOEXCEPT
|
1024
|
+
{
|
1025
|
+
return is_locked;
|
1026
|
+
}
|
1027
|
+
friend class shared_lock<Mutex> ;
|
1028
|
+
friend class unique_lock<Mutex> ;
|
1029
|
+
};
|
1030
|
+
|
1031
|
+
template<typename Mutex>
|
1032
|
+
void swap(upgrade_lock<Mutex>& lhs, upgrade_lock<Mutex>& rhs)
|
1033
|
+
BOOST_NOEXCEPT
|
1034
|
+
{
|
1035
|
+
lhs.swap(rhs);
|
1036
|
+
}
|
1037
|
+
|
1038
|
+
BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
|
1039
|
+
|
1040
|
+
template<typename Mutex>
|
1041
|
+
unique_lock<Mutex>::unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other):
|
1042
|
+
m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)
|
1043
|
+
{
|
1044
|
+
if(is_locked)
|
1045
|
+
{
|
1046
|
+
m->unlock_upgrade_and_lock();
|
1047
|
+
}
|
1048
|
+
BOOST_THREAD_RV(other).release();
|
1049
|
+
}
|
1050
|
+
|
1051
|
+
template <class Mutex>
|
1052
|
+
class upgrade_to_unique_lock
|
1053
|
+
{
|
1054
|
+
private:
|
1055
|
+
upgrade_lock<Mutex>* source;
|
1056
|
+
unique_lock<Mutex> exclusive;
|
1057
|
+
|
1058
|
+
public:
|
1059
|
+
typedef Mutex mutex_type;
|
1060
|
+
BOOST_THREAD_MOVABLE_ONLY( upgrade_to_unique_lock)
|
1061
|
+
|
1062
|
+
explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_) :
|
1063
|
+
source(&m_), exclusive(::boost::move(*source))
|
1064
|
+
{
|
1065
|
+
}
|
1066
|
+
~upgrade_to_unique_lock()
|
1067
|
+
{
|
1068
|
+
if (source)
|
1069
|
+
{
|
1070
|
+
*source = BOOST_THREAD_MAKE_RV_REF(upgrade_lock<Mutex> (::boost::move(exclusive)));
|
1071
|
+
}
|
1072
|
+
}
|
1073
|
+
|
1074
|
+
upgrade_to_unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT:
|
1075
|
+
source(BOOST_THREAD_RV(other).source),exclusive(::boost::move(BOOST_THREAD_RV(other).exclusive))
|
1076
|
+
{
|
1077
|
+
BOOST_THREAD_RV(other).source=0;
|
1078
|
+
}
|
1079
|
+
|
1080
|
+
//std-2104 unique_lock move-assignment should not be noexcept
|
1081
|
+
upgrade_to_unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
|
1082
|
+
{
|
1083
|
+
upgrade_to_unique_lock temp(other);
|
1084
|
+
swap(temp);
|
1085
|
+
return *this;
|
1086
|
+
}
|
1087
|
+
|
1088
|
+
void swap(upgrade_to_unique_lock& other)BOOST_NOEXCEPT
|
1089
|
+
{
|
1090
|
+
std::swap(source,other.source);
|
1091
|
+
exclusive.swap(other.exclusive);
|
1092
|
+
}
|
1093
|
+
|
1094
|
+
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
1095
|
+
typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&);
|
1096
|
+
operator bool_type() const BOOST_NOEXCEPT
|
1097
|
+
{
|
1098
|
+
return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0;
|
1099
|
+
}
|
1100
|
+
bool operator!() const BOOST_NOEXCEPT
|
1101
|
+
{
|
1102
|
+
return !owns_lock();
|
1103
|
+
}
|
1104
|
+
#else
|
1105
|
+
explicit operator bool() const BOOST_NOEXCEPT
|
1106
|
+
{
|
1107
|
+
return owns_lock();
|
1108
|
+
}
|
1109
|
+
#endif
|
1110
|
+
|
1111
|
+
bool owns_lock() const BOOST_NOEXCEPT
|
1112
|
+
{
|
1113
|
+
return exclusive.owns_lock();
|
1114
|
+
}
|
1115
|
+
};
|
1116
|
+
|
1117
|
+
BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
|
1118
|
+
|
1119
|
+
namespace detail
|
1120
|
+
{
|
1121
|
+
template<typename Mutex>
|
1122
|
+
class try_lock_wrapper:
|
1123
|
+
private unique_lock<Mutex>
|
1124
|
+
{
|
1125
|
+
typedef unique_lock<Mutex> base;
|
1126
|
+
public:
|
1127
|
+
BOOST_THREAD_MOVABLE_ONLY(try_lock_wrapper)
|
1128
|
+
|
1129
|
+
try_lock_wrapper()
|
1130
|
+
{}
|
1131
|
+
|
1132
|
+
explicit try_lock_wrapper(Mutex& m):
|
1133
|
+
base(m,try_to_lock)
|
1134
|
+
{}
|
1135
|
+
|
1136
|
+
try_lock_wrapper(Mutex& m_,adopt_lock_t):
|
1137
|
+
base(m_,adopt_lock)
|
1138
|
+
{
|
1139
|
+
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
|
1140
|
+
BOOST_ASSERT(is_locked_by_this_thread(m_));
|
1141
|
+
#endif
|
1142
|
+
}
|
1143
|
+
try_lock_wrapper(Mutex& m_,defer_lock_t):
|
1144
|
+
base(m_,defer_lock)
|
1145
|
+
{}
|
1146
|
+
try_lock_wrapper(Mutex& m_,try_to_lock_t):
|
1147
|
+
base(m_,try_to_lock)
|
1148
|
+
{}
|
1149
|
+
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
1150
|
+
try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
|
1151
|
+
base(::boost::move(other))
|
1152
|
+
{}
|
1153
|
+
|
1154
|
+
#elif defined BOOST_THREAD_USES_MOVE
|
1155
|
+
try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
|
1156
|
+
base(::boost::move(static_cast<base&>(other)))
|
1157
|
+
{}
|
1158
|
+
|
1159
|
+
#else
|
1160
|
+
try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
|
1161
|
+
base(BOOST_THREAD_RV_REF(base)(*other))
|
1162
|
+
{}
|
1163
|
+
#endif
|
1164
|
+
try_lock_wrapper& operator=(BOOST_THREAD_RV_REF_BEG try_lock_wrapper<Mutex> BOOST_THREAD_RV_REF_END other)
|
1165
|
+
{
|
1166
|
+
try_lock_wrapper temp(other);
|
1167
|
+
swap(temp);
|
1168
|
+
return *this;
|
1169
|
+
}
|
1170
|
+
void swap(try_lock_wrapper& other)
|
1171
|
+
{
|
1172
|
+
base::swap(other);
|
1173
|
+
}
|
1174
|
+
void lock()
|
1175
|
+
{
|
1176
|
+
base::lock();
|
1177
|
+
}
|
1178
|
+
bool try_lock()
|
1179
|
+
{
|
1180
|
+
return base::try_lock();
|
1181
|
+
}
|
1182
|
+
void unlock()
|
1183
|
+
{
|
1184
|
+
base::unlock();
|
1185
|
+
}
|
1186
|
+
bool owns_lock() const
|
1187
|
+
{
|
1188
|
+
return base::owns_lock();
|
1189
|
+
}
|
1190
|
+
Mutex* mutex() const
|
1191
|
+
{
|
1192
|
+
return base::mutex();
|
1193
|
+
}
|
1194
|
+
Mutex* release()
|
1195
|
+
{
|
1196
|
+
return base::release();
|
1197
|
+
}
|
1198
|
+
|
1199
|
+
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
1200
|
+
typedef typename base::bool_type bool_type;
|
1201
|
+
operator bool_type() const
|
1202
|
+
{
|
1203
|
+
return base::operator bool_type();
|
1204
|
+
}
|
1205
|
+
bool operator!() const
|
1206
|
+
{
|
1207
|
+
return !this->owns_lock();
|
1208
|
+
}
|
1209
|
+
#else
|
1210
|
+
explicit operator bool() const
|
1211
|
+
{
|
1212
|
+
return owns_lock();
|
1213
|
+
}
|
1214
|
+
#endif
|
1215
|
+
};
|
1216
|
+
|
1217
|
+
template<typename Mutex>
|
1218
|
+
void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs)
|
1219
|
+
{
|
1220
|
+
lhs.swap(rhs);
|
1221
|
+
}
|
1222
|
+
}
|
1223
|
+
}
|
1224
|
+
#include <boost/config/abi_suffix.hpp>
|
1225
|
+
|
1226
|
+
#endif
|