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,148 @@
|
|
1
|
+
// (C) Copyright 2012 Vicente J. Botet Escriba
|
2
|
+
// Distributed under the Boost Software License, Version 1.0. (See
|
3
|
+
// accompanying file LICENSE_1_0.txt or copy at
|
4
|
+
// http://www.boost.org/LICENSE_1_0.txt)
|
5
|
+
|
6
|
+
|
7
|
+
#ifndef BOOST_THREAD_TESTABLE_LOCKABLE_HPP
|
8
|
+
#define BOOST_THREAD_TESTABLE_LOCKABLE_HPP
|
9
|
+
|
10
|
+
#include <boost/thread/detail/config.hpp>
|
11
|
+
|
12
|
+
#include <boost/thread/thread_only.hpp>
|
13
|
+
|
14
|
+
#include <boost/atomic.hpp>
|
15
|
+
#include <boost/assert.hpp>
|
16
|
+
|
17
|
+
#include <boost/config/abi_prefix.hpp>
|
18
|
+
|
19
|
+
namespace boost
|
20
|
+
{
|
21
|
+
/**
|
22
|
+
* Based on Associate Mutexes with Data to Prevent Races, By Herb Sutter, May 13, 2010
|
23
|
+
* http://www.drdobbs.com/windows/associate-mutexes-with-data-to-prevent-r/224701827?pgno=3
|
24
|
+
*
|
25
|
+
* Make our mutex testable if it isn't already.
|
26
|
+
*
|
27
|
+
* Many mutex services (including boost::mutex) don't provide a way to ask,
|
28
|
+
* "Do I already hold a lock on this mutex?"
|
29
|
+
* Sometimes it is needed to know if a method like is_locked to be available.
|
30
|
+
* This wrapper associates an arbitrary lockable type with a thread id that stores the ID of the thread that
|
31
|
+
* currently holds the lockable. The thread id initially holds an invalid value that means no threads own the mutex.
|
32
|
+
* When we acquire a lock, we set the thread id; and when we release a lock, we reset it back to its default no id state.
|
33
|
+
*
|
34
|
+
*/
|
35
|
+
template <typename Lockable>
|
36
|
+
class testable_mutex
|
37
|
+
{
|
38
|
+
Lockable mtx_;
|
39
|
+
atomic<thread::id> id_;
|
40
|
+
public:
|
41
|
+
/// the type of the wrapped lockable
|
42
|
+
typedef Lockable lockable_type;
|
43
|
+
|
44
|
+
/// Non copyable
|
45
|
+
BOOST_THREAD_NO_COPYABLE(testable_mutex)
|
46
|
+
|
47
|
+
testable_mutex() : id_(thread::id()) {}
|
48
|
+
|
49
|
+
void lock()
|
50
|
+
{
|
51
|
+
mtx_.lock();
|
52
|
+
id_ = this_thread::get_id();
|
53
|
+
}
|
54
|
+
|
55
|
+
void unlock()
|
56
|
+
{
|
57
|
+
BOOST_ASSERT(is_locked_by_this_thread());
|
58
|
+
id_ = thread::id();
|
59
|
+
mtx_.unlock();
|
60
|
+
}
|
61
|
+
|
62
|
+
bool try_lock()
|
63
|
+
{
|
64
|
+
if (mtx_.try_lock())
|
65
|
+
{
|
66
|
+
id_ = this_thread::get_id();
|
67
|
+
return true;
|
68
|
+
}
|
69
|
+
else
|
70
|
+
{
|
71
|
+
return false;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
#ifdef BOOST_THREAD_USES_CHRONO
|
75
|
+
template <class Rep, class Period>
|
76
|
+
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
|
77
|
+
{
|
78
|
+
if (mtx_.try_lock_for(rel_time))
|
79
|
+
{
|
80
|
+
id_ = this_thread::get_id();
|
81
|
+
return true;
|
82
|
+
}
|
83
|
+
else
|
84
|
+
{
|
85
|
+
return false;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
template <class Clock, class Duration>
|
89
|
+
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
|
90
|
+
{
|
91
|
+
if (mtx_.try_lock_until(abs_time))
|
92
|
+
{
|
93
|
+
id_ = this_thread::get_id();
|
94
|
+
return true;
|
95
|
+
}
|
96
|
+
else
|
97
|
+
{
|
98
|
+
return false;
|
99
|
+
}
|
100
|
+
}
|
101
|
+
#endif
|
102
|
+
|
103
|
+
bool is_locked_by_this_thread() const
|
104
|
+
{
|
105
|
+
return this_thread::get_id() == id_;
|
106
|
+
}
|
107
|
+
bool is_locked() const
|
108
|
+
{
|
109
|
+
return ! (thread::id() == id_);
|
110
|
+
}
|
111
|
+
|
112
|
+
thread::id get_id() const
|
113
|
+
{
|
114
|
+
return id_;
|
115
|
+
}
|
116
|
+
|
117
|
+
// todo add the shared and upgrade mutex functions
|
118
|
+
};
|
119
|
+
|
120
|
+
template <typename Lockable>
|
121
|
+
struct is_testable_lockable : false_type
|
122
|
+
{};
|
123
|
+
|
124
|
+
template <typename Lockable>
|
125
|
+
struct is_testable_lockable<testable_mutex<Lockable> > : true_type
|
126
|
+
{};
|
127
|
+
|
128
|
+
// /**
|
129
|
+
// * Overloaded function used to check if the mutex is locked when it is testable and do nothing otherwise.
|
130
|
+
// *
|
131
|
+
// * This function is used usually to assert the pre-condition when the function can only be called when the mutex
|
132
|
+
// * must be locked by the current thread.
|
133
|
+
// */
|
134
|
+
// template <typename Lockable>
|
135
|
+
// bool is_locked_by_this_thread(testable_mutex<Lockable> const& mtx)
|
136
|
+
// {
|
137
|
+
// return mtx.is_locked();
|
138
|
+
// }
|
139
|
+
// template <typename Lockable>
|
140
|
+
// bool is_locked_by_this_thread(Lockable const&)
|
141
|
+
// {
|
142
|
+
// return true;
|
143
|
+
// }
|
144
|
+
}
|
145
|
+
|
146
|
+
#include <boost/config/abi_suffix.hpp>
|
147
|
+
|
148
|
+
#endif // header
|
data/ext/boost/thread/thread.hpp
CHANGED
@@ -9,20 +9,8 @@
|
|
9
9
|
// accompanying file LICENSE_1_0.txt or copy at
|
10
10
|
// http://www.boost.org/LICENSE_1_0.txt)
|
11
11
|
|
12
|
-
#include <boost/thread/
|
13
|
-
|
14
|
-
#if defined(BOOST_THREAD_PLATFORM_WIN32)
|
15
|
-
#include <boost/thread/win32/thread_data.hpp>
|
16
|
-
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
|
17
|
-
#include <boost/thread/pthread/thread_data.hpp>
|
18
|
-
#else
|
19
|
-
#error "Boost threads unavailable on this platform"
|
20
|
-
#endif
|
21
|
-
|
22
|
-
#include <boost/thread/detail/thread.hpp>
|
23
|
-
#include <boost/thread/detail/thread_interruption.hpp>
|
12
|
+
#include <boost/thread/thread_only.hpp>
|
24
13
|
#include <boost/thread/detail/thread_group.hpp>
|
25
|
-
#include <boost/thread/v2/thread.hpp>
|
26
14
|
|
27
15
|
|
28
16
|
#endif
|
@@ -0,0 +1,57 @@
|
|
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 Anthony Williams
|
5
|
+
// (C) Copyright 2012 Vicente J. Botet Escriba
|
6
|
+
|
7
|
+
// Based on the Anthony's idea of scoped_thread in CCiA
|
8
|
+
|
9
|
+
#ifndef BOOST_THREAD_THREAD_FUNCTORS_HPP
|
10
|
+
#define BOOST_THREAD_THREAD_FUNCTORS_HPP
|
11
|
+
|
12
|
+
#include <boost/thread/detail/config.hpp>
|
13
|
+
#include <boost/thread/detail/delete.hpp>
|
14
|
+
#include <boost/thread/detail/move.hpp>
|
15
|
+
#include <boost/thread/thread_only.hpp>
|
16
|
+
|
17
|
+
#include <boost/config/abi_prefix.hpp>
|
18
|
+
|
19
|
+
namespace boost
|
20
|
+
{
|
21
|
+
|
22
|
+
struct detach
|
23
|
+
{
|
24
|
+
void operator()(thread& t)
|
25
|
+
{
|
26
|
+
t.detach();
|
27
|
+
}
|
28
|
+
};
|
29
|
+
|
30
|
+
struct join_if_joinable
|
31
|
+
{
|
32
|
+
void operator()(thread& t)
|
33
|
+
{
|
34
|
+
if (t.joinable())
|
35
|
+
{
|
36
|
+
t.join();
|
37
|
+
}
|
38
|
+
}
|
39
|
+
};
|
40
|
+
|
41
|
+
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
42
|
+
struct interrupt_and_join_if_joinable
|
43
|
+
{
|
44
|
+
void operator()(thread& t)
|
45
|
+
{
|
46
|
+
t.interrupt();
|
47
|
+
if (t.joinable())
|
48
|
+
{
|
49
|
+
t.join();
|
50
|
+
}
|
51
|
+
}
|
52
|
+
};
|
53
|
+
#endif
|
54
|
+
}
|
55
|
+
#include <boost/config/abi_suffix.hpp>
|
56
|
+
|
57
|
+
#endif
|
@@ -0,0 +1,46 @@
|
|
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 Anthony Williams
|
5
|
+
// (C) Copyright 2012 Vicente J. Botet Escriba
|
6
|
+
|
7
|
+
// Based on the Anthony's idea of thread_joiner in CCiA
|
8
|
+
|
9
|
+
#ifndef BOOST_THREAD_THREAD_GUARD_HPP
|
10
|
+
#define BOOST_THREAD_THREAD_GUARD_HPP
|
11
|
+
|
12
|
+
#include <boost/thread/detail/delete.hpp>
|
13
|
+
#include <boost/thread/detail/move.hpp>
|
14
|
+
#include <boost/thread/thread_functors.hpp>
|
15
|
+
|
16
|
+
#include <boost/config/abi_prefix.hpp>
|
17
|
+
|
18
|
+
namespace boost
|
19
|
+
{
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Non-copyable RAII scoped thread guard joiner which join the thread if joinable when destroyed.
|
23
|
+
*/
|
24
|
+
template <class CallableThread = join_if_joinable>
|
25
|
+
class thread_guard
|
26
|
+
{
|
27
|
+
thread& t_;
|
28
|
+
public:
|
29
|
+
BOOST_THREAD_NO_COPYABLE( thread_guard)
|
30
|
+
|
31
|
+
explicit thread_guard(thread& t) :
|
32
|
+
t_(t)
|
33
|
+
{
|
34
|
+
}
|
35
|
+
~thread_guard()
|
36
|
+
{
|
37
|
+
CallableThread on_destructor;
|
38
|
+
|
39
|
+
on_destructor(t_);
|
40
|
+
}
|
41
|
+
};
|
42
|
+
|
43
|
+
}
|
44
|
+
#include <boost/config/abi_suffix.hpp>
|
45
|
+
|
46
|
+
#endif
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#ifndef BOOST_THREAD_THREAD_ONLY_HPP
|
2
|
+
#define BOOST_THREAD_THREAD_ONLY_HPP
|
3
|
+
|
4
|
+
// thread.hpp
|
5
|
+
//
|
6
|
+
// (C) Copyright 2013 Vicente J. Botet Escriba
|
7
|
+
//
|
8
|
+
// Distributed under the Boost Software License, Version 1.0. (See
|
9
|
+
// accompanying file LICENSE_1_0.txt or copy at
|
10
|
+
// http://www.boost.org/LICENSE_1_0.txt)
|
11
|
+
|
12
|
+
#include <boost/thread/detail/platform.hpp>
|
13
|
+
|
14
|
+
#if defined(BOOST_THREAD_PLATFORM_WIN32)
|
15
|
+
#include <boost/thread/win32/thread_data.hpp>
|
16
|
+
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
|
17
|
+
#include <boost/thread/pthread/thread_data.hpp>
|
18
|
+
#else
|
19
|
+
#error "Boost threads unavailable on this platform"
|
20
|
+
#endif
|
21
|
+
|
22
|
+
#include <boost/thread/detail/thread.hpp>
|
23
|
+
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
24
|
+
#include <boost/thread/detail/thread_interruption.hpp>
|
25
|
+
#endif
|
26
|
+
#include <boost/thread/v2/thread.hpp>
|
27
|
+
|
28
|
+
|
29
|
+
#endif
|
@@ -0,0 +1,1062 @@
|
|
1
|
+
#ifndef BOOST_THREAD_V2_SHARED_MUTEX_HPP
|
2
|
+
#define BOOST_THREAD_V2_SHARED_MUTEX_HPP
|
3
|
+
|
4
|
+
// shared_mutex.hpp
|
5
|
+
//
|
6
|
+
// Copyright Howard Hinnant 2007-2010.
|
7
|
+
// Copyright Vicente J. Botet Escriba 2012.
|
8
|
+
//
|
9
|
+
// Distributed under the Boost Software License, Version 1.0. (See
|
10
|
+
// accompanying file LICENSE_1_0.txt or copy at
|
11
|
+
// http://www.boost.org/LICENSE_1_0.txt)
|
12
|
+
|
13
|
+
/*
|
14
|
+
<shared_mutex> synopsis
|
15
|
+
|
16
|
+
namespace boost
|
17
|
+
{
|
18
|
+
namespace thread_v2
|
19
|
+
{
|
20
|
+
|
21
|
+
class shared_mutex
|
22
|
+
{
|
23
|
+
public:
|
24
|
+
|
25
|
+
shared_mutex();
|
26
|
+
~shared_mutex();
|
27
|
+
|
28
|
+
shared_mutex(const shared_mutex&) = delete;
|
29
|
+
shared_mutex& operator=(const shared_mutex&) = delete;
|
30
|
+
|
31
|
+
// Exclusive ownership
|
32
|
+
|
33
|
+
void lock();
|
34
|
+
bool try_lock();
|
35
|
+
template <class Rep, class Period>
|
36
|
+
bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time);
|
37
|
+
template <class Clock, class Duration>
|
38
|
+
bool
|
39
|
+
try_lock_until(
|
40
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
41
|
+
void unlock();
|
42
|
+
|
43
|
+
// Shared ownership
|
44
|
+
|
45
|
+
void lock_shared();
|
46
|
+
bool try_lock_shared();
|
47
|
+
template <class Rep, class Period>
|
48
|
+
bool
|
49
|
+
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time);
|
50
|
+
template <class Clock, class Duration>
|
51
|
+
bool
|
52
|
+
try_lock_shared_until(
|
53
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
54
|
+
void unlock_shared();
|
55
|
+
};
|
56
|
+
|
57
|
+
class upgrade_mutex
|
58
|
+
{
|
59
|
+
public:
|
60
|
+
|
61
|
+
upgrade_mutex();
|
62
|
+
~upgrade_mutex();
|
63
|
+
|
64
|
+
upgrade_mutex(const upgrade_mutex&) = delete;
|
65
|
+
upgrade_mutex& operator=(const upgrade_mutex&) = delete;
|
66
|
+
|
67
|
+
// Exclusive ownership
|
68
|
+
|
69
|
+
void lock();
|
70
|
+
bool try_lock();
|
71
|
+
template <class Rep, class Period>
|
72
|
+
bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time);
|
73
|
+
template <class Clock, class Duration>
|
74
|
+
bool
|
75
|
+
try_lock_until(
|
76
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
77
|
+
void unlock();
|
78
|
+
|
79
|
+
// Shared ownership
|
80
|
+
|
81
|
+
void lock_shared();
|
82
|
+
bool try_lock_shared();
|
83
|
+
template <class Rep, class Period>
|
84
|
+
bool
|
85
|
+
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time);
|
86
|
+
template <class Clock, class Duration>
|
87
|
+
bool
|
88
|
+
try_lock_shared_until(
|
89
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
90
|
+
void unlock_shared();
|
91
|
+
|
92
|
+
// Upgrade ownership
|
93
|
+
|
94
|
+
void lock_upgrade();
|
95
|
+
bool try_lock_upgrade();
|
96
|
+
template <class Rep, class Period>
|
97
|
+
bool
|
98
|
+
try_lock_upgrade_for(
|
99
|
+
const boost::chrono::duration<Rep, Period>& rel_time);
|
100
|
+
template <class Clock, class Duration>
|
101
|
+
bool
|
102
|
+
try_lock_upgrade_until(
|
103
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
104
|
+
void unlock_upgrade();
|
105
|
+
|
106
|
+
// Shared <-> Exclusive
|
107
|
+
|
108
|
+
bool try_unlock_shared_and_lock();
|
109
|
+
template <class Rep, class Period>
|
110
|
+
bool
|
111
|
+
try_unlock_shared_and_lock_for(
|
112
|
+
const boost::chrono::duration<Rep, Period>& rel_time);
|
113
|
+
template <class Clock, class Duration>
|
114
|
+
bool
|
115
|
+
try_unlock_shared_and_lock_until(
|
116
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
117
|
+
void unlock_and_lock_shared();
|
118
|
+
|
119
|
+
// Shared <-> Upgrade
|
120
|
+
|
121
|
+
bool try_unlock_shared_and_lock_upgrade();
|
122
|
+
template <class Rep, class Period>
|
123
|
+
bool
|
124
|
+
try_unlock_shared_and_lock_upgrade_for(
|
125
|
+
const boost::chrono::duration<Rep, Period>& rel_time);
|
126
|
+
template <class Clock, class Duration>
|
127
|
+
bool
|
128
|
+
try_unlock_shared_and_lock_upgrade_until(
|
129
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
130
|
+
void unlock_upgrade_and_lock_shared();
|
131
|
+
|
132
|
+
// Upgrade <-> Exclusive
|
133
|
+
|
134
|
+
void unlock_upgrade_and_lock();
|
135
|
+
bool try_unlock_upgrade_and_lock();
|
136
|
+
template <class Rep, class Period>
|
137
|
+
bool
|
138
|
+
try_unlock_upgrade_and_lock_for(
|
139
|
+
const boost::chrono::duration<Rep, Period>& rel_time);
|
140
|
+
template <class Clock, class Duration>
|
141
|
+
bool
|
142
|
+
try_unlock_upgrade_and_lock_until(
|
143
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
144
|
+
void unlock_and_lock_upgrade();
|
145
|
+
};
|
146
|
+
|
147
|
+
} // thread_v2
|
148
|
+
} // boost
|
149
|
+
|
150
|
+
*/
|
151
|
+
|
152
|
+
#include <boost/thread/detail/config.hpp>
|
153
|
+
#include <boost/thread/mutex.hpp>
|
154
|
+
#include <boost/thread/condition_variable.hpp>
|
155
|
+
#include <boost/thread/mutex.hpp>
|
156
|
+
#include <boost/chrono.hpp>
|
157
|
+
#include <climits>
|
158
|
+
#include <boost/system/system_error.hpp>
|
159
|
+
#define BOOST_THREAD_INLINE inline
|
160
|
+
|
161
|
+
namespace boost {
|
162
|
+
namespace thread_v2 {
|
163
|
+
|
164
|
+
class shared_mutex
|
165
|
+
{
|
166
|
+
typedef ::boost::mutex mutex_t;
|
167
|
+
typedef ::boost::condition_variable cond_t;
|
168
|
+
typedef unsigned count_t;
|
169
|
+
|
170
|
+
mutex_t mut_;
|
171
|
+
cond_t gate1_;
|
172
|
+
cond_t gate2_;
|
173
|
+
count_t state_;
|
174
|
+
|
175
|
+
static const count_t write_entered_ = 1U << (sizeof(count_t)*CHAR_BIT - 1);
|
176
|
+
static const count_t n_readers_ = ~write_entered_;
|
177
|
+
|
178
|
+
public:
|
179
|
+
BOOST_THREAD_INLINE shared_mutex();
|
180
|
+
BOOST_THREAD_INLINE ~shared_mutex();
|
181
|
+
|
182
|
+
#ifndef BOOST_NO_DELETED_FUNCTIONS
|
183
|
+
shared_mutex(shared_mutex const&) = delete;
|
184
|
+
shared_mutex& operator=(shared_mutex const&) = delete;
|
185
|
+
#else // BOOST_NO_DELETED_FUNCTIONS
|
186
|
+
private:
|
187
|
+
shared_mutex(shared_mutex const&);
|
188
|
+
shared_mutex& operator=(shared_mutex const&);
|
189
|
+
public:
|
190
|
+
#endif // BOOST_NO_DELETED_FUNCTIONS
|
191
|
+
|
192
|
+
// Exclusive ownership
|
193
|
+
|
194
|
+
BOOST_THREAD_INLINE void lock();
|
195
|
+
BOOST_THREAD_INLINE bool try_lock();
|
196
|
+
template <class Rep, class Period>
|
197
|
+
bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time)
|
198
|
+
{
|
199
|
+
return try_lock_until(boost::chrono::steady_clock::now() + rel_time);
|
200
|
+
}
|
201
|
+
template <class Clock, class Duration>
|
202
|
+
bool
|
203
|
+
try_lock_until(
|
204
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
205
|
+
BOOST_THREAD_INLINE void unlock();
|
206
|
+
|
207
|
+
|
208
|
+
// Shared ownership
|
209
|
+
|
210
|
+
BOOST_THREAD_INLINE void lock_shared();
|
211
|
+
BOOST_THREAD_INLINE bool try_lock_shared();
|
212
|
+
template <class Rep, class Period>
|
213
|
+
bool
|
214
|
+
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
|
215
|
+
{
|
216
|
+
return try_lock_shared_until(boost::chrono::steady_clock::now() +
|
217
|
+
rel_time);
|
218
|
+
}
|
219
|
+
template <class Clock, class Duration>
|
220
|
+
bool
|
221
|
+
try_lock_shared_until(
|
222
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
223
|
+
BOOST_THREAD_INLINE void unlock_shared();
|
224
|
+
|
225
|
+
#if defined BOOST_THREAD_USES_DATETIME
|
226
|
+
bool timed_lock(system_time const& timeout);
|
227
|
+
template<typename TimeDuration>
|
228
|
+
bool timed_lock(TimeDuration const & relative_time)
|
229
|
+
{
|
230
|
+
return timed_lock(get_system_time()+relative_time);
|
231
|
+
}
|
232
|
+
bool timed_lock_shared(system_time const& timeout);
|
233
|
+
template<typename TimeDuration>
|
234
|
+
bool timed_lock_shared(TimeDuration const & relative_time)
|
235
|
+
{
|
236
|
+
return timed_lock_shared(get_system_time()+relative_time);
|
237
|
+
}
|
238
|
+
#endif
|
239
|
+
};
|
240
|
+
|
241
|
+
template <class Clock, class Duration>
|
242
|
+
bool
|
243
|
+
shared_mutex::try_lock_until(
|
244
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
245
|
+
{
|
246
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
247
|
+
if (state_ & write_entered_)
|
248
|
+
{
|
249
|
+
while (true)
|
250
|
+
{
|
251
|
+
boost::cv_status status = gate1_.wait_until(lk, abs_time);
|
252
|
+
if ((state_ & write_entered_) == 0)
|
253
|
+
break;
|
254
|
+
if (status == boost::cv_status::timeout)
|
255
|
+
return false;
|
256
|
+
}
|
257
|
+
}
|
258
|
+
state_ |= write_entered_;
|
259
|
+
if (state_ & n_readers_)
|
260
|
+
{
|
261
|
+
while (true)
|
262
|
+
{
|
263
|
+
boost::cv_status status = gate2_.wait_until(lk, abs_time);
|
264
|
+
if ((state_ & n_readers_) == 0)
|
265
|
+
break;
|
266
|
+
if (status == boost::cv_status::timeout)
|
267
|
+
{
|
268
|
+
state_ &= ~write_entered_;
|
269
|
+
return false;
|
270
|
+
}
|
271
|
+
}
|
272
|
+
}
|
273
|
+
return true;
|
274
|
+
}
|
275
|
+
|
276
|
+
template <class Clock, class Duration>
|
277
|
+
bool
|
278
|
+
shared_mutex::try_lock_shared_until(
|
279
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
280
|
+
{
|
281
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
282
|
+
if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
|
283
|
+
{
|
284
|
+
while (true)
|
285
|
+
{
|
286
|
+
boost::cv_status status = gate1_.wait_until(lk, abs_time);
|
287
|
+
if ((state_ & write_entered_) == 0 &&
|
288
|
+
(state_ & n_readers_) < n_readers_)
|
289
|
+
break;
|
290
|
+
if (status == boost::cv_status::timeout)
|
291
|
+
return false;
|
292
|
+
}
|
293
|
+
}
|
294
|
+
count_t num_readers = (state_ & n_readers_) + 1;
|
295
|
+
state_ &= ~n_readers_;
|
296
|
+
state_ |= num_readers;
|
297
|
+
return true;
|
298
|
+
}
|
299
|
+
|
300
|
+
#if defined BOOST_THREAD_USES_DATETIME
|
301
|
+
bool shared_mutex::timed_lock(system_time const& abs_time)
|
302
|
+
{
|
303
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
304
|
+
if (state_ & write_entered_)
|
305
|
+
{
|
306
|
+
while (true)
|
307
|
+
{
|
308
|
+
bool status = gate1_.timed_wait(lk, abs_time);
|
309
|
+
if ((state_ & write_entered_) == 0)
|
310
|
+
break;
|
311
|
+
if (!status)
|
312
|
+
return false;
|
313
|
+
}
|
314
|
+
}
|
315
|
+
state_ |= write_entered_;
|
316
|
+
if (state_ & n_readers_)
|
317
|
+
{
|
318
|
+
while (true)
|
319
|
+
{
|
320
|
+
bool status = gate2_.timed_wait(lk, abs_time);
|
321
|
+
if ((state_ & n_readers_) == 0)
|
322
|
+
break;
|
323
|
+
if (!status)
|
324
|
+
{
|
325
|
+
state_ &= ~write_entered_;
|
326
|
+
return false;
|
327
|
+
}
|
328
|
+
}
|
329
|
+
}
|
330
|
+
return true;
|
331
|
+
}
|
332
|
+
bool shared_mutex::timed_lock_shared(system_time const& abs_time)
|
333
|
+
{
|
334
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
335
|
+
if (state_ & write_entered_)
|
336
|
+
{
|
337
|
+
while (true)
|
338
|
+
{
|
339
|
+
bool status = gate1_.timed_wait(lk, abs_time);
|
340
|
+
if ((state_ & write_entered_) == 0)
|
341
|
+
break;
|
342
|
+
if (!status )
|
343
|
+
return false;
|
344
|
+
}
|
345
|
+
}
|
346
|
+
state_ |= write_entered_;
|
347
|
+
if (state_ & n_readers_)
|
348
|
+
{
|
349
|
+
while (true)
|
350
|
+
{
|
351
|
+
bool status = gate2_.timed_wait(lk, abs_time);
|
352
|
+
if ((state_ & n_readers_) == 0)
|
353
|
+
break;
|
354
|
+
if (!status)
|
355
|
+
{
|
356
|
+
state_ &= ~write_entered_;
|
357
|
+
return false;
|
358
|
+
}
|
359
|
+
}
|
360
|
+
}
|
361
|
+
return true;
|
362
|
+
}
|
363
|
+
#endif
|
364
|
+
class upgrade_mutex
|
365
|
+
{
|
366
|
+
typedef boost::mutex mutex_t;
|
367
|
+
typedef boost::condition_variable cond_t;
|
368
|
+
typedef unsigned count_t;
|
369
|
+
|
370
|
+
mutex_t mut_;
|
371
|
+
cond_t gate1_;
|
372
|
+
cond_t gate2_;
|
373
|
+
count_t state_;
|
374
|
+
|
375
|
+
static const unsigned write_entered_ = 1U << (sizeof(count_t)*CHAR_BIT - 1);
|
376
|
+
static const unsigned upgradable_entered_ = write_entered_ >> 1;
|
377
|
+
static const unsigned n_readers_ = ~(write_entered_ | upgradable_entered_);
|
378
|
+
|
379
|
+
public:
|
380
|
+
|
381
|
+
BOOST_THREAD_INLINE upgrade_mutex();
|
382
|
+
BOOST_THREAD_INLINE ~upgrade_mutex();
|
383
|
+
|
384
|
+
#ifndef BOOST_NO_DELETED_FUNCTIONS
|
385
|
+
upgrade_mutex(const upgrade_mutex&) = delete;
|
386
|
+
upgrade_mutex& operator=(const upgrade_mutex&) = delete;
|
387
|
+
#else // BOOST_NO_DELETED_FUNCTIONS
|
388
|
+
private:
|
389
|
+
upgrade_mutex(const upgrade_mutex&);
|
390
|
+
upgrade_mutex& operator=(const upgrade_mutex&);
|
391
|
+
public:
|
392
|
+
#endif // BOOST_NO_DELETED_FUNCTIONS
|
393
|
+
|
394
|
+
// Exclusive ownership
|
395
|
+
|
396
|
+
BOOST_THREAD_INLINE void lock();
|
397
|
+
BOOST_THREAD_INLINE bool try_lock();
|
398
|
+
template <class Rep, class Period>
|
399
|
+
bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time)
|
400
|
+
{
|
401
|
+
return try_lock_until(boost::chrono::steady_clock::now() + rel_time);
|
402
|
+
}
|
403
|
+
template <class Clock, class Duration>
|
404
|
+
bool
|
405
|
+
try_lock_until(
|
406
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
407
|
+
BOOST_THREAD_INLINE void unlock();
|
408
|
+
|
409
|
+
// Shared ownership
|
410
|
+
|
411
|
+
BOOST_THREAD_INLINE void lock_shared();
|
412
|
+
BOOST_THREAD_INLINE bool try_lock_shared();
|
413
|
+
template <class Rep, class Period>
|
414
|
+
bool
|
415
|
+
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
|
416
|
+
{
|
417
|
+
return try_lock_shared_until(boost::chrono::steady_clock::now() +
|
418
|
+
rel_time);
|
419
|
+
}
|
420
|
+
template <class Clock, class Duration>
|
421
|
+
bool
|
422
|
+
try_lock_shared_until(
|
423
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
424
|
+
BOOST_THREAD_INLINE void unlock_shared();
|
425
|
+
|
426
|
+
// Upgrade ownership
|
427
|
+
|
428
|
+
BOOST_THREAD_INLINE void lock_upgrade();
|
429
|
+
BOOST_THREAD_INLINE bool try_lock_upgrade();
|
430
|
+
template <class Rep, class Period>
|
431
|
+
bool
|
432
|
+
try_lock_upgrade_for(
|
433
|
+
const boost::chrono::duration<Rep, Period>& rel_time)
|
434
|
+
{
|
435
|
+
return try_lock_upgrade_until(boost::chrono::steady_clock::now() +
|
436
|
+
rel_time);
|
437
|
+
}
|
438
|
+
template <class Clock, class Duration>
|
439
|
+
bool
|
440
|
+
try_lock_upgrade_until(
|
441
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
442
|
+
BOOST_THREAD_INLINE void unlock_upgrade();
|
443
|
+
|
444
|
+
// Shared <-> Exclusive
|
445
|
+
|
446
|
+
BOOST_THREAD_INLINE bool try_unlock_shared_and_lock();
|
447
|
+
template <class Rep, class Period>
|
448
|
+
bool
|
449
|
+
try_unlock_shared_and_lock_for(
|
450
|
+
const boost::chrono::duration<Rep, Period>& rel_time)
|
451
|
+
{
|
452
|
+
return try_unlock_shared_and_lock_until(
|
453
|
+
boost::chrono::steady_clock::now() + rel_time);
|
454
|
+
}
|
455
|
+
template <class Clock, class Duration>
|
456
|
+
bool
|
457
|
+
try_unlock_shared_and_lock_until(
|
458
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
459
|
+
BOOST_THREAD_INLINE void unlock_and_lock_shared();
|
460
|
+
|
461
|
+
// Shared <-> Upgrade
|
462
|
+
|
463
|
+
BOOST_THREAD_INLINE bool try_unlock_shared_and_lock_upgrade();
|
464
|
+
template <class Rep, class Period>
|
465
|
+
bool
|
466
|
+
try_unlock_shared_and_lock_upgrade_for(
|
467
|
+
const boost::chrono::duration<Rep, Period>& rel_time)
|
468
|
+
{
|
469
|
+
return try_unlock_shared_and_lock_upgrade_until(
|
470
|
+
boost::chrono::steady_clock::now() + rel_time);
|
471
|
+
}
|
472
|
+
template <class Clock, class Duration>
|
473
|
+
bool
|
474
|
+
try_unlock_shared_and_lock_upgrade_until(
|
475
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
476
|
+
BOOST_THREAD_INLINE void unlock_upgrade_and_lock_shared();
|
477
|
+
|
478
|
+
// Upgrade <-> Exclusive
|
479
|
+
|
480
|
+
BOOST_THREAD_INLINE void unlock_upgrade_and_lock();
|
481
|
+
BOOST_THREAD_INLINE bool try_unlock_upgrade_and_lock();
|
482
|
+
template <class Rep, class Period>
|
483
|
+
bool
|
484
|
+
try_unlock_upgrade_and_lock_for(
|
485
|
+
const boost::chrono::duration<Rep, Period>& rel_time)
|
486
|
+
{
|
487
|
+
return try_unlock_upgrade_and_lock_until(
|
488
|
+
boost::chrono::steady_clock::now() + rel_time);
|
489
|
+
}
|
490
|
+
template <class Clock, class Duration>
|
491
|
+
bool
|
492
|
+
try_unlock_upgrade_and_lock_until(
|
493
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time);
|
494
|
+
BOOST_THREAD_INLINE void unlock_and_lock_upgrade();
|
495
|
+
|
496
|
+
#if defined BOOST_THREAD_USES_DATETIME
|
497
|
+
inline bool timed_lock(system_time const& abs_time);
|
498
|
+
template<typename TimeDuration>
|
499
|
+
bool timed_lock(TimeDuration const & relative_time)
|
500
|
+
{
|
501
|
+
return timed_lock(get_system_time()+relative_time);
|
502
|
+
}
|
503
|
+
inline bool timed_lock_shared(system_time const& abs_time);
|
504
|
+
template<typename TimeDuration>
|
505
|
+
bool timed_lock_shared(TimeDuration const & relative_time)
|
506
|
+
{
|
507
|
+
return timed_lock_shared(get_system_time()+relative_time);
|
508
|
+
}
|
509
|
+
inline bool timed_lock_upgrade(system_time const& abs_time);
|
510
|
+
template<typename TimeDuration>
|
511
|
+
bool timed_lock_upgrade(TimeDuration const & relative_time)
|
512
|
+
{
|
513
|
+
return timed_lock_upgrade(get_system_time()+relative_time);
|
514
|
+
}
|
515
|
+
#endif
|
516
|
+
|
517
|
+
};
|
518
|
+
|
519
|
+
template <class Clock, class Duration>
|
520
|
+
bool
|
521
|
+
upgrade_mutex::try_lock_until(
|
522
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
523
|
+
{
|
524
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
525
|
+
if (state_ & (write_entered_ | upgradable_entered_))
|
526
|
+
{
|
527
|
+
while (true)
|
528
|
+
{
|
529
|
+
boost::cv_status status = gate1_.wait_until(lk, abs_time);
|
530
|
+
if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
|
531
|
+
break;
|
532
|
+
if (status == boost::cv_status::timeout)
|
533
|
+
return false;
|
534
|
+
}
|
535
|
+
}
|
536
|
+
state_ |= write_entered_;
|
537
|
+
if (state_ & n_readers_)
|
538
|
+
{
|
539
|
+
while (true)
|
540
|
+
{
|
541
|
+
boost::cv_status status = gate2_.wait_until(lk, abs_time);
|
542
|
+
if ((state_ & n_readers_) == 0)
|
543
|
+
break;
|
544
|
+
if (status == boost::cv_status::timeout)
|
545
|
+
{
|
546
|
+
state_ &= ~write_entered_;
|
547
|
+
return false;
|
548
|
+
}
|
549
|
+
}
|
550
|
+
}
|
551
|
+
return true;
|
552
|
+
}
|
553
|
+
|
554
|
+
template <class Clock, class Duration>
|
555
|
+
bool
|
556
|
+
upgrade_mutex::try_lock_shared_until(
|
557
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
558
|
+
{
|
559
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
560
|
+
if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
|
561
|
+
{
|
562
|
+
while (true)
|
563
|
+
{
|
564
|
+
boost::cv_status status = gate1_.wait_until(lk, abs_time);
|
565
|
+
if ((state_ & write_entered_) == 0 &&
|
566
|
+
(state_ & n_readers_) < n_readers_)
|
567
|
+
break;
|
568
|
+
if (status == boost::cv_status::timeout)
|
569
|
+
return false;
|
570
|
+
}
|
571
|
+
}
|
572
|
+
count_t num_readers = (state_ & n_readers_) + 1;
|
573
|
+
state_ &= ~n_readers_;
|
574
|
+
state_ |= num_readers;
|
575
|
+
return true;
|
576
|
+
}
|
577
|
+
|
578
|
+
template <class Clock, class Duration>
|
579
|
+
bool
|
580
|
+
upgrade_mutex::try_lock_upgrade_until(
|
581
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
582
|
+
{
|
583
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
584
|
+
if ((state_ & (write_entered_ | upgradable_entered_)) ||
|
585
|
+
(state_ & n_readers_) == n_readers_)
|
586
|
+
{
|
587
|
+
while (true)
|
588
|
+
{
|
589
|
+
boost::cv_status status = gate1_.wait_until(lk, abs_time);
|
590
|
+
if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
|
591
|
+
(state_ & n_readers_) < n_readers_)
|
592
|
+
break;
|
593
|
+
if (status == boost::cv_status::timeout)
|
594
|
+
return false;
|
595
|
+
}
|
596
|
+
}
|
597
|
+
count_t num_readers = (state_ & n_readers_) + 1;
|
598
|
+
state_ &= ~n_readers_;
|
599
|
+
state_ |= upgradable_entered_ | num_readers;
|
600
|
+
return true;
|
601
|
+
}
|
602
|
+
|
603
|
+
#if defined BOOST_THREAD_USES_DATETIME
|
604
|
+
bool upgrade_mutex::timed_lock(system_time const& abs_time)
|
605
|
+
{
|
606
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
607
|
+
if (state_ & (write_entered_ | upgradable_entered_))
|
608
|
+
{
|
609
|
+
while (true)
|
610
|
+
{
|
611
|
+
bool status = gate1_.timed_wait(lk, abs_time);
|
612
|
+
if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
|
613
|
+
break;
|
614
|
+
if (!status)
|
615
|
+
return false;
|
616
|
+
}
|
617
|
+
}
|
618
|
+
state_ |= write_entered_;
|
619
|
+
if (state_ & n_readers_)
|
620
|
+
{
|
621
|
+
while (true)
|
622
|
+
{
|
623
|
+
bool status = gate2_.timed_wait(lk, abs_time);
|
624
|
+
if ((state_ & n_readers_) == 0)
|
625
|
+
break;
|
626
|
+
if (!status)
|
627
|
+
{
|
628
|
+
state_ &= ~write_entered_;
|
629
|
+
return false;
|
630
|
+
}
|
631
|
+
}
|
632
|
+
}
|
633
|
+
return true;
|
634
|
+
}
|
635
|
+
bool upgrade_mutex::timed_lock_shared(system_time const& abs_time)
|
636
|
+
{
|
637
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
638
|
+
if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
|
639
|
+
{
|
640
|
+
while (true)
|
641
|
+
{
|
642
|
+
bool status = gate1_.timed_wait(lk, abs_time);
|
643
|
+
if ((state_ & write_entered_) == 0 &&
|
644
|
+
(state_ & n_readers_) < n_readers_)
|
645
|
+
break;
|
646
|
+
if (!status)
|
647
|
+
return false;
|
648
|
+
}
|
649
|
+
}
|
650
|
+
count_t num_readers = (state_ & n_readers_) + 1;
|
651
|
+
state_ &= ~n_readers_;
|
652
|
+
state_ |= num_readers;
|
653
|
+
return true;
|
654
|
+
}
|
655
|
+
bool upgrade_mutex::timed_lock_upgrade(system_time const& abs_time)
|
656
|
+
{
|
657
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
658
|
+
if ((state_ & (write_entered_ | upgradable_entered_)) ||
|
659
|
+
(state_ & n_readers_) == n_readers_)
|
660
|
+
{
|
661
|
+
while (true)
|
662
|
+
{
|
663
|
+
bool status = gate1_.timed_wait(lk, abs_time);
|
664
|
+
if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
|
665
|
+
(state_ & n_readers_) < n_readers_)
|
666
|
+
break;
|
667
|
+
if (!status)
|
668
|
+
return false;
|
669
|
+
}
|
670
|
+
}
|
671
|
+
count_t num_readers = (state_ & n_readers_) + 1;
|
672
|
+
state_ &= ~n_readers_;
|
673
|
+
state_ |= upgradable_entered_ | num_readers;
|
674
|
+
return true;
|
675
|
+
}
|
676
|
+
|
677
|
+
#endif
|
678
|
+
template <class Clock, class Duration>
|
679
|
+
bool
|
680
|
+
upgrade_mutex::try_unlock_shared_and_lock_until(
|
681
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
682
|
+
{
|
683
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
684
|
+
if (state_ != 1)
|
685
|
+
{
|
686
|
+
while (true)
|
687
|
+
{
|
688
|
+
boost::cv_status status = gate2_.wait_until(lk, abs_time);
|
689
|
+
if (state_ == 1)
|
690
|
+
break;
|
691
|
+
if (status == boost::cv_status::timeout)
|
692
|
+
return false;
|
693
|
+
}
|
694
|
+
}
|
695
|
+
state_ = write_entered_;
|
696
|
+
return true;
|
697
|
+
}
|
698
|
+
|
699
|
+
template <class Clock, class Duration>
|
700
|
+
bool
|
701
|
+
upgrade_mutex::try_unlock_shared_and_lock_upgrade_until(
|
702
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
703
|
+
{
|
704
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
705
|
+
if ((state_ & (write_entered_ | upgradable_entered_)) != 0)
|
706
|
+
{
|
707
|
+
while (true)
|
708
|
+
{
|
709
|
+
boost::cv_status status = gate2_.wait_until(lk, abs_time);
|
710
|
+
if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
|
711
|
+
break;
|
712
|
+
if (status == boost::cv_status::timeout)
|
713
|
+
return false;
|
714
|
+
}
|
715
|
+
}
|
716
|
+
state_ |= upgradable_entered_;
|
717
|
+
return true;
|
718
|
+
}
|
719
|
+
|
720
|
+
template <class Clock, class Duration>
|
721
|
+
bool
|
722
|
+
upgrade_mutex::try_unlock_upgrade_and_lock_until(
|
723
|
+
const boost::chrono::time_point<Clock, Duration>& abs_time)
|
724
|
+
{
|
725
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
726
|
+
if ((state_ & n_readers_) != 1)
|
727
|
+
{
|
728
|
+
while (true)
|
729
|
+
{
|
730
|
+
boost::cv_status status = gate2_.wait_until(lk, abs_time);
|
731
|
+
if ((state_ & n_readers_) == 1)
|
732
|
+
break;
|
733
|
+
if (status == boost::cv_status::timeout)
|
734
|
+
return false;
|
735
|
+
}
|
736
|
+
}
|
737
|
+
state_ = write_entered_;
|
738
|
+
return true;
|
739
|
+
}
|
740
|
+
|
741
|
+
//////
|
742
|
+
// shared_mutex
|
743
|
+
|
744
|
+
shared_mutex::shared_mutex()
|
745
|
+
: state_(0)
|
746
|
+
{
|
747
|
+
}
|
748
|
+
|
749
|
+
shared_mutex::~shared_mutex()
|
750
|
+
{
|
751
|
+
boost::lock_guard<mutex_t> _(mut_);
|
752
|
+
}
|
753
|
+
|
754
|
+
// Exclusive ownership
|
755
|
+
|
756
|
+
void
|
757
|
+
shared_mutex::lock()
|
758
|
+
{
|
759
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
760
|
+
while (state_ & write_entered_)
|
761
|
+
gate1_.wait(lk);
|
762
|
+
state_ |= write_entered_;
|
763
|
+
while (state_ & n_readers_)
|
764
|
+
gate2_.wait(lk);
|
765
|
+
}
|
766
|
+
|
767
|
+
bool
|
768
|
+
shared_mutex::try_lock()
|
769
|
+
{
|
770
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
771
|
+
if (state_ == 0)
|
772
|
+
{
|
773
|
+
state_ = write_entered_;
|
774
|
+
return true;
|
775
|
+
}
|
776
|
+
return false;
|
777
|
+
}
|
778
|
+
|
779
|
+
void
|
780
|
+
shared_mutex::unlock()
|
781
|
+
{
|
782
|
+
boost::lock_guard<mutex_t> _(mut_);
|
783
|
+
state_ = 0;
|
784
|
+
gate1_.notify_all();
|
785
|
+
}
|
786
|
+
|
787
|
+
// Shared ownership
|
788
|
+
|
789
|
+
void
|
790
|
+
shared_mutex::lock_shared()
|
791
|
+
{
|
792
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
793
|
+
while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
|
794
|
+
gate1_.wait(lk);
|
795
|
+
count_t num_readers = (state_ & n_readers_) + 1;
|
796
|
+
state_ &= ~n_readers_;
|
797
|
+
state_ |= num_readers;
|
798
|
+
}
|
799
|
+
|
800
|
+
bool
|
801
|
+
shared_mutex::try_lock_shared()
|
802
|
+
{
|
803
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
804
|
+
count_t num_readers = state_ & n_readers_;
|
805
|
+
if (!(state_ & write_entered_) && num_readers != n_readers_)
|
806
|
+
{
|
807
|
+
++num_readers;
|
808
|
+
state_ &= ~n_readers_;
|
809
|
+
state_ |= num_readers;
|
810
|
+
return true;
|
811
|
+
}
|
812
|
+
return false;
|
813
|
+
}
|
814
|
+
|
815
|
+
void
|
816
|
+
shared_mutex::unlock_shared()
|
817
|
+
{
|
818
|
+
boost::lock_guard<mutex_t> _(mut_);
|
819
|
+
count_t num_readers = (state_ & n_readers_) - 1;
|
820
|
+
state_ &= ~n_readers_;
|
821
|
+
state_ |= num_readers;
|
822
|
+
if (state_ & write_entered_)
|
823
|
+
{
|
824
|
+
if (num_readers == 0)
|
825
|
+
gate2_.notify_one();
|
826
|
+
}
|
827
|
+
else
|
828
|
+
{
|
829
|
+
if (num_readers == n_readers_ - 1)
|
830
|
+
gate1_.notify_one();
|
831
|
+
}
|
832
|
+
}
|
833
|
+
|
834
|
+
// upgrade_mutex
|
835
|
+
|
836
|
+
upgrade_mutex::upgrade_mutex()
|
837
|
+
: gate1_(),
|
838
|
+
gate2_(),
|
839
|
+
state_(0)
|
840
|
+
{
|
841
|
+
}
|
842
|
+
|
843
|
+
upgrade_mutex::~upgrade_mutex()
|
844
|
+
{
|
845
|
+
boost::lock_guard<mutex_t> _(mut_);
|
846
|
+
}
|
847
|
+
|
848
|
+
// Exclusive ownership
|
849
|
+
|
850
|
+
void
|
851
|
+
upgrade_mutex::lock()
|
852
|
+
{
|
853
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
854
|
+
while (state_ & (write_entered_ | upgradable_entered_))
|
855
|
+
gate1_.wait(lk);
|
856
|
+
state_ |= write_entered_;
|
857
|
+
while (state_ & n_readers_)
|
858
|
+
gate2_.wait(lk);
|
859
|
+
}
|
860
|
+
|
861
|
+
bool
|
862
|
+
upgrade_mutex::try_lock()
|
863
|
+
{
|
864
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
865
|
+
if (state_ == 0)
|
866
|
+
{
|
867
|
+
state_ = write_entered_;
|
868
|
+
return true;
|
869
|
+
}
|
870
|
+
return false;
|
871
|
+
}
|
872
|
+
|
873
|
+
void
|
874
|
+
upgrade_mutex::unlock()
|
875
|
+
{
|
876
|
+
boost::lock_guard<mutex_t> _(mut_);
|
877
|
+
state_ = 0;
|
878
|
+
gate1_.notify_all();
|
879
|
+
}
|
880
|
+
|
881
|
+
// Shared ownership
|
882
|
+
|
883
|
+
void
|
884
|
+
upgrade_mutex::lock_shared()
|
885
|
+
{
|
886
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
887
|
+
while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
|
888
|
+
gate1_.wait(lk);
|
889
|
+
count_t num_readers = (state_ & n_readers_) + 1;
|
890
|
+
state_ &= ~n_readers_;
|
891
|
+
state_ |= num_readers;
|
892
|
+
}
|
893
|
+
|
894
|
+
bool
|
895
|
+
upgrade_mutex::try_lock_shared()
|
896
|
+
{
|
897
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
898
|
+
count_t num_readers = state_ & n_readers_;
|
899
|
+
if (!(state_ & write_entered_) && num_readers != n_readers_)
|
900
|
+
{
|
901
|
+
++num_readers;
|
902
|
+
state_ &= ~n_readers_;
|
903
|
+
state_ |= num_readers;
|
904
|
+
return true;
|
905
|
+
}
|
906
|
+
return false;
|
907
|
+
}
|
908
|
+
|
909
|
+
void
|
910
|
+
upgrade_mutex::unlock_shared()
|
911
|
+
{
|
912
|
+
boost::lock_guard<mutex_t> _(mut_);
|
913
|
+
count_t num_readers = (state_ & n_readers_) - 1;
|
914
|
+
state_ &= ~n_readers_;
|
915
|
+
state_ |= num_readers;
|
916
|
+
if (state_ & write_entered_)
|
917
|
+
{
|
918
|
+
if (num_readers == 0)
|
919
|
+
gate2_.notify_one();
|
920
|
+
}
|
921
|
+
else
|
922
|
+
{
|
923
|
+
if (num_readers == n_readers_ - 1)
|
924
|
+
gate1_.notify_one();
|
925
|
+
}
|
926
|
+
}
|
927
|
+
|
928
|
+
// Upgrade ownership
|
929
|
+
|
930
|
+
void
|
931
|
+
upgrade_mutex::lock_upgrade()
|
932
|
+
{
|
933
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
934
|
+
while ((state_ & (write_entered_ | upgradable_entered_)) ||
|
935
|
+
(state_ & n_readers_) == n_readers_)
|
936
|
+
gate1_.wait(lk);
|
937
|
+
count_t num_readers = (state_ & n_readers_) + 1;
|
938
|
+
state_ &= ~n_readers_;
|
939
|
+
state_ |= upgradable_entered_ | num_readers;
|
940
|
+
}
|
941
|
+
|
942
|
+
bool
|
943
|
+
upgrade_mutex::try_lock_upgrade()
|
944
|
+
{
|
945
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
946
|
+
count_t num_readers = state_ & n_readers_;
|
947
|
+
if (!(state_ & (write_entered_ | upgradable_entered_))
|
948
|
+
&& num_readers != n_readers_)
|
949
|
+
{
|
950
|
+
++num_readers;
|
951
|
+
state_ &= ~n_readers_;
|
952
|
+
state_ |= upgradable_entered_ | num_readers;
|
953
|
+
return true;
|
954
|
+
}
|
955
|
+
return false;
|
956
|
+
}
|
957
|
+
|
958
|
+
void
|
959
|
+
upgrade_mutex::unlock_upgrade()
|
960
|
+
{
|
961
|
+
{
|
962
|
+
boost::lock_guard<mutex_t> _(mut_);
|
963
|
+
count_t num_readers = (state_ & n_readers_) - 1;
|
964
|
+
state_ &= ~(upgradable_entered_ | n_readers_);
|
965
|
+
state_ |= num_readers;
|
966
|
+
}
|
967
|
+
gate1_.notify_all();
|
968
|
+
}
|
969
|
+
|
970
|
+
// Shared <-> Exclusive
|
971
|
+
|
972
|
+
bool
|
973
|
+
upgrade_mutex::try_unlock_shared_and_lock()
|
974
|
+
{
|
975
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
976
|
+
if (state_ == 1)
|
977
|
+
{
|
978
|
+
state_ = write_entered_;
|
979
|
+
return true;
|
980
|
+
}
|
981
|
+
return false;
|
982
|
+
}
|
983
|
+
|
984
|
+
void
|
985
|
+
upgrade_mutex::unlock_and_lock_shared()
|
986
|
+
{
|
987
|
+
{
|
988
|
+
boost::lock_guard<mutex_t> _(mut_);
|
989
|
+
state_ = 1;
|
990
|
+
}
|
991
|
+
gate1_.notify_all();
|
992
|
+
}
|
993
|
+
|
994
|
+
// Shared <-> Upgrade
|
995
|
+
|
996
|
+
bool
|
997
|
+
upgrade_mutex::try_unlock_shared_and_lock_upgrade()
|
998
|
+
{
|
999
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
1000
|
+
if (!(state_ & (write_entered_ | upgradable_entered_)))
|
1001
|
+
{
|
1002
|
+
state_ |= upgradable_entered_;
|
1003
|
+
return true;
|
1004
|
+
}
|
1005
|
+
return false;
|
1006
|
+
}
|
1007
|
+
|
1008
|
+
void
|
1009
|
+
upgrade_mutex::unlock_upgrade_and_lock_shared()
|
1010
|
+
{
|
1011
|
+
{
|
1012
|
+
boost::lock_guard<mutex_t> _(mut_);
|
1013
|
+
state_ &= ~upgradable_entered_;
|
1014
|
+
}
|
1015
|
+
gate1_.notify_all();
|
1016
|
+
}
|
1017
|
+
|
1018
|
+
// Upgrade <-> Exclusive
|
1019
|
+
|
1020
|
+
void
|
1021
|
+
upgrade_mutex::unlock_upgrade_and_lock()
|
1022
|
+
{
|
1023
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
1024
|
+
count_t num_readers = (state_ & n_readers_) - 1;
|
1025
|
+
state_ &= ~(upgradable_entered_ | n_readers_);
|
1026
|
+
state_ |= write_entered_ | num_readers;
|
1027
|
+
while (state_ & n_readers_)
|
1028
|
+
gate2_.wait(lk);
|
1029
|
+
}
|
1030
|
+
|
1031
|
+
bool
|
1032
|
+
upgrade_mutex::try_unlock_upgrade_and_lock()
|
1033
|
+
{
|
1034
|
+
boost::unique_lock<mutex_t> lk(mut_);
|
1035
|
+
if (state_ == (upgradable_entered_ | 1))
|
1036
|
+
{
|
1037
|
+
state_ = write_entered_;
|
1038
|
+
return true;
|
1039
|
+
}
|
1040
|
+
return false;
|
1041
|
+
}
|
1042
|
+
|
1043
|
+
void
|
1044
|
+
upgrade_mutex::unlock_and_lock_upgrade()
|
1045
|
+
{
|
1046
|
+
{
|
1047
|
+
boost::lock_guard<mutex_t> _(mut_);
|
1048
|
+
state_ = upgradable_entered_ | 1;
|
1049
|
+
}
|
1050
|
+
gate1_.notify_all();
|
1051
|
+
}
|
1052
|
+
|
1053
|
+
} // thread_v2
|
1054
|
+
} // boost
|
1055
|
+
|
1056
|
+
namespace boost {
|
1057
|
+
//using thread_v2::shared_mutex;
|
1058
|
+
using thread_v2::upgrade_mutex;
|
1059
|
+
typedef thread_v2::upgrade_mutex shared_mutex;
|
1060
|
+
}
|
1061
|
+
|
1062
|
+
#endif
|