summaryrefslogtreecommitdiff
path: root/libs/thread
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2013-08-26 08:15:55 -0400
committerAnas Nashif <anas.nashif@intel.com>2013-08-26 08:15:55 -0400
commitbb4dd8289b351fae6b55e303f189127a394a1edd (patch)
tree77c9c35a31b1459dd7988c2448e797d142530c41 /libs/thread
parent1a78a62555be32868418fe52f8e330c9d0f95d5a (diff)
downloadboost-bb4dd8289b351fae6b55e303f189127a394a1edd.tar.gz
boost-bb4dd8289b351fae6b55e303f189127a394a1edd.tar.bz2
boost-bb4dd8289b351fae6b55e303f189127a394a1edd.zip
Imported Upstream version 1.51.0upstream/1.51.0
Diffstat (limited to 'libs/thread')
-rw-r--r--libs/thread/build/Jamfile.v284
-rw-r--r--libs/thread/doc/Jamfile.v29
-rw-r--r--libs/thread/doc/changes.qbk128
-rw-r--r--libs/thread/doc/compliance.qbk118
-rw-r--r--libs/thread/doc/condition_variables.qbk283
-rw-r--r--libs/thread/doc/configuration.qbk217
-rw-r--r--libs/thread/doc/emulations.qbk365
-rw-r--r--libs/thread/doc/future_ref.qbk352
-rwxr-xr-xlibs/thread/doc/futures.qbk2
-rw-r--r--libs/thread/doc/mutex_concepts.qbk1140
-rw-r--r--libs/thread/doc/mutexes.qbk31
-rw-r--r--libs/thread/doc/once.qbk29
-rw-r--r--libs/thread/doc/overview.qbk25
-rw-r--r--libs/thread/doc/shared_mutex_ref.qbk107
-rw-r--r--libs/thread/doc/sync_tutorial.qbk14
-rw-r--r--libs/thread/doc/thread.qbk86
-rw-r--r--libs/thread/doc/thread_ref.qbk759
-rw-r--r--libs/thread/doc/time.qbk23
-rw-r--r--libs/thread/example/condition.cpp2
-rw-r--r--libs/thread/example/monitor.cpp3
-rw-r--r--libs/thread/example/once.cpp11
-rw-r--r--libs/thread/example/shared_monitor.cpp143
-rw-r--r--libs/thread/example/shared_mutex.cpp745
-rw-r--r--libs/thread/example/starvephil.cpp10
-rw-r--r--libs/thread/example/tennis.cpp4
-rw-r--r--libs/thread/example/thread.cpp6
-rw-r--r--libs/thread/example/thread_group.cpp4
-rw-r--r--libs/thread/example/tss.cpp4
-rw-r--r--libs/thread/example/xtime.cpp6
-rwxr-xr-xlibs/thread/src/future.cpp61
-rw-r--r--libs/thread/src/pthread/once.cpp27
-rw-r--r--libs/thread/src/pthread/thread.cpp159
-rw-r--r--libs/thread/src/pthread/timeconv.inl16
-rw-r--r--libs/thread/src/win32/thread.cpp140
-rw-r--r--libs/thread/src/win32/timeconv.inl16
-rw-r--r--libs/thread/src/win32/tss_pe.cpp8
-rw-r--r--libs/thread/test/Jamfile.v2537
-rw-r--r--libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp14
-rw-r--r--libs/thread/test/no_implicit_move_from_lvalue_thread.cpp14
-rw-r--r--libs/thread/test/sync/conditions/condition_variable/assign_fail.cpp39
-rw-r--r--libs/thread/test/sync/conditions/condition_variable/copy_fail.cpp38
-rw-r--r--libs/thread/test/sync/conditions/condition_variable/default_pass.cpp27
-rw-r--r--libs/thread/test/sync/conditions/condition_variable/dtor_pass.cpp69
-rw-r--r--libs/thread/test/sync/conditions/condition_variable/native_handle_pass.cpp37
-rw-r--r--libs/thread/test/sync/conditions/condition_variable/wait_for_pass.cpp95
-rw-r--r--libs/thread/test/sync/conditions/condition_variable/wait_for_pred_pass.cpp110
-rw-r--r--libs/thread/test/sync/conditions/condition_variable/wait_until_pass.cpp108
-rw-r--r--libs/thread/test/sync/conditions/condition_variable/wait_until_pred_pass.cpp122
-rw-r--r--libs/thread/test/sync/conditions/condition_variable_any/assign_fail.cpp38
-rw-r--r--libs/thread/test/sync/conditions/condition_variable_any/copy_fail.cpp38
-rw-r--r--libs/thread/test/sync/conditions/condition_variable_any/default_pass.cpp28
-rw-r--r--libs/thread/test/sync/conditions/condition_variable_any/dtor_pass.cpp69
-rw-r--r--libs/thread/test/sync/conditions/condition_variable_any/wait_for_pass.cpp99
-rw-r--r--libs/thread/test/sync/conditions/condition_variable_any/wait_for_pred_pass.cpp111
-rw-r--r--libs/thread/test/sync/conditions/condition_variable_any/wait_until_pass.cpp112
-rw-r--r--libs/thread/test/sync/conditions/condition_variable_any/wait_until_pred_pass.cpp126
-rw-r--r--libs/thread/test/sync/conditions/cv_status/cv_status_pass.cpp60
-rw-r--r--libs/thread/test/sync/futures/async/async_pass.cpp186
-rwxr-xr-xlibs/thread/test/sync/futures/future/copy_assign_fail.cpp48
-rw-r--r--libs/thread/test/sync/futures/future/copy_ctor_fail.cpp46
-rwxr-xr-xlibs/thread/test/sync/futures/future/default_pass.cpp45
-rwxr-xr-xlibs/thread/test/sync/futures/future/dtor_pass.cpp109
-rwxr-xr-xlibs/thread/test/sync/futures/future/get_pass.cpp171
-rwxr-xr-xlibs/thread/test/sync/futures/future/move_assign_pass.cpp87
-rwxr-xr-xlibs/thread/test/sync/futures/future/move_ctor_pass.cpp78
-rw-r--r--libs/thread/test/sync/futures/future/share_pass.cpp84
-rw-r--r--libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp149
-rwxr-xr-xlibs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp57
-rw-r--r--libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp57
-rw-r--r--libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp36
-rwxr-xr-xlibs/thread/test/sync/futures/packaged_task/dtor_pass.cpp75
-rw-r--r--libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp127
-rwxr-xr-xlibs/thread/test/sync/futures/packaged_task/get_future_pass.cpp75
-rwxr-xr-xlibs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp69
-rwxr-xr-xlibs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp63
-rwxr-xr-xlibs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp59
-rwxr-xr-xlibs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp59
-rw-r--r--libs/thread/test/sync/futures/packaged_task/operator_pass.cpp126
-rw-r--r--libs/thread/test/sync/futures/packaged_task/reset_pass.cpp75
-rwxr-xr-xlibs/thread/test/sync/futures/packaged_task/types_pass.cpp36
-rw-r--r--libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp48
-rw-r--r--libs/thread/test/sync/futures/promise/alloc_ctor_pass.cpp67
-rwxr-xr-xlibs/thread/test/sync/futures/promise/copy_assign_fail.cpp43
-rw-r--r--libs/thread/test/sync/futures/promise/copy_ctor_fail.cpp42
-rwxr-xr-xlibs/thread/test/sync/futures/promise/default_pass.cpp49
-rwxr-xr-xlibs/thread/test/sync/futures/promise/dtor_pass.cpp116
-rwxr-xr-xlibs/thread/test/sync/futures/promise/get_future_pass.cpp64
-rwxr-xr-xlibs/thread/test/sync/futures/promise/move_assign_pass.cpp155
-rwxr-xr-xlibs/thread/test/sync/futures/promise/move_ctor_pass.cpp151
-rw-r--r--libs/thread/test/sync/futures/promise/use_allocator_pass.cpp47
-rw-r--r--libs/thread/test/sync/futures/test_allocator.hpp158
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp72
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp45
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp44
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/lock_guard/default_pass.cpp72
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/lock_guard/types_pass.cpp39
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp41
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp40
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp33
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp52
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp37
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp49
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp48
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp33
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp35
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp79
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp82
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp47
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp65
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp64
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp76
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp77
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp102
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp114
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp78
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp74
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp76
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp69
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp48
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp47
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp58
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp38
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp38
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp39
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock/types_pass.cpp40
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp75
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp45
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp44
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp74
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp40
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp36
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp49
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp48
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp33
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp35
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp85
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp52
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp63
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp69
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp66
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp69
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp67
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp63
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp64
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp67
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp78
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp84
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp104
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp115
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp85
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp73
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp84
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp69
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp48
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp47
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp58
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp38
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp48
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp47
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp39
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/types_pass.cpp39
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp37
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp49
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp48
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp33
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp35
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp80
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp66
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp46
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp69
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp66
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp69
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp46
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp76
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp79
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp103
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp114
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp78
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp74
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp76
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp69
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp48
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp47
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp58
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp38
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp38
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp39
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp40
-rw-r--r--libs/thread/test/sync/mutual_exclusion/mutex/assign_fail.cpp39
-rw-r--r--libs/thread/test/sync/mutual_exclusion/mutex/copy_fail.cpp39
-rw-r--r--libs/thread/test/sync/mutual_exclusion/mutex/default_pass.cpp29
-rw-r--r--libs/thread/test/sync/mutual_exclusion/mutex/lock_pass.cpp71
-rw-r--r--libs/thread/test/sync/mutual_exclusion/mutex/native_handle_pass.cpp36
-rw-r--r--libs/thread/test/sync/mutual_exclusion/mutex/try_lock_pass.cpp79
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_mutex/assign_fail.cpp39
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_mutex/copy_fail.cpp39
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_mutex/default_pass.cpp29
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_mutex/lock_pass.cpp76
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp37
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp84
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp39
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp39
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp29
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp77
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp36
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp84
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp85
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp80
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/shared_mutex/assign_fail.cpp39
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/shared_mutex/copy_fail.cpp41
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/shared_mutex/default_pass.cpp29
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/shared_mutex/lock_pass.cpp69
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp74
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp78
-rwxr-xr-xlibs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp74
-rw-r--r--libs/thread/test/sync/mutual_exclusion/timed_mutex/assign_fail.cpp40
-rw-r--r--libs/thread/test/sync/mutual_exclusion/timed_mutex/copy_fail.cpp39
-rw-r--r--libs/thread/test/sync/mutual_exclusion/timed_mutex/default_pass.cpp29
-rw-r--r--libs/thread/test/sync/mutual_exclusion/timed_mutex/lock_pass.cpp71
-rw-r--r--libs/thread/test/sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp37
-rw-r--r--libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp80
-rw-r--r--libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp80
-rw-r--r--libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp80
-rwxr-xr-xlibs/thread/test/test_2309.cpp82
-rw-r--r--libs/thread/test/test_2501.cpp1
-rw-r--r--libs/thread/test/test_2741.cpp98
-rw-r--r--libs/thread/test/test_4521.cpp4
-rw-r--r--libs/thread/test/test_4648.cpp4
-rw-r--r--libs/thread/test/test_4882.cpp4
-rw-r--r--libs/thread/test/test_5351.cpp2
-rw-r--r--libs/thread/test/test_5502.cpp8
-rw-r--r--libs/thread/test/test_5542_1.cpp22
-rw-r--r--libs/thread/test/test_5542_3.cpp2
-rwxr-xr-xlibs/thread/test/test_5891.cpp33
-rw-r--r--libs/thread/test/test_6130.cpp34
-rw-r--r--libs/thread/test/test_6170.cpp12
-rw-r--r--libs/thread/test/test_6174.cpp31
-rw-r--r--libs/thread/test/test_barrier.cpp17
-rw-r--r--libs/thread/test/test_condition.cpp17
-rw-r--r--libs/thread/test/test_condition_notify_all.cpp21
-rw-r--r--libs/thread/test/test_condition_notify_one.cpp31
-rw-r--r--libs/thread/test/test_condition_timed_wait_times_out.cpp25
-rw-r--r--libs/thread/test/test_futures.cpp459
-rw-r--r--libs/thread/test/test_generic_locks.cpp95
-rw-r--r--libs/thread/test/test_hardware_concurrency.cpp15
-rw-r--r--libs/thread/test/test_lock_concept.cpp78
-rwxr-xr-xlibs/thread/test/test_ml.cpp196
-rw-r--r--libs/thread/test/test_move_function.cpp23
-rw-r--r--libs/thread/test/test_mutex.cpp31
-rw-r--r--libs/thread/test/test_once.cpp25
-rw-r--r--libs/thread/test/test_shared_mutex.cpp29
-rw-r--r--libs/thread/test/test_shared_mutex_part_2.cpp31
-rw-r--r--libs/thread/test/test_shared_mutex_timed_locks.cpp19
-rw-r--r--libs/thread/test/test_shared_mutex_timed_locks_chrono.cpp288
-rw-r--r--libs/thread/test/test_thread.cpp36
-rw-r--r--libs/thread/test/test_thread_exit.cpp23
-rw-r--r--libs/thread/test/test_thread_id.cpp21
-rw-r--r--libs/thread/test/test_thread_launching.cpp40
-rw-r--r--libs/thread/test/test_thread_move.cpp16
-rw-r--r--libs/thread/test/test_thread_move_return.cpp19
-rw-r--r--libs/thread/test/test_thread_return_local.cpp21
-rw-r--r--libs/thread/test/test_tss.cpp28
-rw-r--r--libs/thread/test/test_xtime.cpp28
-rw-r--r--libs/thread/test/threads/container/thread_ptr_list_pass.cpp101
-rw-r--r--libs/thread/test/threads/container/thread_vector_pass.cpp88
-rw-r--r--libs/thread/test/threads/this_thread/get_id/get_id_pass.cpp28
-rw-r--r--libs/thread/test/threads/this_thread/sleep_for/sleep_for_pass.cpp48
-rw-r--r--libs/thread/test/threads/this_thread/sleep_until/sleep_until_pass.cpp48
-rw-r--r--libs/thread/test/threads/thread/assign/copy_fail.cpp80
-rw-r--r--libs/thread/test/threads/thread/assign/move_pass.cpp102
-rw-r--r--libs/thread/test/threads/thread/constr/FArgs_pass.cpp143
-rw-r--r--libs/thread/test/threads/thread/constr/F_pass.cpp148
-rw-r--r--libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp47
-rw-r--r--libs/thread/test/threads/thread/constr/Frvalue_pass.cpp54
-rw-r--r--libs/thread/test/threads/thread/constr/copy_fail.cpp95
-rw-r--r--libs/thread/test/threads/thread/constr/default_pass.cpp30
-rw-r--r--libs/thread/test/threads/thread/constr/move_pass.cpp94
-rw-r--r--libs/thread/test/threads/thread/destr/dtor_pass.cpp81
-rw-r--r--libs/thread/test/threads/thread/id/hash_pass.cpp40
-rw-r--r--libs/thread/test/threads/thread/members/detach_pass.cpp75
-rw-r--r--libs/thread/test/threads/thread/members/get_id_pass.cpp73
-rw-r--r--libs/thread/test/threads/thread/members/join_pass.cpp151
-rw-r--r--libs/thread/test/threads/thread/members/joinable_pass.cpp71
-rw-r--r--libs/thread/test/threads/thread/members/native_handle_pass.cpp71
-rw-r--r--libs/thread/test/threads/thread/members/swap_pass.cpp73
-rw-r--r--libs/thread/test/threads/thread/non_members/swap_pass.cpp72
-rw-r--r--libs/thread/test/threads/thread/static/hardware_concurrency_pass.cpp28
-rw-r--r--libs/thread/test/util.inl56
-rw-r--r--libs/thread/tutorial/helloworld4.cpp20
289 files changed, 20402 insertions, 1067 deletions
diff --git a/libs/thread/build/Jamfile.v2 b/libs/thread/build/Jamfile.v2
index af14ccd06e..5e2f3ed43d 100644
--- a/libs/thread/build/Jamfile.v2
+++ b/libs/thread/build/Jamfile.v2
@@ -1,6 +1,7 @@
-# $Id: Jamfile.v2 66171 2010-10-25 07:52:02Z vladimir_prus $
+# $Id: Jamfile.v2 79373 2012-07-09 05:55:01Z viboes $
# Copyright 2006-2007 Roland Schwarz.
# Copyright 2007 Anthony Williams
+# Copyright 2011-2012 Vicente J.Botet Escriba.
# Distributed under the Boost Software License, Version 1.0. (See
# accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
@@ -39,12 +40,66 @@ import path ;
project boost/thread
: source-location ../src
: requirements <threading>multi
+ #<link>static:<define>BOOST_THREAD_STATIC_LINK=1
+ #<link>shared:<define>BOOST_THREAD_DYN_LINK=1
<link>static:<define>BOOST_THREAD_BUILD_LIB=1
<link>shared:<define>BOOST_THREAD_BUILD_DLL=1
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(__name__).tag
<toolset>gcc:<cxxflags>-Wno-long-long
- : default-build <threading>multi
+ <define>BOOST_SYSTEM_NO_DEPRECATED
+ <library>/boost/system//boost_system
+ #-pedantic -ansi -std=gnu++0x -Wextra -fpermissive
+ <warnings>all
+ <toolset>gcc:<cxxflags>-Wextra
+ <toolset>gcc:<cxxflags>-pedantic
+ <toolset>gcc:<cxxflags>-Wno-long-long
+ #<toolset>gcc:<cxxflags>-ansi
+ #<toolset>gcc:<cxxflags>-fpermissive
+
+ <toolset>darwin:<cxxflags>-Wextra
+ <toolset>darwin:<cxxflags>-pedantic
+ <toolset>darwin:<cxxflags>-ansi
+ <toolset>darwin:<cxxflags>-fpermissive
+ <toolset>darwin:<cxxflags>-Wno-long-long
+
+ #<toolset>pathscale:<cxxflags>-Wextra
+ <toolset>pathscale:<cxxflags>-Wno-long-long
+ <toolset>pathscale:<cxxflags>-pedantic
+
+ <toolset>clang:<cxxflags>-Wextra
+ <toolset>clang:<cxxflags>-pedantic
+ <toolset>clang:<cxxflags>-ansi
+ #<toolset>clang:<cxxflags>-fpermissive
+ <toolset>clang:<cxxflags>-Wno-long-long
+
+ <toolset>gcc-mingw-4.4.0:<cxxflags>-fdiagnostics-show-option
+ <toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option
+ <toolset>gcc-mingw-4.6.0:<cxxflags>-fdiagnostics-show-option
+ <toolset>gcc-mingw-4.6.3:<cxxflags>-fdiagnostics-show-option
+ <toolset>gcc-mingw-4.7.0:<cxxflags>-fdiagnostics-show-option
+ <toolset>gcc-mingw-4.8.0:<cxxflags>-fdiagnostics-show-option
+
+ <toolset>darwin-4.6.2:<cxxflags>-Wno-delete-non-virtual-dtor
+ <toolset>darwin-4.7.0:<cxxflags>-Wno-delete-non-virtual-dtor
+
+ #<toolset>clang-2.8:<cxxflags>-Wno-delete-non-virtual-dtor
+ #<toolset>clang-2.8:<cxxflags>-Wno-unused-function
+ #<toolset>clang-2.9:<cxxflags>-Wno-delete-non-virtual-dtor
+ #<toolset>clang-2.9:<cxxflags>-Wno-unused-function
+ <toolset>clang-3.0:<cxxflags>-Wno-delete-non-virtual-dtor
+ #<toolset>clang-3.0:<cxxflags>-Wno-unused-function
+ #<toolset>clang-3.0:<cxxflags>-Wno-unused-variable
+
+
+ # : default-build <threading>multi
+ : usage-requirements # pass these requirement to dependents (i.e. users)
+ #<link>static:<define>BOOST_THREAD_STATIC_LINK=1
+ #<link>shared:<define>BOOST_THREAD_DYN_LINK=1
+ <link>static:<define>BOOST_THREAD_BUILD_LIB=1
+ <link>shared:<define>BOOST_THREAD_BUILD_DLL=1
+ <define>BOOST_SYSTEM_NO_DEPRECATED
+ <library>/boost/system//boost_system
;
local rule default_threadapi ( )
@@ -60,19 +115,19 @@ feature.set-default threadapi : [ default_threadapi ] ;
rule tag ( name : type ? : property-set )
{
local result = $(name) ;
-
+
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
{
local api = [ $(property-set).get <threadapi> ] ;
-
+
# non native api gets additional tag
if $(api) != [ default_threadapi ] {
result = $(result)_$(api) ;
}
}
-
+
# forward to the boost tagging rule
- return [ indirect.call $(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
+ return [ indirect.call $(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
$(result) : $(type) : $(property-set) ] ;
}
@@ -130,7 +185,7 @@ rule win32_pthread_paths ( properties * )
.notified = true ;
}
}
- else
+ else
{
result += <include>$(include_path) ;
result += <library>$(lib_path) ;
@@ -152,6 +207,12 @@ rule usage-requirements ( properties * )
# in that case?
}
}
+
+ if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties)
+ {
+ result += <library>/boost/chrono//boost_chrono ;
+ }
+
return $(result) ;
}
@@ -162,7 +223,7 @@ rule requirements ( properties * )
if <threadapi>pthread in $(properties)
{
result += <define>BOOST_THREAD_POSIX ;
- if <target-os>windows in $(properties)
+ if <target-os>windows in $(properties)
{
local paths = [ win32_pthread_paths $(properties) ] ;
if $(paths)
@@ -175,6 +236,11 @@ rule requirements ( properties * )
}
}
}
+ if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties)
+ {
+ result += <library>/boost/chrono//boost_chrono ;
+ }
+
return $(result) ;
}
@@ -198,7 +264,7 @@ alias thread_sources
explicit thread_sources ;
lib boost_thread
- : thread_sources
+ : thread_sources future.cpp
: <conditional>@requirements
:
: <link>shared:<define>BOOST_THREAD_USE_DLL=1
diff --git a/libs/thread/doc/Jamfile.v2 b/libs/thread/doc/Jamfile.v2
index 9e5f8e3f5b..adc8cbbb5e 100644
--- a/libs/thread/doc/Jamfile.v2
+++ b/libs/thread/doc/Jamfile.v2
@@ -1,4 +1,5 @@
-# (C) Copyright 2008 Anthony Williams
+# (C) Copyright 2008-11 Anthony Williams
+# (C) Copyright 2011-12 Vicente J. Botet Escriba
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -15,13 +16,13 @@ boostbook standalone
# Use graphics not text for navigation:
<xsl:param>navig.graphics=1
# How far down we chunk nested sections, basically all of them:
- <xsl:param>chunk.section.depth=3
+ <xsl:param>chunk.section.depth=2
# Don't put the first section on the same page as the TOC:
<xsl:param>chunk.first.sections=1
# How far down sections get TOC's
- <xsl:param>toc.section.depth=10
+ <xsl:param>toc.section.depth=4
# Max depth in each TOC:
- <xsl:param>toc.max.depth=3
+ <xsl:param>toc.max.depth=2
# How far down we go with TOC's
<xsl:param>generate.section.toc.level=10
# Path for links to Boost:
diff --git a/libs/thread/doc/changes.qbk b/libs/thread/doc/changes.qbk
index 809ed89749..9997c6778d 100644
--- a/libs/thread/doc/changes.qbk
+++ b/libs/thread/doc/changes.qbk
@@ -1,13 +1,106 @@
[/
- (C) Copyright 2007-8 Anthony Williams.
+ (C) Copyright 2007-11 Anthony Williams.
+ (C) Copyright 2011-12 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
]
-[section:changes Changes since]
+[section:changes History]
-[heading Changes since boost 1.41]
+[heading Version 3.0.1 - boost 1.51]
+
+Deprecated features since boost 1.50 available only until boost 1.55:
+
+These deprecated features will be provided by default up to boost 1.52. If you don't want to include the deprecated features you could define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0. Since 1.53 these features will not be included any more by default. Since this version, if you want to include the deprecated features yet you could define BOOST_THREAD_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0. These deprecated features will be only available until boost 1.55, that is you have 1 year and a half to move to the new features.
+
+* Time related functions don't using the Boost.Chrono library, use the chrono overloads instead.
+
+Breaking changes when BOOST_THREAD_VERSION==3:
+
+There are some new features which share the same interface but with different behavior. These breaking features are provided by default when BOOST_THREAD_VERSION is 3, but the user can however choose the version 2 behavior by defining the corresponding macro. As for the deprecated features, these broken features will be only available until boost 1.55.
+
+* [@http://svn.boost.org/trac/boost/ticket/6229 #6229] Rename the unique_future to future following the c++11.
+* [@http://svn.boost.org/trac/boost/ticket/6266 #6266] Breaking change: thread destructor should call terminate if joinable.
+* [@http://svn.boost.org/trac/boost/ticket/6269 #6269] Breaking change: thread move assignment should call terminate if joinable.
+
+
+Fixed Bugs:
+
+
+* [@http://svn.boost.org/trac/boost/ticket/4258 #4258] Linking with boost thread does not work on mingw/gcc 4.5.
+* [@http://svn.boost.org/trac/boost/ticket/4885 #4885] Access violation in set_tss_data at process exit due to invalid assumption about TlsAlloc.
+* [@http://svn.boost.org/trac/boost/ticket/6931 #6931] mutex waits forwever with Intel Compiler and /debug:parallel
+* [@http://svn.boost.org/trac/boost/ticket/7044 #7044] boost 1.50.0 header missing.
+* [@http://svn.boost.org/trac/boost/ticket/7052 #7052] Thread: BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 only masks thread::operator==, thread::operator!= forward declarations, not definitions.
+* [@http://svn.boost.org/trac/boost/ticket/7066 #7066] An attempt to fix current_thread_tls_key static initialization order.
+* [@http://svn.boost.org/trac/boost/ticket/7074 #7074] Multiply defined symbol boost::allocator_arg.
+* [@http://svn.boost.org/trac/boost/ticket/7078 #7078] Trivial 64-bit warning fix on Windows for thread attribute stack size
+* [@http://svn.boost.org/trac/boost/ticket/7089 #7089] BOOST_THREAD_WAIT_BUG limits functionality without solving anything
+
+
+[heading Version 3.0.0 - boost 1.50]
+
+Breaking changes when BOOST_THREAD_VERSION==3:
+
+* [@http://svn.boost.org/trac/boost/ticket/6229 #6229] Breaking change: Rename the unique_future to future following the c++11.
+* [@http://svn.boost.org/trac/boost/ticket/6266 #6266] Breaking change: thread destructor should call terminate if joinable.
+* [@http://svn.boost.org/trac/boost/ticket/6269 #6269] Breaking change: thread move assignment should call terminate if joinable.
+
+New Features:
+
+* [@http://svn.boost.org/trac/boost/ticket/1850 #1850] Request for unlock_guard to compliment lock_guard.
+* [@http://svn.boost.org/trac/boost/ticket/2637 #2637] Request for shared_mutex duration timed_lock and timed_lock_shared.
+* [@http://svn.boost.org/trac/boost/ticket/2741 #2741] Proposal to manage portable and non portable thread attributes.
+* [@http://svn.boost.org/trac/boost/ticket/3567 #3567] Request for shared_lock_guard.
+* [@http://svn.boost.org/trac/boost/ticket/6194 #6194] Adapt to Boost.Move.
+* [@http://svn.boost.org/trac/boost/ticket/6195 #6195] c++11 compliance: Provide the standard time related interface using Boost.Chrono.
+* [@http://svn.boost.org/trac/boost/ticket/6217 #6217] Enhance Boost.Thread shared mutex interface following Howard Hinnant proposal.
+* [@http://svn.boost.org/trac/boost/ticket/6224 #6224] c++11 compliance: Add the use of standard noexcept on compilers supporting them.
+* [@http://svn.boost.org/trac/boost/ticket/6225 #6225] Add the use of standard =delete defaulted operations on compilers supporting them.
+* [@http://svn.boost.org/trac/boost/ticket/6226 #6226] c++11 compliance: Add explicit bool conversion from locks.
+* [@http://svn.boost.org/trac/boost/ticket/6228 #6228] Add promise constructor with allocator following the standard c++11.
+* [@http://svn.boost.org/trac/boost/ticket/6230 #6230] c++11 compliance: Follows the exception reporting mechanism as defined in the c++11.
+* [@http://svn.boost.org/trac/boost/ticket/6231 #6231] Add BasicLockable requirements in the documentation to follow c++11.
+* [@http://svn.boost.org/trac/boost/ticket/6272 #6272] c++11 compliance: Add thread::id hash specialization.
+* [@http://svn.boost.org/trac/boost/ticket/6273 #6273] c++11 compliance: Add cv_status enum class and use it on the conditions wait functions.
+* [@http://svn.boost.org/trac/boost/ticket/6342 #6342] c++11 compliance: Adapt the one_flag to the c++11 interface.
+* [@http://svn.boost.org/trac/boost/ticket/6671 #6671] upgrade_lock: missing mutex and release functions.
+* [@http://svn.boost.org/trac/boost/ticket/6672 #6672] upgrade_lock:: missing constructors from time related types.
+* [@http://svn.boost.org/trac/boost/ticket/6675 #6675] upgrade_lock:: missing non-member swap.
+* [@http://svn.boost.org/trac/boost/ticket/6676 #6676] lock conversion should be explicit.
+* Added missing packaged_task::result_type and packaged_task:: constructor with allocator.
+* Added packaged_task::reset()
+
+
+Fixed Bugs:
+
+* [@http://svn.boost.org/trac/boost/ticket/2380 #2380] boost::move from lvalue does not work with gcc.
+* [@http://svn.boost.org/trac/boost/ticket/2430 #2430] shared_mutex for win32 doesn't have timed_lock_upgrade.
+* [@http://svn.boost.org/trac/boost/ticket/2575 #2575] Bug- Boost 1.36.0 on Itanium platform.
+* [@http://svn.boost.org/trac/boost/ticket/3160 #3160] Duplicate tutorial code in boost::thread.
+* [@http://svn.boost.org/trac/boost/ticket/4345 #4345] thread::id and joining problem with cascade of threads.
+* [@http://svn.boost.org/trac/boost/ticket/4521 #4521] Error using boost::move on packaged_task (MSVC 10).
+* [@http://svn.boost.org/trac/boost/ticket/4711 #4711] Must use implementation details to return move-only types.
+* [@http://svn.boost.org/trac/boost/ticket/4921 #4921] BOOST_THREAD_USE_DLL and BOOST_THREAD_USE_LIB are crucial and need to be documented.
+* [@http://svn.boost.org/trac/boost/ticket/5013 #5013] documentation: boost::thread: pthreas_exit causes terminate().
+* [@http://svn.boost.org/trac/boost/ticket/5173 #5173] boost::this_thread::get_id is very slow.
+* [@http://svn.boost.org/trac/boost/ticket/5351 #5351] interrupt a future get boost::unknown_exception.
+* [@http://svn.boost.org/trac/boost/ticket/5516 #5516] Upgrade lock is not acquired when previous upgrade lock releases if another read lock is present.
+* [@http://svn.boost.org/trac/boost/ticket/5990 #5990] shared_future<T>::get() has wrong return type.
+* [@http://svn.boost.org/trac/boost/ticket/6174 #6174] packaged_task doesn't correctly handle moving results.
+* [@http://svn.boost.org/trac/boost/ticket/6222 #6222] Compile error with SunStudio: unique_future move.
+* [@http://svn.boost.org/trac/boost/ticket/6354 #6354] PGI: Compiler threading support is not turned on.
+* [@http://svn.boost.org/trac/boost/ticket/6673 #6673] shared_lock: move assign doesn't works with c++11.
+* [@http://svn.boost.org/trac/boost/ticket/6674 #6674] shared_mutex: try_lock_upgrade_until doesn't works.
+* [@http://svn.boost.org/trac/boost/ticket/6908 #6908] Compile error due to unprotected definitions of _WIN32_WINNT and WINVER.
+* [@http://svn.boost.org/trac/boost/ticket/6940 #6940] TIME_UTC is a macro in C11.
+* [@http://svn.boost.org/trac/boost/ticket/6959 #6959] call of abs is ambiguous.
+* Fix issue signaled on the ML with task_object(task_object const&) in presence of task_object(task_object &&)
+
+
+
+[heading Version 2.1.1 - boost 1.49]
Fixed Bugs:
@@ -24,10 +117,7 @@ Fixed Bugs:
* [@http://svn.boost.org/trac/boost/ticket/4480 #4480] OpenVMS patches for compiler issues workarounds.
* [@http://svn.boost.org/trac/boost/ticket/4819 #4819] boost.thread's documentation misprints.
-* [@http://svn.boost.org/trac/boost/ticket/5040 #5040] future.hpp in boost::thread does not compile with /clr.
* [@http://svn.boost.org/trac/boost/ticket/5423 #5423] thread issues with C++0x.
-* [@http://svn.boost.org/trac/boost/ticket/5502 #5502] race condition between shared_mutex timed_lock and lock_shared.
-* [@http://svn.boost.org/trac/boost/ticket/5594 #5594] boost::shared_mutex not fully compatible with Windows CE.
* [@http://svn.boost.org/trac/boost/ticket/5617 #5617] boost::thread::id copy ctor.
* [@http://svn.boost.org/trac/boost/ticket/5739 #5739] set-but-not-used warnings with gcc-4.6.
* [@http://svn.boost.org/trac/boost/ticket/5826 #5826] threads.cpp: resource leak on threads creation failure.
@@ -35,15 +125,13 @@ Fixed Bugs:
* [@http://svn.boost.org/trac/boost/ticket/5859 #5859] win32 shared_mutex constructor leaks on exceptions.
* [@http://svn.boost.org/trac/boost/ticket/6100 #6100] Compute hardware_concurrency() using get_nprocs() on GLIBC systems.
-* [@http://svn.boost.org/trac/boost/ticket/6141 #6141] Compilation error when boost.thread and boost.move are used together.
* [@http://svn.boost.org/trac/boost/ticket/6168 #6168] recursive_mutex is using wrong config symbol (possible typo).
* [@http://svn.boost.org/trac/boost/ticket/6175 #6175] Compile error with SunStudio.
* [@http://svn.boost.org/trac/boost/ticket/6200 #6200] patch to have condition_variable and mutex error better handle EINTR.
* [@http://svn.boost.org/trac/boost/ticket/6207 #6207] shared_lock swap compiler error on clang 3.0 c++11.
* [@http://svn.boost.org/trac/boost/ticket/6208 #6208] try_lock_wrapper swap compiler error on clang 3.0 c++11.
-
-[heading Changes since boost 1.40]
+[heading Version 2.1.0 - Changes since boost 1.40]
The 1.41.0 release of Boost adds futures to the thread library. There are also a few minor changes.
@@ -63,7 +151,7 @@ The 1.36.0 release of Boost includes a few new features in the thread library:
* Backwards-compatibility overloads added for `timed_lock` and `timed_wait` functions to allow use of `xtime` for timeouts.
-[heading Changes since boost 1.34]
+[heading Version 2.0.0 - Changes since boost 1.34]
Almost every line of code in __boost_thread__ has been changed since the 1.34 release of boost. However, most of the interface
changes have been extensions, so the new code is largely backwards-compatible with the old code. The new features and breaking
@@ -126,19 +214,15 @@ been moved to __thread_id__.
[section:future Future]
-The following features will be included in next releases. By order of priority:
+The following features will be included in next releases.
+
+# Complete the C++11 missing features, in particular
+
+ * [@http://svn.boost.org/trac/boost/ticket/4710 #4710] Missing async().
+ * [@http://svn.boost.org/trac/boost/ticket/6227 #6227] Use of variadic templates on Generic Locking Algorithms on compilers providing them.
+ * [@http://svn.boost.org/trac/boost/ticket/6270 #6270] Add thread constructor from movable callable and movable arguments following C++11.
+
-* [@http://svn.boost.org/trac/boost/ticket/6194 #6194] Adapt to Boost.Move.
-* [@http://svn.boost.org/trac/boost/ticket/4710 #4710] Missing async().
-* [@http://svn.boost.org/trac/boost/ticket/6195 #6195] Provide the standard time related interface using Boost.Chrono.
- * [@http://svn.boost.org/trac/boost/ticket/2637 #2637] shared mutex lock
-* Lock guards
- * [@http://svn.boost.org/trac/boost/ticket/1850 #1850] request for unlock_guard (and/or unique_unlock) to compliment lock_guard/unique_lock
- * [@http://svn.boost.org/trac/boost/ticket/3567 #3567] Request for shared_lock_guard
-* [@http://svn.boost.org/trac/boost/ticket/2741 #2741] Proposal to manage portable and non portable thread attributes.
- * #2880 Request for Thread scheduler support for boost ..
- * #3696 Boost Thread library lacks any way to set priority of threads
- * #5956 Add optional stack_size argument to thread::start_thread()
[endsect]
diff --git a/libs/thread/doc/compliance.qbk b/libs/thread/doc/compliance.qbk
index 2bf923ebd7..6f619c4693 100644
--- a/libs/thread/doc/compliance.qbk
+++ b/libs/thread/doc/compliance.qbk
@@ -1,97 +1,107 @@
[/
- (C) Copyright 2011 Vicente J. Botet Escriba.
+ (C) Copyright 2011-12 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
]
-[section:compliance Compliance with standard]
+[section:compliance Conformance and Extension]
[section:cpp11 C++11 standard Thread library]
-[table Compliance C++11 standard
+[table C++11 standard Conformance
[[Section] [Description] [Status] [Comments] [Ticket]]
[[30] [Thread support library] [Partial] [-] [-]]
[[30.1] [General] [-] [-] [-]]
[[30.2] [Requirements] [-] [-] [-]]
[[30.2.1] [Template parameter names] [-] [-] [-]]
- [[30.2.2] [Exceptions] [No] [-] [#12]]
+ [[30.2.2] [Exceptions] [Yes] [-] [-]]
[[30.2.3] [Native handles] [Yes] [-] [-]]
- [[30.2.4] [Timing specifications] [No] [-] [#6195]]
- [[30.2.5] [Requirements for Lockable types] [Partial] [-] [-]]
+ [[30.2.4] [Timing specifications] [Yes] [-] [-]]
+ [[30.2.5] [Requirements for Lockable types] [Yes] [-] [-]]
[[30.2.5.1] [In general] [-] [-] [-]]
- [[30.2.5.2] [BasicLockable requirements] [No] [-] [#13]]
+ [[30.2.5.2] [BasicLockable requirements] [Yes] [-] [-]]
[[30.2.5.3] [Lockable requirements] [yes] [-] [-]]
- [[30.2.5.4] [TimedLockable requirements] [Partial] [chrono] [#6195]]
+ [[30.2.5.4] [TimedLockable requirements] [Yes] [-] [-]]
[[30.2.6] [decay_copy] [-] [-] [-]]
[[30.3] [Threads] [Partial] [-] [-]]
- [[30.3.1] [Class thread] [Partial] [-] [-]]
- [[30.3.1.1] [Class thread::id] [Partial] [Missing noexcept, template <> struct hash<thread::id>] [#3,#4]]
- [[30.3.1.2] [thread constructors] [Partial] [Missing noexcept and move semantics] [#3,#6194]]
- [[30.3.1.3] [thread destructor] [Yes] [-] [-]]
- [[30.3.1.4] [thread assignment] [Partial] [move semantics] [-]]
- [[30.3.1.5] [thread members] [Partial] [Missing noexcept, chrono] [#3,#6195]]
- [[30.3.1.6] [thread static members] [Partial] [Missing noexcept] [#3,#6195]]
+ [[30.3.1] [Class thread] [Partial] [move,variadic,terminate] [#zzzz,#6270,#6269]]
+ [[30.3.1.1] [Class thread::id] [Yes] [-] [-]]
+ [[30.3.1.2] [thread constructors] [Partial] [move,variadic] [#zzzz,#6270]]
+ [[30.3.1.3] [thread destructor] [Partial] [terminate] [#6266]]
+ [[30.3.1.4] [thread assignment] [Partial] [terminate] [#6269]]
+ [[30.3.1.5] [thread members] [Yes] [-] [-]]
+ [[30.3.1.6] [thread static members] [Yes] [-] [-]]
[[30.3.1.7] [thread specialized algorithms] [Yes] [-] [-]]
- [[30.3.2] [Namespace this_thread] [Partial] [chrono] [#6195]]
+
+ [[30.3.2] [Namespace this_thread] [Yes] [-] [-]]
[[30.4] [Mutual exclusion] [Partial] [-] [-]]
- [[30.4.1] [Mutex requirements] [Partial] [-] [-]]
- [[30.4.1.1] [In general] [Partial] [-] [-]]
- [[30.4.1.2] [Mutex types] [Partial] [noexcept,delete] [#3,#5]]
- [[30.4.1.2.1] [Class mutex] [Partial] [noexcept,delete] [#3,#5]]
- [[30.4.1.2.2] [Class recursive_mutex] [Partial] [noexcept,delete] [#3,#5]]
- [[30.4.1.3] [Timed mutex types] [Partial] [noexcept,chrono,delete] [#3,#6195,#5]]
- [[30.4.1.3.1] [Class timed_mutex] [Partial] [noexcept,chrono,delete] [#3,#6195,#5]]
- [[30.4.1.3.1] [Class recursive_timed_mutex] [Partial] [noexcept,chrono,delete] [#3,#6195,#5]]
- [[30.4.2] [Locks] [Partial] [noexcept,chrono,move,delete,bool] [#3,#6195,#5,#6]]
- [[30.4.2.1] [Class template lock_guard] [Partial] [cons/dest delete] [#5]]
- [[30.4.2.2] [Class template unique_lock] [Partial] [noexcept, chrono, move, delete] [#3,#6195,#5,#6]]
- [[30.4.2.2.1] [unique_lock constructors, destructor, and assignment] [Partial] [noexcept, chrono, move, delete] [#3,#6195,#5,#6]]
- [[30.4.2.2.2] [unique_lock locking] [Partial] [chrono] [,#6195,]]
+ [[30.4.1] [Mutex requirements] [Yes] [-] [-]]
+ [[30.4.1.1] [In general] [Yes] [-] [-]]
+ [[30.4.1.2] [Mutex types] [Yes] [-] [-]]
+ [[30.4.1.2.1] [Class mutex] [Yes] [-] [-]]
+ [[30.4.1.2.2] [Class recursive_mutex] [Yes] [-] [-]]
+ [[30.4.1.3] [Timed mutex types] [Yes] [-] [-]]
+ [[30.4.1.3.1] [Class timed_mutex] [Yes] [-] [-]]
+ [[30.4.1.3.1] [Class recursive_timed_mutex] [Yes] [-] [-]]
+ [[30.4.2] [Locks] [Partial] [variadic] [#6227]]
+ [[30.4.2.1] [Class template lock_guard] [Yes] [-] [-]]
+ [[30.4.2.2] [Class template unique_lock] [Yes] [-] [-]]
+ [[30.4.2.2.1] [unique_lock constructors, destructor, and assignment] [Yes] [-] [-]]
+ [[30.4.2.2.2] [unique_lock locking] [Yes] [-] [-]]
[[30.4.2.2.3] [unique_lock modifiers] [Yes] [-] [-]]
- [[30.4.2.2.4] [unique_lock observers] [Partial] [explicit operator bool] [#6]]
- [[30.4.3] [Generic locking algorithms] [Partial] [Variadic,] [#7]]
- [[30.4.4] [Call once] [Partial] [move,variadic] [#6194,#7]]
- [[30.4.4.1] [Struct once_flag] [Yes] [-] [-]]
- [[30.4.4.2] [Function call_once] [Yes] [-] [-]]
- [[30.5] [Condition variables] [Partial] [chrono,cv_status,notify_all_at_thread_exit] [#6195,#8,#9]]
- [[30.5 6-10] [Function notify_all_at_thread_exit] [No] [-] [#9]]
- [[30.5.1] [Class condition_variable] [Partial] [chrono,cv_status] [#6195,#8]]
- [[30.5.2] [Class condition_variable_any] [Partial] [chrono,cv_status] [#6195,#8]]
+ [[30.4.2.2.4] [unique_lock observers] [Yes] [] [-]]
+ [[30.4.3] [Generic locking algorithms] [Partial] [variadic] [#6227]]
+ [[30.4.4] [Call once] [Partial] [The interface doesn't corresponds] [#6342]]
+ [[30.4.4.1] [Struct once_flag] [Partial] [interface] [#6342]]
+ [[30.4.4.2] [Function call_once] [Partial] [interface] [#6342]]
+ [[30.5] [Condition variables] [Partial] [notify_all_at_thread_exit] [#xxxx]]
+ [[30.5 6-10] [Function notify_all_at_thread_exit] [No] [-] [#xxxx]]
+ [[30.5.1] [Class condition_variable] [Yes] [-] [-]]
+ [[30.5.2] [Class condition_variable_any] [Yes] [-] [-]]
[[30.6] [Futures] [Partial] [-] [-]]
[[30.6.1] [Overview] [Partial] [-] [-]]
- [[30.6.2] [Error handling] [No] [-] [-]]
- [[30.6.3] [Class future_error] [No] [-] [-]]
- [[30.6.4] [Shared state] [No] [-] [-]]
- [[30.6.5] [Class template promise] [Partial] [allocator,move,delete] [#10,#6194,#5]]
- [[30.6.6] [Class template future] [No] [unique_future is the closest to future] [#11]]
- [[30.6.7] [Class template shared_future] [Partial] [allocator,move,delete] [#10,#6194,#5]]
+ [[30.6.2] [Error handling] [Yes] [-] [-]]
+ [[30.6.3] [Class future_error] [Yes] [-] [-]]
+ [[30.6.4] [Shared state] [-] [-] [-]]
+ [[30.6.5] [Class template promise] [Partial] [allocator] [#6228]]
+ [[30.6.6] [Class template future] [Partial] [allocator,unique_future is the closest to future, renamed in V3] [#6228]]
+ [[30.6.7] [Class template shared_future] [Partial] [allocator] [#6228]]
[[30.6.8] [Function template async] [No] [async] [#4710]]
- [[30.6.8] [Class template packaged_task] [Partial] [-] [-]]
+ [[30.6.9] [Class template packaged_task] [Partial] [move] [#yyyy]]
]
-
+[/
[table Extension
[[Section] [Description] [Comments]]
[[30.3.1.5.x] [interrupt] [-]]
- [[30.3.1.5.y] [operator==,operator!=] [-]]
- [[30.3.2.x] [Interruprion] [-]]
+ [[30.3.2.x] [Interruption] [-]]
[[30.3.2.y] [at_thread_exit] [-]]
[[30.4.3.x] [Generic locking algorithms begin/end] [-]]
[[30.x] [Barriers] [-]]
[[30.y] [Thread Local Storage] [-]]
[[30.z] [Class thread_group] [-]]
]
-
+]
[endsect]
-[section:shared Shared Mutex library extension]
-[table Clock Requirements
- [[Section] [Description] [Status] [Comments]]
- [[XXXX] [DDDD] [SSSS] [CCCC]]
- [[XXXX] [DDDD] [SSSS] [CCCC]]
+[section:shared Shared Locking extensions]
+
+[table Howard's Shared Locking Proposal Conformance
+ [[Section] [Description] [Status] [Comments]]
+ [[X] [Shared Locking] [Yes] [Needs `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION]]
+ [[X.1] [Shared Lockables Concepts] [Yes] [ - ]]
+ [[X.1.1] [SharedLockable concept] [Yes] [ - ]]
+ [[X.1.2] [UpgradeLockable concept] [Yes] [ - ]]
+ [[X.2] [Shared Mutex Types] [Yes] [ - ]]
+ [[X.2.1] [shared_mutex class] [Yes] [ - ]]
+ [[X.2.2] [upgrade_mutex class] [Yes] [ - ]]
+ [[X.3] [Locks] [Yes] [-]]
+ [[X.3.1] [unique_lock class adaptations] [Yes] [-]]
+ [[X.3.2] [shared_lock class] [Yes] [ - ]]
+ [[X.3.3] [upgrade_lock class] [Yes] [-]]
]
[endsect]
diff --git a/libs/thread/doc/condition_variables.qbk b/libs/thread/doc/condition_variables.qbk
index e54dd34cc0..77d0b26aed 100644
--- a/libs/thread/doc/condition_variables.qbk
+++ b/libs/thread/doc/condition_variables.qbk
@@ -1,5 +1,6 @@
[/
- (C) Copyright 2007-8 Anthony Williams.
+ (C) Copyright 2007-11 Anthony Williams.
+ (C) Copyright 2011-12 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
@@ -9,6 +10,17 @@
[heading Synopsis]
+ namespace boost
+ {
+ enum class cv_status;
+ {
+ no_timeout,
+ timeout
+ };
+ class condition_variable;
+ class condition_variable_any;
+ }
+
The classes `condition_variable` and `condition_variable_any` provide a
mechanism for one thread to wait for notification from another thread that a
particular condition has become true. The general usage pattern is that one
@@ -84,31 +96,54 @@ optimizations in some cases, based on the knowledge of the mutex type;
condition_variable();
~condition_variable();
- void notify_one();
- void notify_all();
+ void notify_one() noexcept;
+ void notify_all() noexcept;
void wait(boost::unique_lock<boost::mutex>& lock);
template<typename predicate_type>
void wait(boost::unique_lock<boost::mutex>& lock,predicate_type predicate);
+ template <class Clock, class Duration>
+ typename cv_status::type
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<Clock, Duration>& t);
+
+ template <class Clock, class Duration, class Predicate>
+ bool
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred);
+
+ template <class Rep, class Period>
+ typename cv_status::type
+ wait_for(
+ unique_lock<mutex>& lock,
+ const chrono::duration<Rep, Period>& d);
+
+ template <class Rep, class Period, class Predicate>
+ bool
+ wait_for(
+ unique_lock<mutex>& lock,
+ const chrono::duration<Rep, Period>& d,
+ Predicate pred);
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time);
-
template<typename duration_type>
bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time);
-
template<typename predicate_type>
bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time,predicate_type predicate);
-
template<typename duration_type,typename predicate_type>
bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time,predicate_type predicate);
-
- // backwards compatibility
-
bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time);
template<typename predicate_type>
bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time,predicate_type predicate);
+ #endif
+
};
}
@@ -292,6 +327,114 @@ return true;
[endsect]
+[section:wait_until `template <class Clock, class Duration> cv_status wait_until(boost::unique_lock<boost::mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time)`]
+
+[variablelist
+
+[[Precondition:] [`lock` is locked by the current thread, and either no other
+thread is currently waiting on `*this`, or the execution of the `mutex()` member
+function on the `lock` objects supplied in the calls to `wait` or `wait_for` or `wait_until`
+in all the threads currently waiting on `*this` would return the same value as
+`lock->mutex()` for this call to `wait`.]]
+
+[[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
+thread will unblock when notified by a call to `this->notify_one()` or
+`this->notify_all()`, when the time as reported by `Clock::now()`
+would be equal to or later than the specified `abs_time`, or spuriously. When
+the thread is unblocked (for whatever reason), the lock is reacquired by
+invoking `lock.lock()` before the call to `wait` returns. The lock is also
+reacquired by invoking `lock.lock()` if the function exits with an exception.]]
+
+[[Returns:] [`cv_status::no_timeout` if the call is returning because the time specified by
+`abs_time` was reached, `cv_status::timeout` otherwise.]]
+
+[[Postcondition:] [`lock` is locked by the current thread.]]
+
+[[Throws:] [__thread_resource_error__ if an error
+occurs. __thread_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __thread__ object associated with the current thread of execution.]]
+
+]
+
+[endsect]
+
+[section:wait_for `template <class Rep, class Period> cv_status wait_for(boost::unique_lock<boost::mutex>& lock, const chrono::duration<Rep, Period>& rel_time)`]
+
+
+[variablelist
+
+[[Precondition:] [`lock` is locked by the current thread, and either no other
+thread is currently waiting on `*this`, or the execution of the `mutex()` member
+function on the `lock` objects supplied in the calls to `wait` or `wait_until` or `wait_for`
+in all the threads currently waiting on `*this` would return the same value as
+`lock->mutex()` for this call to `wait`.]]
+
+[[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
+thread will unblock when notified by a call to `this->notify_one()` or
+`this->notify_all()`, after the period of time indicated by the `rel_time`
+argument has elapsed, or spuriously. When the thread is unblocked (for whatever
+reason), the lock is reacquired by invoking `lock.lock()` before the call to
+`wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
+function exits with an exception.]]
+
+[[Returns:] [`cv_status::no_timeout ` if the call is returning because the time period specified
+by `rel_time` has elapsed, `cv_status::timeout ` otherwise.]]
+
+[[Postcondition:] [`lock` is locked by the current thread.]]
+
+[[Throws:] [__thread_resource_error__ if an error
+occurs. __thread_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __thread__ object associated with the current thread of execution.]]
+
+]
+
+[note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.]
+
+[endsect]
+
+[section:wait_until_predicate `template <class Clock, class Duration, class Predicate> bool wait_until(boost::unique_lock<boost::mutex>& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred)`]
+
+
+[variablelist
+
+[[Effects:] [As-if ``
+while(!pred())
+{
+ if(!wait_until(lock,abs_time))
+ {
+ return pred();
+ }
+}
+return true;
+``]]
+
+]
+
+[endsect]
+
+[section:wait_for_predicate `template <class Rep, class Period, class Predicate> bool wait_for(boost::unique_lock<boost::mutex>& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred)`]
+
+
+[variablelist
+
+[[Effects:] [As-if ``
+while(!pred())
+{
+ if(!wait_for(lock,rel_time))
+ {
+ return pred();
+ }
+}
+return true;
+``]]
+
+]
+
+[endsect]
+
+
+
+
[endsect]
[section:condition_variable_any Class `condition_variable_any`]
@@ -315,25 +458,43 @@ return true;
template<typename lock_type,typename predicate_type>
void wait(lock_type& lock,predicate_type predicate);
+ template <class lock_type, class Clock, class Duration>
+ cv_status wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t);
+
+ template <class lock_type, class Clock, class Duration, class Predicate>
+ bool wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred);
+
+
+ template <class lock_type, class Rep, class Period>
+ cv_status wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d);
+
+ template <class lock_type, class Rep, class Period, class Predicate>
+ bool wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d,
+ Predicate pred);
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
template<typename lock_type>
bool timed_wait(lock_type& lock,boost::system_time const& abs_time);
-
template<typename lock_type,typename duration_type>
bool timed_wait(lock_type& lock,duration_type const& rel_time);
-
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& lock,boost::system_time const& abs_time,predicate_type predicate);
-
template<typename lock_type,typename duration_type,typename predicate_type>
bool timed_wait(lock_type& lock,duration_type const& rel_time,predicate_type predicate);
-
- // backwards compatibility
-
template<typename lock_type>
bool timed_wait(lock_type>& lock,boost::xtime const& abs_time);
-
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& lock,boost::xtime const& abs_time,predicate_type predicate);
+ #endif
};
}
@@ -498,6 +659,96 @@ return true;
[endsect]
+[section:wait_until `template <class lock_type, class Clock, class Duration> cv_status wait_until(lock_type& lock, const chrono::time_point<Clock, Duration>& abs_time)`]
+
+[variablelist
+
+[[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
+thread will unblock when notified by a call to `this->notify_one()` or
+`this->notify_all()`, when the time as reported by `Clock::now()`
+would be equal to or later than the specified `abs_time`, or spuriously. When
+the thread is unblocked (for whatever reason), the lock is reacquired by
+invoking `lock.lock()` before the call to `wait` returns. The lock is also
+reacquired by invoking `lock.lock()` if the function exits with an exception.]]
+
+[[Returns:] [`cv_status::timeout` if the call is returning because the time specified by
+`abs_time` was reached, `cv_status::no_timeout` otherwise.]]
+
+[[Postcondition:] [`lock` is locked by the current thread.]]
+
+[[Throws:] [__thread_resource_error__ if an error
+occurs. __thread_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __thread__ object associated with the current thread of execution.]]
+
+]
+
+[endsect]
+
+[section:wait_for `template <class lock_type, class Rep, class Period> cv_status wait_for(lock_type& lock, const chrono::duration<Rep, Period>& rel_time)`]
+
+[variablelist
+
+[[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
+thread will unblock when notified by a call to `this->notify_one()` or
+`this->notify_all()`, after the period of time indicated by the `rel_time`
+argument has elapsed, or spuriously. When the thread is unblocked (for whatever
+reason), the lock is reacquired by invoking `lock.lock()` before the call to
+`wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
+function exits with an exception.]]
+
+[[Returns:] [`cv_status::timeout` if the call is returning because the time specified by
+`abs_time` was reached, `cv_status::no_timeout` otherwise.]]
+
+[[Postcondition:] [`lock` is locked by the current thread.]]
+
+[[Throws:] [__thread_resource_error__ if an error
+occurs. __thread_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __thread__ object associated with the current thread of execution.]]
+
+]
+
+[note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.]
+
+[endsect]
+
+[section:wait_until_predicate `template <class lock_type, class Clock, class Duration, class Predicate> bool wait_until(lock_type& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred)`]
+
+[variablelist
+
+[[Effects:] [As-if ``
+while(!pred())
+{
+ if(!__cvany_wait_until(lock,abs_time))
+ {
+ return pred();
+ }
+}
+return true;
+``]]
+
+]
+
+[endsect]
+
+[section:wait_for_predicate `template <class lock_type, class Rep, class Period, class Predicate> bool wait_until(lock_type& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred)`]
+
+[variablelist
+
+[[Effects:] [As-if ``
+while(!pred())
+{
+ if(!__cvany_wait_for(lock,rel_time))
+ {
+ return pred();
+ }
+}
+return true;
+``]]
+
+]
+
+[endsect]
+
[endsect]
[section:condition Typedef `condition`]
diff --git a/libs/thread/doc/configuration.qbk b/libs/thread/doc/configuration.qbk
new file mode 100644
index 0000000000..a68568601f
--- /dev/null
+++ b/libs/thread/doc/configuration.qbk
@@ -0,0 +1,217 @@
+[/
+ (C) Copyright 20012 Vicente J. Botet Escriba.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+]
+
+
+[section:configuration Configuration]
+
+[section:system Boost.System]
+
+Boost.Thread uses by default Boost.System to define the exceptions. For backward compatibility and also for compilers that don't work well with Boost.System the user can define `BOOST_THREAD_DONT_USE_SYSTEM `.
+
+`BOOST_THREAD_USES_SYSTEM` is defined when Boost.Thread uses Boost.Move.
+
+[endsect]
+
+[section:chrono Boost.Chrono]
+
+Boost.Thread uses by default Boost.Chrono for the time related functions. For backward compatibility and also for compilers that don't work well with Boost.Chrono the user can define `BOOST_THREAD_DONT_USE_CHRONO`. If `BOOST_THREAD_DONT_USE_SYSTEM` is defined then `BOOST_THREAD_DONT_USE_CHRONO` is defined implicitly.
+
+`BOOST_THREAD_USES_CHRONO` is defined when Boost.Thread uses Boost.Chrono.
+
+[endsect]
+
+[section:move Boost.Move]
+
+Boost.Thread uses by default an internal move semantic implementation. Since version 3.0.0 you can use the move emulation emulation provided by Boost.Move.
+
+When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_USES_MOVE ` if you want to use Boost.Move interface.
+When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_USE_MOVE ` if you want to use boost::unique_future.
+
+[endsect]
+
+[section:shared_gen Shared Locking Generic]
+
+The shared mutex implementation on Windows platform provides currently less functionality than the generic one that is used for PTheads based platforms. In order to have access to these functions, the user needs to define `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` to use the generic implementation, that while could be less efficient, provides all the functions.
+
+When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN ` if you want these features.
+When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN ` if you don't want these features.
+
+[endsect]
+
+[section:shared_upwards Shared Locking Upwards Conversion]
+
+Boost.Threads includes in version 2 the Shared Locking Upwards Conversion as defined in [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking].
+These conversions need to be used carefully to avoid deadlock or livelock. The user need to define explicitly `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` to get these upwards conversions.
+
+When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION ` if you want these features.
+When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSION ` if you don't want these features.
+
+[endsect]
+
+[section:explicit_cnv Explicit Lock Conversion]
+
+In [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking] the lock conversions are explicit. As this explicit conversion breaks the lock interfaces, it is provided only if the `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION` is defined.
+
+When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION ` if you want these features.
+When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION ` if you don't want these features.
+
+[endsect]
+
+
+[section:future unique_future versus future]
+
+C++11 uses `std::future`. Versions of Boost.Thread previous to version 3.0.0 uses `boost:unique_future`.
+Since version 3.0.0 `boost::future` replaces `boost::unique_future` when `BOOST_THREAD_PROVIDES_FUTURE` is defined. The documentation doesn't contains anymore however `boost::unique_future`.
+
+When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_FUTURE` if you want to use boost::future.
+When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_FUTURE` if you want to use boost::unique_future.
+
+[endsect]
+
+[section:lazy promise lazy initialization]
+
+C++11 promise initialize the associated state at construction time. Versions of Boost.Thread previous to version 3.0.0 initialize it lazily at any point in time in which this associated state is needed.
+
+Since version 3.0.0 this difference in behavior can be configured. When `BOOST_THREAD_PROVIDES_PROMISE_LAZY` is defined the backward compatible behavior is provided.
+
+When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY ` if you want to use boost::future.
+When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_PROVIDES_PROMISE_LAZY ` if you want to use boost::unique_future.
+
+[endsect]
+
+[section:alloc promise Allocator constructor]
+
+C++11 std::promise provides constructors with allocators.
+
+ template <typename R>
+ class promise
+ {
+ public:
+ template <class Allocator>
+ explicit promise(allocator_arg_t, Allocator a);
+ // ...
+ };
+ template <class R, class Alloc> struct uses_allocator<promise<R>,Alloc>: true_type {};
+
+where
+
+ struct allocator_arg_t { };
+ constexpr allocator_arg_t allocator_arg = allocator_arg_t();
+
+ template <class T, class Alloc> struct uses_allocator;
+
+Since version 3.0.0 Boost.Thread implements this constructor using the following interface
+
+ namespace boost
+ {
+ typedef container::allocator_arg_t allocator_arg_t;
+ constexpr allocator_arg_t allocator_arg = {};
+
+ namespace container
+ {
+ template <class R, class Alloc>
+ struct uses_allocator<promise<R>,Alloc>: true_type {};
+ }
+ template <class T, class Alloc>
+ struct uses_allocator : public container::uses_allocator<T, Alloc> {};
+ }
+
+which introduces a dependency on Boost.Container. This feature is provided only if `BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS` is defined.
+
+When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS ` if you want these features.
+When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS ` if you don't want these features.
+
+[endsect]
+
+[section:terminate Call to terminate if joinable]
+
+C++11 has a different semantic for the thread destructor and the move assignment. Instead of detaching the thread, calls to terminate() if the thread was joinable. When `BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE` and `BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE` is defined Boost.Thread provides the C++ semantic.
+
+When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE ` if you want these features.
+When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE ` if you don't want these features.
+
+When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE ` if you want these features.
+When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE ` if you don't want these features.
+
+[endsect]
+
+[section:once_flag once_flag]
+
+C++11 defines a default constructor for once_flag. When `BOOST_THREAD_PROVIDES_ONCE_CXX11 ` is defined Boost.Thread provides this C++ semantics. In this case, the previous aggregate syntax is not supported.
+
+ boost::once_flag once = BOOST_ONCE_INIT;
+
+You should now just do
+
+ boost::once_flag once;
+
+When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_ONCE_CXX11` if you want these features.
+When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11` if you don't want these features.
+
+[endsect]
+
+[section:deprecated Deprecated]
+
+Version 3.0.0 deprecates some Boost.Thread features.
+
+These deprecated features will be provided by default up to boost 1.52. If you don't want to include the deprecated features you could define `BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0`. Since 1.53 these features will not be included any more by default. Since this version, if you want to include the deprecated features yet you could define `BOOST_THREAD_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0`. These deprecated features will be only available until boost 1.55, that is you have 1 year and a half to move to the new features.
+
+
+[endsect]
+
+
+[section:version Version]
+
+`BOOST_THREAD_VERSION` defines the Boost.Thread version.
+The default version is 2. In this case the following breaking or extending macros are defined if the opposite is not requested:
+
+* `BOOST_THREAD_PROVIDES_PROMISE_LAZY`
+* `BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0`
+
+The user can request the version 3 by defining `BOOST_THREAD_VERSION` to 3. In this case the following breaking or extending macros are defined if the opposite is not requested:
+
+* Breaking change `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION `
+* Breaking change `BOOST_THREAD_PROVIDES_FUTURE`
+* Uniformity `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN`
+* Extension `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION`
+* Conformity `BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS`
+* Breaking change BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
+* Breaking change BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
+* Breaking change `BOOST_THREAD_PROVIDES_ONCE_CXX11`
+
+* Breaking change `BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY`
+* Breaking change `BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0`
+
+The default value for `BOOST_THREAD_VERSION` will be changed to 3 since Boost 1.53.
+
+[endsect]
+
+[endsect]
+
+[section:limitations Limitations]
+
+Some compilers don't work correctly with some of the added features.
+
+[section:sun SunPro]
+
+If __SUNPRO_CC < 0x5100 the library defines
+
+* `BOOST_THREAD_DONT_USE_MOVE`
+* `BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS`
+
+
+[endsect]
+[section:vacpp VACPP]
+
+If __IBMCPP__ is defined the library defines
+
+* `BOOST_THREAD_DONT_USE_CHRONO`
+
+And Boost.Thread doesn't links with Boost.Chrono.
+
+[endsect]
+[endsect]
diff --git a/libs/thread/doc/emulations.qbk b/libs/thread/doc/emulations.qbk
new file mode 100644
index 0000000000..d507b392f1
--- /dev/null
+++ b/libs/thread/doc/emulations.qbk
@@ -0,0 +1,365 @@
+[/
+ (C) Copyright 20012 Vicente J. Botet Escriba.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+]
+
+
+[section:emulations Emulations]
+[section:delete `=delete` emulation]
+
+C++11 allows to delete some implicitly generated functions as constructors and assignment using '= delete' as in
+
+ public:
+ thread(thread const&) = delete;
+
+On compilers not supporting this feature, Boost.Thread relays on a partial simulation, it declares the function as private without definition.
+
+ private:
+ thread(thread &);
+
+The emulation is partial as the private function can be used for overload resolution for some compilers and prefer it to other overloads that need a conversion. See below the consequences on the move semantic emulation.
+
+[endsect]
+
+[section:move Move semantics]
+
+In order to implement Movable classes, move parameters and return types Boost.Thread uses the rvalue reference when the compiler support it.
+On compilers not supporting it Boost.Thread uses either the emulation provided by Boost.Move or the emulation provided by the previous versions of Boost.Thread depending whether `BOOST_THREAD_USES_MOVE` is defined or not. This macros is unset by default when `BOOST_THREAD_VERSION` is 2. Since `BOOST_THREAD_VERSION` 3, `BOOST_THREAD_USES_MOVE` is defined.
+
+[section:deprecated Deprecated Version 2 interface]
+
+Previous to version 1.50, Boost.Thread make use of its own move semantic emulation which had more limitations than the provided by Boost.Move. In addition, it is of interest of the whole Boost community that Boost.Thread uses Boost.Move so that boost::thread can be stored on Movable aware containers.
+
+To preserve backward compatibility at least during some releases, Boost.Thread allows the user to use the deprecated move semantic emulation defining BOOST_THREAD_DONT_USE_MOVE.
+
+Many aspects of move semantics can be emulated for compilers not supporting rvalue references and Boost.Thread legacy offers tools for that purpose.
+
+[section:Helper Helpers class and function]
+
+Next follows the interface of the legacy move semantic helper class and function.
+
+ namespace boost
+ {
+ namespace detail
+ {
+ template<typename T>
+ struct thread_move_t
+ {
+ explicit thread_move_t(T& t_);
+ T& operator*() const;
+ T* operator->() const;
+ private:
+ void operator=(thread_move_t&);
+ };
+ }
+ template<typename T>
+ boost::detail::thread_move_t<T> move(boost::detail::thread_move_t<T> t);
+ }
+[endsect]
+
+[section:movable Movable emulation]
+
+We can write a MovableOny class as follows. You just need to follow these simple steps:
+
+* Add a conversion to the `detail::thread_move_t<classname>`
+* Make the copy constructor private.
+* Write a constructor taking the parameter as `detail::thread_move_t<classname>`
+* Write an assignment taking the parameter as `detail::thread_move_t<classname>`
+
+For example the thread class defines the following:
+
+ class thread
+ {
+ // ...
+ private:
+ thread(thread&);
+ thread& operator=(thread&);
+ public:
+ detail::thread_move_t<thread> move()
+ {
+ detail::thread_move_t<thread> x(*this);
+ return x;
+ }
+ operator detail::thread_move_t<thread>()
+ {
+ return move();
+ }
+ thread(detail::thread_move_t<thread> x)
+ {
+ thread_info=x->thread_info;
+ x->thread_info.reset();
+ }
+ thread& operator=(detail::thread_move_t<thread> x)
+ {
+ thread new_thread(x);
+ swap(new_thread);
+ return *this;
+ }
+ // ...
+
+ };
+
+[endsect]
+
+[endsect]
+
+[section:portable Portable interface]
+
+In order to make the library code portable Boost.Thread uses some macros that will use either the ones provided by Boost.Move or the deprecated move semantics provided by previous versions of Boost.Thread.
+
+See the Boost.Move documentation for a complete description on how to declare new Movable classes and its limitations.
+
+* `BOOST_THREAD_RV_REF(TYPE)` is the equivalent of `BOOST_RV_REF(TYPE)`
+* `BOOST_THREAD_RV_REF_BEG` is the equivalent of `BOOST_RV_REF_BEG(TYPE)`
+* `BOOST_THREAD_RV_REF_END` is the equivalent of `BOOST_RV_REF_END(TYPE)`
+* `BOOST_THREAD_FWD_REF(TYPE)` is the equivalent of `BOOST_FWD_REF(TYPE)
+
+In addition the following macros are needed to make the code portable:
+
+* `BOOST_THREAD_RV(V)` macro to access the rvalue from a BOOST_THREAD_RV_REF(TYPE),
+* `BOOST_THREAD_MAKE_RV_REF(RVALUE)` makes a rvalue.
+* `BOOST_THREAD_DCL_MOVABLE(CLASS)` to avoid conflicts with Boost.Move
+* `BOOST_THREAD_DCL_MOVABLE_BEG(T1)` and `BOOST_THREAD_DCL_MOVABLE_END` are variant of `BOOST_THREAD_DCL_MOVABLE` when the parameter is a template instantiation.
+
+Other macros are provided and must be included on the public section:
+
+* `BOOST_THREAD_NO_COPYABLE` declares a class no-copyable either deleting the copy constructors and copy assignment or moving them to the private section.
+* `BOOST_THREAD_MOVABLE(CLASS)` declares all the implicit conversions to an rvalue-reference.
+* `BOOST_THREAD_MOVABLE_ONLY(CLASS)` is the equivalent of `BOOST_MOVABLE_BUT_NOT_COPYABLE(CLASS)`
+* `BOOST_THREAD_COPYABLE_AND_MOVABLE(CLASS)` is the equivalent of `BOOST_COPYABLE_AND_MOVABLE(CLASS)`
+
+
+[section:NO_COPYABLE `BOOST_THREAD_NO_COPYABLE(CLASS)`]
+
+This macro marks a class as no copyable, disabling copy construction and assignment.
+
+[endsect]
+
+[section:MOVABLE `BOOST_THREAD_MOVABLE(CLASS)`]
+
+This macro marks a class as movable, declaring all the implicit conversions to an rvalue-reference.
+
+[endsect]
+
+[section:MOVABLE_ONLY `BOOST_THREAD_MOVABLE_ONLY(CLASS)`]
+
+This macro marks a type as movable but not copyable, disabling copy construction and assignment. The user will need to write a move constructor/assignment to fully write a movable but not copyable class.
+
+[endsect]
+
+[section:COPYABLE_AND_MOVABLE `BOOST_THREAD_COPYABLE_AND_MOVABLE(CLASS)`]
+
+This macro marks a type as copyable and movable. The user will need to write a move constructor/assignment and a copy assignment to fully write a copyable and movable class.
+
+[endsect]
+
+[section:RV_REF `BOOST_THREAD_RV_REF(TYPE)`, `BOOST_THREAD_RV_REF_BEG` and `BOOST_THREAD_RV_REF_END`]
+
+This macro is used to achieve portable syntax in move constructors and assignments for classes marked as `BOOST_THREAD_COPYABLE_AND_MOVABLE` or `BOOST_THREAD_MOVABLE_ONLY`.
+
+`BOOST_THREAD_RV_REF_BEG` and `BOOST_THREAD_RV_REF_END` are used when the parameter end with a `>` to avoid the compiler error.
+
+[endsect]
+
+[section:RV `BOOST_THREAD_RV(V)`]
+
+While Boost.Move emulation allows to access an rvalue reference `BOOST_THREAD_RV_REF(TYPE)` using the dot operator, the legacy defines the `operator->`. We need then a macro `BOOST_THREAD_RV` that mask this difference. E.g.
+
+ thread(BOOST_THREAD_RV_REF(thread) x)
+ {
+ thread_info=BOOST_THREAD_RV(x).thread_info;
+ BOOST_THREAD_RV(x).thread_info.reset();
+ }
+
+The use of this macros has reduced considerably the size of the Boost.Thread move related code.
+
+[endsect]
+
+[section:MAKE_RV_REF `BOOST_THREAD_MAKE_RV_REF(RVALUE)`]
+
+While Boost.Move is the best C++03 move emulation there are some limitations that impact the way the library can be used.
+For example, with the following declarations
+
+ class thread {
+ // ...
+ private:
+ thread(thread &);
+ public:
+ thread(rv<thread>&);
+ // ...
+ };
+
+This could not work on some compilers even if thread is convertible to `rv<thread>` because the compiler prefers the private copy constructor.
+
+ thread mkth()
+ {
+ return thread(f);
+ }
+
+On these compilers we need to use instead an explicit conversion. The library provides a move member function that allows to workaround the issue.
+
+ thread mkth()
+ {
+ return thread(f).move();
+ }
+
+Note that `::boost::move` can not be used in this case as thread is not implicitly convertible to `thread&`.
+
+ thread mkth()
+ {
+ return ::boost::move(thread(f));
+ }
+
+To make the code portable Boost.Thread the user needs to use a macro `BOOST_THREAD_MAKE_RV_REF` that can be used as in
+
+ thread mkth()
+ {
+ return BOOST_THREAD_MAKE_RV_REF(thread(f));
+ }
+
+Note that this limitation is shared also by the legacy Boost.Thread move emulation.
+
+[endsect]
+
+[section:DCL_MOVABLE `BOOST_THREAD_DCL_MOVABLE`, `BOOST_THREAD_DCL_MOVABLE_BEG(T1)` and `BOOST_THREAD_DCL_MOVABLE_END`]
+
+As Boost.Move defines also the `boost::move` function we need to specialize the `has_move_emulation_enabled_aux` metafunction.
+
+ template <>
+ struct has_move_emulation_enabled_aux<thread>
+ : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
+ {};
+
+so that the following Boost.Move overload is disabled
+
+ template <class T>
+ inline typename BOOST_MOVE_BOOST_NS::disable_if<has_move_emulation_enabled_aux<T>, T&>::type move(T& x);
+
+The macros `BOOST_THREAD_DCL_MOVABLE(CLASS)`, `BOOST_THREAD_DCL_MOVABLE_BEG(T1)` and `BOOST_THREAD_DCL_MOVABLE_END` are used for this purpose. E.g.
+
+ BOOST_THREAD_DCL_MOVABLE(thread)
+
+and
+
+ BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
+
+
+[endsect]
+[endsect]
+
+
+[endsect]
+
+[section:bool_explicit_conversion Bool explicit conversion]
+
+Locks provide an explicit bool conversion operator when the compiler provides them.
+
+ explicit operator bool() const;
+
+The library provides un implicit conversion to an undefined type that can be used as a conditional expression.
+
+ #if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
+ operator ``['unspecified-bool-type]``() const;
+ bool operator!() const;
+ #else
+ explicit operator bool() const;
+ #endif
+
+The user should use the lock.owns_lock() when a explicit conversion is required.
+
+[section:bool_conversion `operator `['unspecified-bool-type]`() const`]
+
+[variablelist
+
+[[Returns:] [If __owns_lock_ref__ would return `true`, a value that evaluates to
+`true` in boolean contexts, otherwise a value that evaluates to `false` in
+boolean contexts.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+[section:operator_not `bool operator!() const`]
+
+[variablelist
+
+[[Returns:] [`!` __owns_lock_ref__.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+[endsect]
+
+[section:scoped_enums Scoped Enums]
+
+Some of the enumerations defined in the standard library are scoped enums.
+
+On compilers that don't support them, the library uses a class to wrap the underlying type. Instead of
+
+ enum class future_errc
+ {
+ broken_promise,
+ future_already_retrieved,
+ promise_already_satisfied,
+ no_state
+ };
+
+the library declare these types as
+
+ BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
+ {
+ broken_promise,
+ future_already_retrieved,
+ promise_already_satisfied,
+ no_state
+ }
+ BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
+
+These macros allows to use 'future_errc' in almost all the cases as an scoped enum.
+
+There are however some limitations:
+
+* The type is not a C++ enum, so 'is_enum<future_errc>' will be false_type.
+* The emulated scoped enum can not be used in switch nor in template arguments. For these cases the user needs to use some macros.
+
+Instead of
+
+ switch (ev)
+ {
+ case future_errc::broken_promise:
+ // ...
+
+use
+
+ switch (boost::native_value(ev))
+ {
+ case future_errc::broken_promise:
+
+And instead of
+
+ #ifdef BOOST_NO_SCOPED_ENUMS
+ template <>
+ struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type { };
+ #endif
+
+use
+
+ #ifdef BOOST_NO_SCOPED_ENUMS
+ template <>
+ struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type> : public true_type { };
+ #endif
+
+
+
+[endsect]
+
+[endsect] \ No newline at end of file
diff --git a/libs/thread/doc/future_ref.qbk b/libs/thread/doc/future_ref.qbk
index 219619ca8e..e2762c5339 100644
--- a/libs/thread/doc/future_ref.qbk
+++ b/libs/thread/doc/future_ref.qbk
@@ -1,5 +1,5 @@
[/
- (C) Copyright 2008-9 Anthony Williams.
+ (C) Copyright 2008-11 Anthony Williams.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
@@ -7,12 +7,155 @@
[section:reference Futures Reference]
-[section:future_state `state` enum]
+ //#include <boost/thread/futures.hpp>
+ namespace boost
+ {
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
namespace future_state
{
- enum state {uninitialized, waiting, ready};
+ enum state {uninitialized, waiting, ready, moved};
}
+ #endif
+
+ enum class future_errc
+ {
+ broken_promise,
+ future_already_retrieved,
+ promise_already_satisfied,
+ no_state
+ };
+
+ namespace system
+ {
+ template <>
+ struct is_error_code_enum<future_errc> : public true_type {};
+
+ error_code make_error_code(future_errc e);
+
+ error_condition make_error_condition(future_errc e);
+ }
+
+ const system::error_category& future_category();
+
+ class future_error;
+
+ template <typename R>
+ class promise;
+
+ template <typename R>
+ void swap(promise<R>& x, promise<R>& y) noexcept;
+
+ namespace container {
+ template <class R, class Alloc>
+ struct uses_allocator<promise<R>, Alloc>:: true_type;
+ }
+
+ template <typename R>
+ class future;
+
+ template <typename R>
+ class shared_future;
+
+ template <typename R>
+ class packaged_task;
+ template <class R> void swap(packaged_task<R>&, packaged_task<R>&) noexcept;
+
+ //template <class R, class Alloc>
+ //struct uses_allocator<packaged_task <R>, Alloc>; // NOT YET IMPLEMENTED
+
+ // template <class F, class... Args>
+ // future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
+ // async(F&& f, Args&&... args); // NOT YET IMPLEMENTED
+ // template <class F, class... Args>
+ // future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
+ // async(launch policy, F&& f, Args&&... args); // NOT YET IMPLEMENTED
+
+
+ template<typename Iterator>
+ void wait_for_all(Iterator begin,Iterator end); // EXTENSION
+
+ template<typename F1,typename... FS>
+ void wait_for_all(F1& f1,Fs&... fs); // EXTENSION
+
+ template<typename Iterator>
+ Iterator wait_for_any(Iterator begin,Iterator end);
+
+ template<typename F1,typename... Fs>
+ unsigned wait_for_any(F1& f1,Fs&... fs);
+
+
+[section:future_state Enumeration `state`]
+
+ namespace future_state
+ {
+ enum state {uninitialized, waiting, ready, moved};
+ }
+
+
+[endsect]
+
+
+[section:future_errc Enumeration `future_errc `]
+
+ enum class future_errc
+ {
+ broken_promise,
+ future_already_retrieved,
+ promise_already_satisfied,
+ no_state
+ }
+
+[endsect]
+[section:is_error_code_enum Specialization `is_error_code_enum<future_errc>`]
+
+ namespace system
+ {
+ template <>
+ struct is_error_code_enum<future_errc> : public true_type {};
+
+ }
+
+[endsect]
+[section:make_error_code Non-member function `make_error_code()`]
+
+ namespace system
+ {
+ error_code make_error_code(future_errc e);
+ }
+
+[endsect]
+[section:make_error_condition Non-member function `make_error_condition()`]
+
+ namespace system
+ {
+ error_condition make_error_condition(future_errc e);
+ }
+
+[endsect]
+[section:future_category Non-member function `future_category()`]
+
+ const system::error_category& future_category();
+
+[endsect]
+[section:future_error Class `future_error`]
+
+ class future_error
+ : public std::logic_error
+ {
+ public:
+ future_error(system::error_code ec);
+
+ const system::error_code& code() const no_except;
+ };
+
+[endsect]
+
+[section:future_status Enumeration `future_status`]
+
+ enum class future_status {
+ ready, timeout, deferred
+ };
[endsect]
@@ -21,35 +164,46 @@
template <typename R>
class unique_future
{
- unique_future(unique_future & rhs);// = delete;
- unique_future& operator=(unique_future& rhs);// = delete;
public:
- typedef future_state::state state;
+ unique_future(unique_future & rhs);// = delete;
+ unique_future& operator=(unique_future& rhs);// = delete;
- unique_future();
+ unique_future() noexcept;
~unique_future();
// move support
- unique_future(unique_future && other);
- unique_future& operator=(unique_future && other);
+ unique_future(unique_future && other) noexcept;
+ unique_future& operator=(unique_future && other) noexcept;
+ shared_future<R> share();
- void swap(unique_future& other);
+ void swap(unique_future& other) noexcept; // EXTENSION
// retrieving the value
R&& get();
// functions to check state
- state get_state() const;
- bool is_ready() const;
- bool has_exception() const;
- bool has_value() const;
+ bool valid() const;
+ bool is_ready() const; // EXTENSION
+ bool has_exception() const; // EXTENSION
+ bool has_value() const; // EXTENSION
// waiting for the result to be ready
- void wait() const;
+ void wait() const;
+ template <class Rep, class Period>
+ future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+ template <class Clock, class Duration>
+ future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
template<typename Duration>
bool timed_wait(Duration const& rel_time) const;
- bool timed_wait_until(boost::system_time const& abs_time) const;
+ bool timed_wait_until(boost::system_time const& abs_time) const;
+ #endif
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
+ typedef future_state::state state;
+ state get_state() const;
+ #endif
};
[section:default_constructor Default Constructor]
@@ -126,7 +280,7 @@ result prior to the call, that result no longer has an associated __unique_futur
[section:swap Member function `swap()`]
- void swap(unique_future & other);
+ void swap(unique_future & other) no_except;
[variablelist
@@ -247,7 +401,7 @@ associated with `*this` is not ready at the point of the call, and the current t
[endsect]
-[section:is_ready Member function `is_ready()`]
+[section:is_ready Member function `is_ready()` EXTENSION]
bool is_ready();
@@ -264,7 +418,7 @@ otherwise.]]
[endsect]
-[section:has_value Member function `has_value()`]
+[section:has_value Member function `has_value()` EXTENSION]
bool has_value();
@@ -281,7 +435,7 @@ stored value, `false` otherwise.]]
[endsect]
-[section:has_exception Member function `has_exception()`]
+[section:has_exception Member function `has_exception()` EXTENSION]
bool has_exception();
@@ -324,9 +478,9 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
class shared_future
{
public:
- typedef future_state::state state;
+ typedef future_state::state state; // EXTENSION
- shared_future();
+ shared_future() noexcept;
~shared_future();
// copy support
@@ -334,10 +488,10 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
shared_future& operator=(shared_future const& other);
// move support
- shared_future(shared_future && other);
- shared_future(unique_future<R> && other);
- shared_future& operator=(shared_future && other);
- shared_future& operator=(unique_future<R> && other);
+ shared_future(shared_future && other) noexcept;
+ shared_future(unique_future<R> && other) noexcept;
+ shared_future& operator=(shared_future && other) noexcept;
+ shared_future& operator=(unique_future<R> && other) noexcept;
void swap(shared_future& other);
@@ -345,16 +499,26 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
R get();
// functions to check state, and wait for ready
- state get_state() const;
- bool is_ready() const;
- bool has_exception() const;
- bool has_value() const;
+ bool valid() const noexcept;
+ bool is_ready() const noexcept; // EXTENSION
+ bool has_exception() const noexcept; // EXTENSION
+ bool has_value() const noexcept; // EXTENSION
// waiting for the result to be ready
void wait() const;
+ template <class Rep, class Period>
+ future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+ template <class Clock, class Duration>
+ future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
template<typename Duration>
bool timed_wait(Duration const& rel_time) const;
- bool timed_wait_until(boost::system_time const& abs_time) const;
+ bool timed_wait_until(boost::system_time const& abs_time) const;
+ #endif
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
+ state get_state() const noexcept;
+ #endif
};
[section:default_constructor Default Constructor]
@@ -470,7 +634,7 @@ associated with `*this` is not ready at the point of the call, and the current t
[endsect]
-[section:is_ready Member function `is_ready()`]
+[section:is_ready Member function `is_ready()` EXTENSION]
bool is_ready();
@@ -487,7 +651,7 @@ otherwise.]]
[endsect]
-[section:has_value Member function `has_value()`]
+[section:has_value Member function `has_value()` EXTENSION]
bool has_value();
@@ -504,7 +668,7 @@ stored value, `false` otherwise.]]
[endsect]
-[section:has_exception Member function `has_exception()`]
+[section:has_exception Member function `has_exception()` EXTENSION]
bool has_exception();
@@ -546,19 +710,20 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
template <typename R>
class promise
{
- promise(promise & rhs);// = delete;
- promise & operator=(promise & rhs);// = delete;
public:
- // template <class Allocator> explicit promise(Allocator a);
promise();
+ template <class Allocator>
+ promise(allocator_arg_t, Allocator a);
+ promise & operator=(const promise & rhs);// = delete;
+ promise(const promise & rhs);// = delete;
~promise();
// Move support
- promise(promise && rhs);
- promise & operator=(promise&& rhs);
+ promise(promise && rhs) noexcept;;
+ promise & operator=(promise&& rhs) noexcept;;
- void swap(promise& other);
+ void swap(promise& other) noexcept;
// Result retrieval
unique_future<R> get_future();
@@ -567,8 +732,13 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
void set_value(R&& r);
void set_exception(boost::exception_ptr e);
+ // setting the result with deferred notification
+ // void set_value_at_thread_exit(const R& r); // NOT YET IMPLEMENTED
+ // void set_value_at_thread_exit(see below); // NOT YET IMPLEMENTED
+ // void set_exception_at_thread_exit(exception_ptr p); // NOT YET IMPLEMENTED
+
template<typename F>
- void set_wait_callback(F f);
+ void set_wait_callback(F f); // EXTENSION
};
[section:default_constructor Default Constructor]
@@ -585,6 +755,25 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
[endsect]
+[section:alloc_constructor Allocator Constructor]
+
+ template <class Allocator>
+ promise(allocator_arg_t, Allocator a);
+
+[variablelist
+
+[[Effects:] [Constructs a new __promise__ with no associated result using the allocator `a`.]]
+
+[[Throws:] [Nothing.]]
+
+[[Notes:] [Available only if BOOST_THREAD_FUTURE_USES_ALLOCATORS is defined.]]
+
+]
+
+[endsect]
+
+
+
[section:move_constructor Move Constructor]
promise(promise && other);
@@ -718,50 +907,53 @@ or __shared_future__ associated with this result, and the result is not ['ready]
[section:packaged_task `packaged_task` class template]
- template<typename R>
+ template<typename R
+ // , class... ArgTypes // NOT YET IMPLEMENTED
+ >
class packaged_task
{
+ public:
+ typedef R result_type;
+
packaged_task(packaged_task&);// = delete;
packaged_task& operator=(packaged_task&);// = delete;
-
- public:
+
// construction and destruction
- template <class F>
- explicit packaged_task(F const& f);
+ packaged_task() noexcept;
explicit packaged_task(R(*f)());
template <class F>
explicit packaged_task(F&& f);
- // template <class F, class Allocator>
- // explicit packaged_task(F const& f, Allocator a);
- // template <class F, class Allocator>
- // explicit packaged_task(F&& f, Allocator a);
+ template <class F, class Allocator>
+ packaged_task(allocator_arg_t, Allocator a, F&& f);
~packaged_task()
{}
// move support
- packaged_task(packaged_task&& other);
- packaged_task& operator=(packaged_task&& other);
+ packaged_task(packaged_task&& other) noexcept;
+ packaged_task& operator=(packaged_task&& other) noexcept;
+
+ void swap(packaged_task& other) noexcept;
- void swap(packaged_task& other);
+ bool valid() const noexcept;
// result retrieval
unique_future<R> get_future();
// execution
void operator()();
+ // void operator()(ArgTypes... ); // NOT YET IMPLEMENTED
+ // void make_ready_at_thread_exit(ArgTypes...); // NOT YET IMPLEMENTED
+ void reset();
template<typename F>
- void set_wait_callback(F f);
+ void set_wait_callback(F f); // EXTENSION
};
[section:task_constructor Task Constructor]
- template<typename F>
- packaged_task(F const &f);
-
packaged_task(R(*f)());
template<typename F>
@@ -772,11 +964,37 @@ or __shared_future__ associated with this result, and the result is not ['ready]
[[Preconditions:] [`f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` shall behave the same
as invoking `f`.]]
-[[Effects:] [Constructs a new __packaged_task__ with a copy of `f` stored as the associated task.]]
+[[Effects:] [Constructs a new __packaged_task__ with `boost::forward<F>(f)` stored as the associated task.]]
[[Throws:] [Any exceptions thrown by the copy (or move) constructor of `f`. `std::bad_alloc` if memory for the internal data
structures could not be allocated.]]
+[[Notes:] [The R(*f)()) overload to allow passing a function without needing to use `&`.]]
+
+]
+
+[endsect]
+
+[section:alloc_constructor Allocator Constructor]
+
+ template <class Allocator>
+ packaged_task(allocator_arg_t, Allocator a, R(*f)());
+ template <class F, class Allocator>
+ packaged_task(allocator_arg_t, Allocator a, F&& f);
+
+[variablelist
+
+[[Preconditions:] [`f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` shall behave the same
+as invoking `f`.]]
+
+[[Effects:] [Constructs a new __packaged_task with `boost::forward<F>(f)` stored as the associated task using the allocator `a`.]]
+
+[[Throws:] [Any exceptions thrown by the copy (or move) constructor of `f`. `std::bad_alloc` if memory for the internal data
+structures could not be allocated.]]
+
+[[Notes:] [Available only if BOOST_THREAD_FUTURE_USES_ALLOCATORS is defined.]]
+[[Notes:] [The R(*f)()) overload to allow passing a function without needing to use `&`.]]
+
]
[endsect]
@@ -798,6 +1016,7 @@ with no associated task.]]
[endsect]
+
[section:move_assignment Move Assignment Operator]
packaged_task& operator=(packaged_task && other);
@@ -865,7 +1084,22 @@ __packaged_task__. __task_already_started__ if the task has already been invoked
[endsect]
-[section:set_wait_callback Member Function `set_wait_callback()`]
+[section:reset Member Function `reset()`]
+
+ void reset();
+
+[variablelist
+
+[[Effects:] [Reset the state of the packaged_task so that it can be called again.]]
+
+[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of
+__packaged_task__.]]
+
+]
+
+[endsect]
+
+[section:set_wait_callback Member Function `set_wait_callback()` EXTENSION]
template<typename F>
void set_wait_callback(F f);
diff --git a/libs/thread/doc/futures.qbk b/libs/thread/doc/futures.qbk
index a4e123f453..fbc6696051 100755
--- a/libs/thread/doc/futures.qbk
+++ b/libs/thread/doc/futures.qbk
@@ -1,5 +1,5 @@
[/
- (C) Copyright 2008-9 Anthony Williams.
+ (C) Copyright 2008-11 Anthony Williams.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
diff --git a/libs/thread/doc/mutex_concepts.qbk b/libs/thread/doc/mutex_concepts.qbk
index dd3aba79d4..aa33179bb9 100644
--- a/libs/thread/doc/mutex_concepts.qbk
+++ b/libs/thread/doc/mutex_concepts.qbk
@@ -1,5 +1,6 @@
[/
(C) Copyright 2007-8 Anthony Williams.
+ (C) Copyright 2011-12 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
@@ -17,58 +18,86 @@ __boost_thread__ supports four basic concepts for lockable objects: __lockable_c
__shared_lockable_concept_type__ and __upgrade_lockable_concept_type__. Each mutex type implements one or more of these concepts, as
do the various lock types.
-[section:lockable `Lockable` Concept]
+[section:basic_lockable `BasicLockable` Concept]
-The __lockable_concept__ models exclusive ownership. A type that implements the __lockable_concept__ shall provide the following
-member functions:
+The __BasicLockable concept models exclusive ownership.
+A type `L` meets the __BasicLockable requiremets if the following expressions are well-formed and have the specified semantics (`m` denotes a value of type `L`):
-* [lock_ref_link `void lock();`]
-* [try_lock_ref_link `bool try_lock();`]
-* [unlock_ref_link `void unlock();`]
+* `m.__lock();`
+* `m.__unlock();`
-Lock ownership acquired through a call to __lock_ref__ or __try_lock_ref__ must be released through a call to __unlock_ref__.
+Lock ownership acquired through a call to __lock_ref__ must be released through a call to __unlock_ref__.
-[section:lock `void lock()`]
+[section:lock `m.lock();`]
[variablelist
[[Effects:] [The current thread blocks until ownership can be obtained for the current thread.]]
-[[Postcondition:] [The current thread owns `*this`.]]
+[[Postcondition:] [The current thread owns `m`.]]
+
+[[Return type:] [`void`.]]
[[Throws:] [__thread_resource_error__ if an error occurs.]]
+[[Error Conditions:] [
+
+[*operation_not_permitted]: if the thread does not have the privilege to perform the operation.
+
+[*resource_deadlock_would_occur]: if the implementation detects that a deadlock would occur.
+
+[*device_or_resource_busy]: if the mutex is already locked and blocking is not possible.
+
+]]
+
+[[Thread safety:] [If an exception is thrown then a lock shall not have been acquired for the current thread.]]
+
]
[endsect]
-[section:try_lock `bool try_lock()`]
+[section:unlock `m.unlock();`]
[variablelist
-[[Effects:] [Attempt to obtain ownership for the current thread without blocking.]]
+[[Precondition:] [The current thread owns `m`.]]
-[[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]]
+[[Effects:] [Releases ownership by the current thread.]]
-[[Postcondition:] [If the call returns `true`, the current thread owns the `*this`.]]
+[[Return type:] [`void`.]]
-[[Throws:] [__thread_resource_error__ if an error occurs.]]
+[[Postcondition:] [The current thread no longer owns `m`.]]
+[[Throws:] [Nothing.]]
]
[endsect]
-[section:unlock `void unlock()`]
+
+[endsect]
+[section:lockable `Lockable` Concept]
+
+A type `L` meets the __Lockable requirements if it meets the __BasicLocable requirements and the following expressions are well-formed and have the specified semantics (`m` denotes a value of type `L`):
+
+* `m.__try_lock()`
+
+Lock ownership acquired through a call to __try_lock_ref__ must be released through a call to __unlock_ref__.
+
+[section:try_lock `m.try_lock()`]
[variablelist
-[[Precondition:] [The current thread owns `*this`.]]
+[[Effects:] [Attempt to obtain ownership for the current thread without blocking.]]
-[[Effects:] [Releases ownership by the current thread.]]
+[[Return type:] [`bool`.]]
-[[Postcondition:] [The current thread no longer owns `*this`.]]
+[[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread owns the `m`.]]
+
+[[Throws:] [Nothing.]]
-[[Throws:] [Nothing]]
]
[endsect]
+
[endsect]
[section:timed_lockable `TimedLockable` Concept]
@@ -76,16 +105,62 @@ Lock ownership acquired through a call to __lock_ref__ or __try_lock_ref__ must
The __timed_lockable_concept__ refines the __lockable_concept__ to add support for
timeouts when trying to acquire the lock.
-A type that implements the __timed_lockable_concept__ shall meet the requirements
-of the __lockable_concept__. In addition, the following member functions must be
-provided:
+A type `L` meets the __TimedLockable requirements if it meets the __Lockable requirements and the following expressions are well-formed and have the specified semantics.
+
+[*Variables:]
+
+* `m` denotes a value of type `L`,
+* `rel_time` denotes a value of an instantiation of `chrono::duration`, and
+* `abs_time` denotes a value of an instantiation of `chrono::time_point`:
+
+[*Expressions:]
+
+* `m.__try_lock_for(rel_time)`
+* `m.__try_lock_until(abs_time)`
+
+Lock ownership acquired through a call to __try_lock_for or __try_lock_until must be released through a call to __unlock.
+
+[section:try_lock_until `m.try_lock_until(abs_time)`]
-* [timed_lock_ref_link `bool timed_lock(boost::system_time const& abs_time);`]
-* [timed_lock_duration_ref_link `template<typename DurationType> bool timed_lock(DurationType const& rel_time);`]
+[variablelist
+
+[[Effects:] [Attempt to obtain ownership for the current thread. Blocks until ownership can be obtained, or the specified time is
+reached. If the specified time has already passed, behaves as __try_lock_ref__.]]
+
+[[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread owns `m`.]]
+
+[[Throws:] [Nothing.]]
+]
+[endsect]
+
+[section:try_lock_for `m.try_lock_for(rel_time)`]
+
+[variablelist
+
+[[Effects:] [As-if `__try_lock_until(chrono::steady_clock::now() + rel_time)`.]]
+
+]
+[endsect]
+
+[heading Deprecated V3.0.0]
+
+The following expressions were required on version 2, but are now deprecated.
+
+[*Variables:]
+
+* `rel_time` denotes a value of an instantiation of an unspecified `DurationType` arithmetic compatible with `boost::system_time`, and
+* `abs_time` denotes a value of an instantiation of `boost::system_time`:
+
+[*Expressions:]
+
+* `m.__timed_lock_duration(rel_time)`
+* `m.__timed_lock(abs_time)`
Lock ownership acquired through a call to __timed_lock_ref__ must be released through a call to __unlock_ref__.
-[section:timed_lock `bool timed_lock(boost::system_time const& abs_time)`]
+[section:timed_lock `m.timed_lock(abs_time)`]
[variablelist
@@ -94,14 +169,13 @@ reached. If the specified time has already passed, behaves as __try_lock_ref__.]
[[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]]
-[[Postcondition:] [If the call returns `true`, the current thread owns `*this`.]]
+[[Postcondition:] [If the call returns `true`, the current thread owns `m`.]]
[[Throws:] [__thread_resource_error__ if an error occurs.]]
]
[endsect]
-[section:timed_lock_duration `template<typename DurationType> bool
-timed_lock(DurationType const& rel_time)`]
+[section:timed_lock_duration `m.timed_lock(rel_time)`]
[variablelist
@@ -111,6 +185,7 @@ timed_lock(DurationType const& rel_time)`]
]
[endsect]
+
[endsect]
[section:shared_lockable `SharedLockable` Concept]
@@ -122,32 +197,38 @@ exclusive ownership, and if any thread does have exclusive ownership, no other t
can have shared or exclusive ownership. Alternatively, many threads may have
shared ownership.
-For a type to implement the __shared_lockable_concept__, as well as meeting the
-requirements of the __timed_lockable_concept__, it must also provide the following
-member functions:
+A type `L` meets the __SharedLockable requirements if it meets the __TimedLockable requirements and the following expressions are well-formed and have the specified semantics.
+
+[*Variables:]
-* [lock_shared_ref_link `void lock_shared();`]
-* [try_lock_shared_ref_link `bool try_lock_shared();`]
-* [unlock_shared_ref_link `bool unlock_shared();`]
-* [timed_lock_shared_ref_link `bool timed_lock_shared(boost::system_time const& abs_time);`]
+* `m` denotes a value of type `L`,
+* `rel_time` denotes a value of an instantiation of `chrono::duration`, and
+* `abs_time` denotes a value of an instantiation of `chrono::time_point`:
-Lock ownership acquired through a call to __lock_shared_ref__, __try_lock_shared_ref__ or __timed_lock_shared_ref__ must be released
-through a call to __unlock_shared_ref__.
+[*Expressions:]
-[section:lock_shared `void lock_shared()`]
+* `m.__lock_shared();`
+* `m.__try_lock_shared()`
+* `m.__try_lock_shared_for(rel_time)`
+* `m.__try_lock_shared_until(abs_time)`
+* `m.__unlock_shared();`
+
+Lock ownership acquired through a call to __lock_shared_ref__, __try_lock_shared_ref__, __try_lock_shared_for or __try_lock_shared_until must be released through a call to __unlock_shared_ref__.
+
+[section:lock_shared `m.lock_shared()`]
[variablelist
[[Effects:] [The current thread blocks until shared ownership can be obtained for the current thread.]]
-[[Postcondition:] [The current thread has shared ownership of `*this`.]]
+[[Postcondition:] [The current thread has shared ownership of `m`.]]
[[Throws:] [__thread_resource_error__ if an error occurs.]]
]
[endsect]
-[section:try_lock_shared `bool try_lock_shared()`]
+[section:try_lock_shared `m.try_lock_shared()`]
[variablelist
@@ -155,14 +236,31 @@ through a call to __unlock_shared_ref__.
[[Returns:] [`true` if shared ownership was obtained for the current thread, `false` otherwise.]]
-[[Postcondition:] [If the call returns `true`, the current thread has shared ownership of `*this`.]]
+[[Postcondition:] [If the call returns `true`, the current thread has shared ownership of `m`.]]
[[Throws:] [__thread_resource_error__ if an error occurs.]]
]
[endsect]
-[section:timed_lock_shared `bool timed_lock_shared(boost::system_time const& abs_time)`]
+[section:try_lock_shared_for `m.try_lock_shared_for(rel_time)`]
+
+[variablelist
+
+[[Effects:] [Attempt to obtain shared ownership for the current thread. Blocks until shared ownership can be obtained, or the
+specified duration is elapsed. If the specified duration is already elapsed, behaves as __try_lock_shared_ref__.]]
+
+[[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has shared
+ownership of `m`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+[endsect]
+
+[section:try_lock_shared_until `m.try_lock_shared_until(abs_time))`]
[variablelist
@@ -172,28 +270,60 @@ specified time is reached. If the specified time has already passed, behaves as
[[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]]
[[Postcondition:] [If the call returns `true`, the current thread has shared
-ownership of `*this`.]]
+ownership of `m`.]]
[[Throws:] [__thread_resource_error__ if an error occurs.]]
]
[endsect]
-[section:unlock_shared `void unlock_shared()`]
+[section:unlock_shared `m.unlock_shared()`]
[variablelist
-[[Precondition:] [The current thread has shared ownership of `*this`.]]
+[[Precondition:] [The current thread has shared ownership of `m`.]]
-[[Effects:] [Releases shared ownership of `*this` by the current thread.]]
+[[Effects:] [Releases shared ownership of `m` by the current thread.]]
-[[Postcondition:] [The current thread no longer has shared ownership of `*this`.]]
+[[Postcondition:] [The current thread no longer has shared ownership of `m`.]]
[[Throws:] [Nothing]]
]
[endsect]
+[heading Deprecated V3]
+
+The following expressions were required on version 1, but are now deprecated.
+
+[*Variables:]
+
+* `abs_time` denotes a value of an instantiation of `boost::system_time`:
+
+[*Expressions:]
+
+* `m.timed_lock_shared(abs_time);`
+
+Lock ownership acquired through a call to __timed_lock_shared_ref__ must be released through a call to __unlock_shared_ref__.
+
+[section:timed_lock_shared `m.timed_lock_shared(abs_time)`]
+
+[variablelist
+
+[[Effects:] [Attempt to obtain shared ownership for the current thread. Blocks until shared ownership can be obtained, or the
+specified time is reached. If the specified time has already passed, behaves as __try_lock_shared_ref__.]]
+
+[[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has shared
+ownership of `m`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+[endsect]
+
+
[endsect]
@@ -213,91 +343,441 @@ Ownership can also be ['downgraded] as well as ['upgraded]: exclusive ownership
__upgrade_lockable_concept__ can be downgraded to upgradable ownership or shared ownership, and upgradable ownership can be
downgraded to plain shared ownership.
-For a type to implement the __upgrade_lockable_concept__, as well as meeting the
-requirements of the __shared_lockable_concept__, it must also provide the following
-member functions:
+A type `L` meets the __SharedLockable requirements if it meets the __TimedLockable requirements and the following expressions are well-formed and have the specified semantics.
+
+[*Variables:]
+
+* `m` denotes a value of type `L`,
+* `rel_time` denotes a value of an instantiation of `chrono::duration`, and
+* `abs_time` denotes a value of an instantiation of `chrono::time_point`:
+
+[*Expressions:]
+
+* `m.__lock_upgrade();`
+* `m.__unlock_upgrade()`
+* `m.__try_lock_upgrade()`
+* `m.__try_lock_upgrade_for(rel_time)`
+* `m.__try_lock_upgrade_until(abs_time)`
+* `m.__unlock_and_lock_shared()`
+* `m.__unlock_and_lock_upgrade();`
+* `m.__unlock_upgrade_and_lock();`]
+* `m.__try_unlock_upgrade_and_lock()`
+* `m.__try_unlock_upgrade_and_lock_for(rel_time)`
+* `m.__try_unlock_upgrade_and_lock_until(abs_time)`
+* `m.__unlock_upgrade_and_lock_shared();`
+
+
+If `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION is defined the following expressions are also required:
+
+* `m.__try_unlock_shared_and_lock();`
+* `m.__try_unlock_shared_and_lock_for(rel_time);`
+* `m.__try_unlock_shared_and_lock_until(abs_time);`
+* `m.__try_unlock_shared_and_lock_upgrade();`
+* `m.__try_unlock_shared_and_lock_upgrade_for(rel_time);`
+* `m.__try_unlock_shared_and_lock_upgrade_until(abs_time);`
-* [lock_upgrade_ref_link `void lock_upgrade();`]
-* [unlock_upgrade_ref_link `bool unlock_upgrade();`]
-* [unlock_upgrade_and_lock_ref_link `void unlock_upgrade_and_lock();`]
-* [unlock_and_lock_upgrade_ref_link `void unlock_and_lock_upgrade();`]
-* [unlock_upgrade_and_lock_shared_ref_link `void unlock_upgrade_and_lock_shared();`]
Lock ownership acquired through a call to __lock_upgrade_ref__ must be released through a call to __unlock_upgrade_ref__. If the
ownership type is changed through a call to one of the `unlock_xxx_and_lock_yyy()` functions, ownership must be released through a
call to the unlock function corresponding to the new level of ownership.
-[section:lock_upgrade `void lock_upgrade()`]
+[section:lock_upgrade `m.lock_upgrade()`]
[variablelist
+[[Precondition:] [The calling thread has no ownership of the mutex. ]]
+
[[Effects:] [The current thread blocks until upgrade ownership can be obtained for the current thread.]]
-[[Postcondition:] [The current thread has upgrade ownership of `*this`.]]
+[[Postcondition:] [The current thread has upgrade ownership of `m`.]]
+
+[[Synchronization:] [Prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]]
[[Throws:] [__thread_resource_error__ if an error occurs.]]
]
[endsect]
-[section:unlock_upgrade `void unlock_upgrade()`]
+[section:unlock_upgrade `m.unlock_upgrade()`]
[variablelist
-[[Precondition:] [The current thread has upgrade ownership of `*this`.]]
+[[Precondition:] [The current thread has upgrade ownership of `m`.]]
-[[Effects:] [Releases upgrade ownership of `*this` by the current thread.]]
+[[Effects:] [Releases upgrade ownership of `m` by the current thread.]]
-[[Postcondition:] [The current thread no longer has upgrade ownership of `*this`.]]
+[[Postcondition:] [The current thread no longer has upgrade ownership of `m`.]]
+[[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership on the same object.]]
+
[[Throws:] [Nothing]]
]
[endsect]
-[section:unlock_upgrade_and_lock `void unlock_upgrade_and_lock()`]
+[section:try_lock_upgrade `m.try_lock_upgrade()`]
[variablelist
-[[Precondition:] [The current thread has upgrade ownership of `*this`.]]
+[[Precondition:] [The calling thread has no ownership of the mutex. ]]
-[[Effects:] [Atomically releases upgrade ownership of `*this` by the current thread and acquires exclusive ownership of `*this`. If
-any other threads have shared ownership, blocks until exclusive ownership can be acquired.]]
+[[Effects:] [Attempts to obtain upgrade ownership of the mutex for the calling thread without blocking. If upgrade ownership is not obtained, there is no effect and try_lock_upgrade() immediately returns.]]
+
+[[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
-[[Postcondition:] [The current thread has exclusive ownership of `*this`.]]
+[[Synchronization:] [If `__try_lock_upgrade()` returns true, prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]]
[[Throws:] [Nothing]]
]
[endsect]
-[section:unlock_upgrade_and_lock_shared `void unlock_upgrade_and_lock_shared()`]
+
+[section:try_lock_upgrade_for `m.try_lock_upgrade_for(rel_time)`]
[variablelist
-[[Precondition:] [The current thread has upgrade ownership of `*this`.]]
+[[Precondition:] [The calling thread has no ownership of the mutex. ]]
-[[Effects:] [Atomically releases upgrade ownership of `*this` by the current thread and acquires shared ownership of `*this` without
-blocking.]]
+[[Effects:] [If the tick period of `rel_time` is not exactly convertible to the native tick period, the duration shall be rounded up to the nearest native tick period.
+Attempts to obtain upgrade lock ownership for the calling thread within the relative timeout specified by `rel_time`.
+If the time specified by `rel_time` is less than or equal to `rel_time.zero()`, the function attempts to obtain ownership without blocking (as if by calling `__try_lock_upgrade()`).
+The function returns within the timeout specified by `rel_time` only if it has obtained upgrade ownership of the mutex object.]]
+
+[[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
-[[Postcondition:] [The current thread has shared ownership of `*this`.]]
+[[Synchronization:] [If `__try_lock_upgrade_for(rel_time)` returns true, prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]]
[[Throws:] [Nothing]]
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
]
[endsect]
-[section:unlock_and_lock_upgrade `void unlock_and_lock_upgrade()`]
+[section:try_lock_upgrade_until `m.try_lock_upgrade_until(abs_time)`]
[variablelist
-[[Precondition:] [The current thread has exclusive ownership of `*this`.]]
+[[Precondition:] [The calling thread has no ownership of the mutex. ]]
+
+[[Effects:] [The function attempts to obtain upgrade ownership of the mutex.
+If `abs_time` has already passed, the function attempts to obtain upgrade ownership without blocking (as if by calling `__try_lock_upgrade()`).
+The function returns before the absolute timeout specified by `abs_time` only if it has obtained upgrade ownership of the mutex object.]]
+
+[[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
+
+[[Synchronization:] [If `__try_lock_upgrade_until(abs_time)` returns true, prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]]
+
+[[Throws:] [Nothing]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+]
+[endsect]
+
+
+[section:try_unlock_shared_and_lock `m.try_unlock_shared_and_lock()`]
+
+[variablelist
+
+[[Precondition:] [The calling thread must hold a shared lock on the mutex.]]
+
+[[Effects:] [The function attempts to atomically convert the ownership from shared to exclusive for the calling thread without blocking.
+For this conversion to be successful, this thread must be the only thread holding any ownership of the lock.
+If the conversion is not successful, the shared ownership of m is retained.]]
+
+[[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
+
+[[Synchronization:] [If `__try_unlock_shared_and_lock()` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
-[[Effects:] [Atomically releases exclusive ownership of `*this` by the current thread and acquires upgrade ownership of `*this`
+
+[[Throws:] [Nothing]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+]
+[endsect]
+
+[section:try_unlock_shared_and_lock_for `m.try_unlock_shared_and_lock_for(rel_time)`]
+
+[variablelist
+
+[[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
+
+[[Effects:] [If the tick period of `rel_time` is not exactly convertible to the native tick period, the duration shall be rounded up to the nearest native tick period.
+The function attempts to atomically convert the ownership from shared to exclusive for the calling thread within the relative timeout specified by `rel_time`.
+If the time specified by `rel_time` is less than or equal to `rel_time.zero()`, the function attempts to obtain exclusive ownership without blocking (as if by calling `try_unlock_shared_and_lock()`).
+The function shall return within the timeout specified by `rel_time` only if it has obtained exclusive ownership of the mutex object.
+For this conversion to be successful, this thread must be the only thread holding any ownership of the lock at the moment of conversion.
+If the conversion is not successful, the shared ownership of the mutex is retained.]]
+
+[[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
+
+[[Synchronization:] [If `__try_unlock_shared_and_lock_for(rel_time)` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
+
+[[Throws:] [Nothing]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+]
+[endsect]
+
+
+[section:try_unlock_shared_and_lock_until `m.try_unlock_shared_and_lock_until(abs_time)`]
+
+[variablelist
+
+[[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
+
+[[Effects:] [The function attempts to atomically convert the ownership from shared to exclusive for the calling thread within the absolute timeout specified by `abs_time`.
+If `abs_time` has already passed, the function attempts to obtain exclusive ownership without blocking (as if by calling `try_unlock_shared_and_lock()`).
+The function shall return before the absolute timeout specified by `abs_time` only if it has obtained exclusive ownership of the mutex object.
+For this conversion to be successful, this thread must be the only thread holding any ownership of the lock at the moment of conversion.
+If the conversion is not successful, the shared ownership of the mutex is retained.]]
+
+[[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
+
+[[Synchronization:] [If `__try_unlock_shared_and_lock_until(rel_time)` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
+
+[[Throws:] [Nothing]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+]
+[endsect]
+
+[section:unlock_and_lock_shared `m.unlock_and_lock_shared()`]
+
+[variablelist
+
+[[Precondition:] [The calling thread shall hold an exclusive lock on `m`.]]
+
+[[Effects:] [Atomically converts the ownership from exclusive to shared for the calling thread.]]
+
+[[Postcondition:] [The current thread has shared ownership of `m`.]]
+
+[[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership of the same object.]]
+
+[[Throws:] [Nothing]]
+
+]
+[endsect]
+
+[section:try_unlock_shared_and_lock_upgrade `m.try_unlock_shared_and_lock_upgrade()`]
+
+[variablelist
+
+[[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
+
+[[Effects:] [The function attempts to atomically convert the ownership from shared to upgrade for the calling thread without blocking.
+For this conversion to be successful, there must be no thread holding upgrade ownership of this object.
+If the conversion is not successful, the shared ownership of the mutex is retained.]]
+
+[[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
+
+[[Synchronization:] [If `__try_unlock_shared_and_lock_upgrade()` returns true, prior `__unlock_upgrade()` and subsequent lock operations on the same object synchronize with this operation. ]]
+
+[[Throws:] [Nothing]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+]
+[endsect]
+
+
+[section:try_unlock_shared_and_lock_upgrade_for `m.try_unlock_shared_and_lock_upgrade_for(rel_time)`]
+
+[variablelist
+
+[[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
+
+[[Effects:] [If the tick period of `rel_time` is not exactly convertible to the native tick period, the duration shall be rounded up to the nearest native tick period.
+The function attempts to atomically convert the ownership from shared to upgrade for the calling thread within the relative timeout specified by `rel_time`.
+If the time specified by `rel_time` is less than or equal to `rel_time.zero()`, the function attempts to obtain upgrade ownership without blocking (as if by calling `__try_unlock_shared_and_lock_upgrade()`).
+The function shall return within the timeout specified by `rel_time` only if it has obtained exclusive ownership of the mutex object.
+For this conversion to be successful, there must be no thread holding upgrade ownership of this object at the moment of conversion.
+If the conversion is not successful, the shared ownership of m is retained.]]
+
+[[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
+
+[[Synchronization:] [If `__try_unlock_shared_and_lock_upgrade_for(rel_time)` returns true, prior `__unlock_upgrade()` and subsequent lock operations on the same object synchronize with this operation. ]]
+
+[[Throws:] [Nothing]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+
+]
+[endsect]
+
+[section:try_unlock_shared_and_lock_upgrade_until `m.try_unlock_shared_and_lock_upgrade_until(abs_time)`]
+
+[variablelist
+
+[[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
+
+[[Effects:] [The function attempts to atomically convert the ownership from shared to upgrade for the calling thread within the absolute timeout specified by `abs_time`.
+If `abs_time` has already passed, the function attempts to obtain upgrade ownership without blocking (as if by calling `__try_unlock_shared_and_lock_upgrade()`).
+The function shall return before the absolute timeout specified by `abs_time` only if it has obtained upgrade ownership of the mutex object.
+For this conversion to be successful, there must be no thread holding upgrade ownership of this object at the moment of conversion.
+If the conversion is not successful, the shared ownership of the mutex is retained.]]
+
+[[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
+
+[[Synchronization:] [If `__try_unlock_shared_and_lock_upgrade_until(rel_time)` returns true, prior `__unlock_upgrade()` and subsequent lock operations on the same object synchronize with this operation. ]]
+
+[[Throws:] [Nothing]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+]
+[endsect]
+
+[section:unlock_and_lock_upgrade `m.unlock_and_lock_upgrade()`]
+
+[variablelist
+
+[[Precondition:] [The current thread has exclusive ownership of `m`.]]
+
+[[Effects:] [Atomically releases exclusive ownership of `m` by the current thread and acquires upgrade ownership of `m`
without blocking.]]
-[[Postcondition:] [The current thread has upgrade ownership of `*this`.]]
+[[Postcondition:] [The current thread has upgrade ownership of `m`.]]
+
+[[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership of the same object.]]
+
+[[Throws:] [Nothing]]
+
+]
+[endsect]
+
+
+[section:unlock_upgrade_and_lock `m.unlock_upgrade_and_lock()`]
+
+[variablelist
+
+[[Precondition:] [The current thread has upgrade ownership of `m`.]]
+
+[[Effects:] [Atomically releases upgrade ownership of `m` by the current thread and acquires exclusive ownership of `m`. If
+any other threads have shared ownership, blocks until exclusive ownership can be acquired.]]
+
+[[Postcondition:] [The current thread has exclusive ownership of `m`.]]
+
+[[Synchronization:] [This operation synchronizes with prior `__unlock_shared()` and subsequent lock operations that obtain ownership of the same object.]]
+
+[[Throws:] [Nothing]]
+
+]
+[endsect]
+
+[section:try_unlock_upgrade_and_lock `m.try_unlock_upgrade_and_lock()`]
+
+[variablelist
+
+[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]]
+
+[[Effects:] [The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread without blocking.
+For this conversion to be successful, this thread must be the only thread holding any ownership of the lock.
+If the conversion is not successful, the upgrade ownership of m is retained.]]
+
+[[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
+
+[[Synchronization:] [If `__try_unlock_upgrade_and_lock()` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
+
+[[Throws:] [Nothing]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+
+]
+[endsect]
+
+[section:try_unlock_upgrade_and_lock_for `m.try_unlock_upgrade_and_lock_for(rel_time)`]
+
+[variablelist
+
+[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]]
+
+[[Effects:] [If the tick period of `rel_time` is not exactly convertible to the native tick period, the duration shall be rounded up to the nearest native tick period.
+The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread within the relative timeout specified by `rel_time`.
+If the time specified by `rel_time` is less than or equal to `rel_time.zero()`, the function attempts to obtain exclusive ownership without blocking (as if by calling `__try_unlock_upgrade_and_lock()`).
+The function shall return within the timeout specified by `rel_time` only if it has obtained exclusive ownership of the mutex object.
+For this conversion to be successful, this thread shall be the only thread holding any ownership of the lock at the moment of conversion.
+If the conversion is not successful, the upgrade ownership of m is retained.]]
+
+[[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
+
+[[Synchronization:] [If `__try_unlock_upgrade_and_lock_for(rel_time)` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
+
+[[Throws:] [Nothing]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+]
+[endsect]
+
+[section:try_unlock_upgrade_and_lock_until `m.try_unlock_upgrade_and_lock_until(abs_time)`]
+
+[variablelist
+
+[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]]
+
+[[Effects:] [The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread within the absolute timeout specified by `abs_time`.
+If `abs_time` has already passed, the function attempts to obtain exclusive ownership without blocking (as if by calling `__try_unlock_upgrade_and_lock()`).
+The function shall return before the absolute timeout specified by `abs_time` only if it has obtained exclusive ownership of the mutex object.
+For this conversion to be successful, this thread shall be the only thread holding any ownership of the lock at the moment of conversion.
+If the conversion is not successful, the upgrade ownership of m is retained.]]
+
+[[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
+
+[[Synchronization:] [If `__try_unlock_upgrade_and_lock_for(rel_time)` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
+
+[[Throws:] [Nothing]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+]
+[endsect]
+
+
+[section:unlock_upgrade_and_lock_shared `m.unlock_upgrade_and_lock_shared()`]
+
+[variablelist
+
+[[Precondition:] [The current thread has upgrade ownership of `m`.]]
+
+[[Effects:] [Atomically releases upgrade ownership of `m` by the current thread and acquires shared ownership of `m` without
+blocking.]]
+
+[[Postcondition:] [The current thread has shared ownership of `m`.]]
+
+[[Synchronization:] [This operation synchronizes with prior `unlock_shared()` and subsequent lock operations that obtain ownership of the same object.]]
[[Throws:] [Nothing]]
@@ -310,6 +790,32 @@ without blocking.]]
[section:locks Lock Types]
+ #include <boost/thread/locks.hpp>
+
+ struct defer_lock_t {};
+ struct try_to_lock_t {};
+ struct adopt_lock_t {};
+ constexpr defer_lock_t defer_lock;
+ constexpr try_to_lock_t try_to_lock;
+ constexpr adopt_lock_t adopt_lock;
+
+ template<typename Lockable>
+ class lock_guard
+ template<typename Lockable>
+ class unique_lock;
+ template<typename Mutex>
+ void swap(unique_lock <Mutex>& lhs, unique_lock <Mutex>& rhs);
+ template<typename Lockable>
+ class shared_lock;
+ template<typename Mutex>
+ void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs);
+ template<typename Lockable>
+ class upgrade_lock;
+ template<typename Mutex>
+ void swap(upgrade_lock <Mutex>& lhs, upgrade_lock <Mutex>& rhs);
+ template <class Mutex>
+ class upgrade_to_unique_lock;
+
[section:lock_tags Lock option tags]
#include <boost/thread/locks.hpp>
@@ -403,41 +909,61 @@ object passed to the constructor.]]
class unique_lock
{
public:
- unique_lock();
+ typedef Lockable mutex_type;
+ unique_lock() noexcept;
explicit unique_lock(Lockable& m_);
unique_lock(Lockable& m_,adopt_lock_t);
- unique_lock(Lockable& m_,defer_lock_t);
+ unique_lock(Lockable& m_,defer_lock_t) noexcept;
unique_lock(Lockable& m_,try_to_lock_t);
- unique_lock(Lockable& m_,system_time const& target_time);
+ #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION
+ unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)
+ template <class Clock, class Duration>
+ unique_lock(shared_lock<mutex_type>&& sl,
+ const chrono::time_point<Clock, Duration>& abs_time);
+ template <class Rep, class Period>
+ unique_lock(shared_lock<mutex_type>&& sl,
+ const chrono::duration<Rep, Period>& rel_time)
+ #endif
+
+ template <class Clock, class Duration>
+ unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t);
+ template <class Rep, class Period>
+ unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d);
~unique_lock();
- unique_lock(detail::thread_move_t<unique_lock<Lockable> > other);
- unique_lock(detail::thread_move_t<upgrade_lock<Lockable> > other);
+ unique_lock(unique_lock const&) = delete;
+ unique_lock& operator=(unique_lock const&) = delete;
+ unique_lock(unique_lock<Lockable>&& other) noexcept;
+ explicit unique_lock(upgrade_lock<Lockable>&& other) noexcept;
- operator detail::thread_move_t<unique_lock<Lockable> >();
- detail::thread_move_t<unique_lock<Lockable> > move();
- unique_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other);
- unique_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other);
+ unique_lock& operator=(unique_lock<Lockable>&& other) noexcept;
- void swap(unique_lock& other);
- void swap(detail::thread_move_t<unique_lock<Lockable> > other);
+ void swap(unique_lock& other) noexcept;
+ Lockable* release() noexcept;
void lock();
bool try_lock();
- template<typename TimeDuration>
- bool timed_lock(TimeDuration const& relative_time);
- bool timed_lock(::boost::system_time const& absolute_time);
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock();
- bool owns_lock() const;
- operator ``['unspecified-bool-type]``() const;
- bool operator!() const;
+ explicit operator bool() const noexcept;
+ bool owns_lock() const noexcept;
+
+ Lockable* mutex() const noexcept;
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
+ unique_lock(Lockable& m_,system_time const& target_time);
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const& relative_time);
+ bool timed_lock(::boost::system_time const& absolute_time);
+ #endif
- Lockable* mutex() const;
- Lockable* release();
};
__unique_lock__ is more complex than __lock_guard__: not only does it provide for RAII-style locking, it also allows for deferring
@@ -445,9 +971,10 @@ acquiring the lock until the __lock_ref__ member function is called explicitly,
fashion, or with a timeout. Consequently, __unlock_ref__ is only called in the destructor if the lock object has locked the
__lockable_concept_type__ object, or otherwise adopted a lock on the __lockable_concept_type__ object.
-Specializations of __unique_lock__ model the __timed_lockable_concept__ if the supplied __lockable_concept_type__ type itself models
-__timed_lockable_concept__ (e.g. `boost::unique_lock<boost::timed_mutex>`), or the __lockable_concept__ otherwise
-(e.g. `boost::unique_lock<boost::mutex>`).
+Specializations of __unique_lock__ model the __TimedLockable concept if the supplied `Lockable` type itself models
+__TimedLockable concept (e.g. `boost::unique_lock<boost::timed_mutex>`), or the __Lockable concept if the supplied `Lockable` type itself models
+__Lockable concept (e.g. `boost::unique_lock<boost::mutex>`), or the __BasicLockable concept if the supplied `Lockable` type itself models
+__BasicLockable concept.
An instance of __unique_lock__ is said to ['own] the lock state of a __lockable_concept_type__ `m` if __mutex_func_ref__ returns a
pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] the lock state of a __lockable_concept_type__ object
@@ -533,6 +1060,82 @@ returns `false`.]]
[endsect]
+[section:constructor_sh_try `unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)`]
+
+[variablelist
+
+[[Requires:] [The supplied `Mutex` type must implement `__try_unlock_shared_and_lock()`.]]
+
+[[Effects:] [Constructs an object of type __unique_lock. Let `pm` be and `owns` the ownership state. Initializes `pm` with nullptr and `owns` with false.
+If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.release()`.
+Else `sl.__owns_lock()` returns `true`, and in this case if `sl.mutex()->try_unlock_shared_and_lock()` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
+
+[[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()->try_unlock_shared_and_lock()` returns `false`, `sl` is not modified.]]
+
+[[Throws:] [Nothing.]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+]
+
+[endsect]
+
+
+[section:constructor_sh_until `unique_lock(shared_lock<mutex_type>&&, const chrono::time_point<Clock, Duration>&)`]
+
+ template <class Clock, class Duration>
+ unique_lock(shared_lock<mutex_type>&& sl,
+ const chrono::time_point<Clock, Duration>& abs_time);
+
+[variablelist
+
+[[Requires:] [The supplied `Mutex` type shall implement `__try_unlock_shared_and_lock_until(abs_time)`.]]
+
+[[Effects:] [Constructs an object of type `__unique_lock`, initializing `pm` with `nullptr` and `owns` with `false`.
+If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.__release()`.
+Else `sl.owns_lock()` returns `true`, and in this case if `sl.mutex()->__try_unlock_shared_and_lock_until(abs_time)` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
+
+[[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()-> __try_unlock_shared_and_lock_until(abs_time)` returns `false`, `sl` is not modified.]]
+
+[[Throws:] [Nothing.]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+]
+
+[endsect]
+
+[section:constructor_sh_for `unique_lock(shared_lock<mutex_type>&&, const chrono::duration<Rep, Period>&)`]
+
+ template <class Rep, class Period>
+ unique_lock(shared_lock<mutex_type>&& sl,
+ const chrono::duration<Rep, Period>& rel_time)
+
+[variablelist
+
+[[Requires:] [The supplied `Mutex` type shall implement `__try_unlock_shared_and_lock_for(rel_time)`.]]
+
+[[Effects:] [Constructs an object of type `__unique_lock`, initializing `pm` with `nullptr` and `owns` with `false`.
+If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.__release()`.
+Else `sl.owns_lock()` returns `true`, and in this case if `sl.mutex()-> __try_unlock_shared_and_lock_for(rel_time)` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
+
+[[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()-> __try_unlock_shared_and_lock_for(rel_time)` returns `false`, `sl` is not modified.]]
+
+
+[[Postcondition:] [.]]
+
+[[Throws:] [Nothing.]]
+
+[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
+
+]
+
+[endsect]
+
+
+
+
+
[section:constructor_abs_time `unique_lock(Lockable & m,boost::system_time const& abs_time)`]
[variablelist
@@ -551,6 +1154,43 @@ returns `false`.]]
[endsect]
+[section:constructor_time_point `template <class Clock, class Duration> unique_lock(Lockable & m,const chrono::time_point<Clock, Duration>& abs_time)`]
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`. Invokes
+`m.__try_lock_until(abs_time)`, and takes ownership of the lock state if the call
+returns `true`.]]
+
+[[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_until
+returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
+returns `false`.]]
+
+[[Throws:] [Any exceptions thrown by the call to `m.__try_lock_until(abs_time)`.]]
+
+]
+
+[endsect]
+
+[section:constructor_duration `template <class Rep, class Period> unique_lock(Lockable & m,const chrono::duration<Rep, Period>& abs_time)`]
+
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`. Invokes
+`m.__try_lock_for(rel_time)`, and takes ownership of the lock state if the call
+returns `true`.]]
+
+[[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_for
+returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
+returns `false`.]]
+
+[[Throws:] [Any exceptions thrown by the call to `m.__try_lock_for(rel_time)`.]]
+
+]
+
+[endsect]
+
[section:destructor `~unique_lock()`]
[variablelist
@@ -590,13 +1230,11 @@ object associated with `*this`.]]
[endsect]
-[section:bool_conversion `operator unspecified-bool-type() const`]
+[section:explicit_bool_conversion `explicit operator bool() const`]
[variablelist
-[[Returns:] [If __owns_lock_ref__ would return `true`, a value that evaluates to
-`true` in boolean contexts, otherwise a value that evaluates to `false` in
-boolean contexts.]]
+[[Returns:] [`__owns_lock_ref__()`.]]
[[Throws:] [Nothing.]]
@@ -604,17 +1242,6 @@ boolean contexts.]]
[endsect]
-[section:operator_not `bool operator!() const`]
-
-[variablelist
-
-[[Returns:] [`!` __owns_lock_ref__.]]
-
-[[Throws:] [Nothing.]]
-
-]
-
-[endsect]
[section:release `Lockable* release()`]
@@ -646,34 +1273,53 @@ __owns_lock_ref__ returns `false`.]]
class shared_lock
{
public:
+ typedef Lockable mutex_type;
+
+ // Shared locking
shared_lock();
explicit shared_lock(Lockable& m_);
shared_lock(Lockable& m_,adopt_lock_t);
shared_lock(Lockable& m_,defer_lock_t);
shared_lock(Lockable& m_,try_to_lock_t);
- shared_lock(Lockable& m_,system_time const& target_time);
- shared_lock(detail::thread_move_t<shared_lock<Lockable> > other);
- shared_lock(detail::thread_move_t<unique_lock<Lockable> > other);
- shared_lock(detail::thread_move_t<upgrade_lock<Lockable> > other);
-
+ template <class Clock, class Duration>
+ shared_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t);
+ template <class Rep, class Period>
+ shared_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d);
~shared_lock();
- operator detail::thread_move_t<shared_lock<Lockable> >();
- detail::thread_move_t<shared_lock<Lockable> > move();
+ shared_lock(shared_lock const&) = delete;
+ shared_lock& operator=(shared_lock const&) = delete;
- shared_lock& operator=(detail::thread_move_t<shared_lock<Lockable> > other);
- shared_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other);
- shared_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other);
- void swap(shared_lock& other);
+ shared_lock(shared_lock<Lockable> && other);
+ shared_lock& operator=(shared_lock<Lockable> && other);
void lock();
bool try_lock();
- bool timed_lock(boost::system_time const& target_time);
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock();
- operator ``['unspecified-bool-type]``() const;
- bool operator!() const;
+ // Conversion from upgrade locking
+ explicit shared_lock(upgrade_lock<Lockable> && other);
+
+ // Conversion from exclusive locking
+ explicit shared_lock(unique_lock<Lockable> && other);
+
+ // Setters
+ void swap(shared_lock& other);
+ mutex_type* release() noexcept;
+
+ // Getters
+ explicit operator bool() const;
bool owns_lock() const;
+ mutex_type mutex() const;
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
+ shared_lock(Lockable& m_,system_time const& target_time);
+ bool timed_lock(boost::system_time const& target_time);
+ #endif
};
Like __unique_lock__, __shared_lock__ models the __lockable_concept__, but rather than acquiring unique ownership of the supplied
@@ -825,25 +1471,12 @@ object associated with `*this`.]]
[endsect]
-[section:bool_conversion `operator unspecified-bool-type() const`]
-
-[variablelist
-
-[[Returns:] [If __owns_lock_shared_ref__ would return `true`, a value that evaluates to
-`true` in boolean contexts, otherwise a value that evaluates to `false` in
-boolean contexts.]]
-[[Throws:] [Nothing.]]
-
-]
-
-[endsect]
-
-[section:operator_not `bool operator!() const`]
+[section:explicit_operator_bool `explicit operator bool() const`]
[variablelist
-[[Returns:] [`!` __owns_lock_shared_ref__.]]
+[[Returns:] [__owns_lock_shared_ref__.]]
[[Throws:] [Nothing.]]
@@ -881,27 +1514,59 @@ __owns_lock_shared_ref__ returns `false`.]]
class upgrade_lock
{
public:
- explicit upgrade_lock(Lockable& m_);
-
- upgrade_lock(detail::thread_move_t<upgrade_lock<Lockable> > other);
- upgrade_lock(detail::thread_move_t<unique_lock<Lockable> > other);
-
+ typedef Lockable mutex_type;
+
+ // Upgrade locking
+
+ upgrade_lock();
+ explicit upgrade_lock(mutex_type& m_);
+ upgrade_lock(mutex_type& m, defer_lock_t) noexcept;
+ upgrade_lock(mutex_type& m, try_to_lock_t);
+ upgrade_lock(mutex_type& m, adopt_lock_t);
+ template <class Clock, class Duration>
+ upgrade_lock(mutex_type& m,
+ const chrono::time_point<Clock, Duration>& abs_time);
+ template <class Rep, class Period>
+ upgrade_lock(mutex_type& m,
+ const chrono::duration<Rep, Period>& rel_time);
~upgrade_lock();
- operator detail::thread_move_t<upgrade_lock<Lockable> >();
- detail::thread_move_t<upgrade_lock<Lockable> > move();
+ upgrade_lock(const upgrade_lock& other) = delete;
+ upgrade_lock& operator=(const upgrade_lock<Lockable> & other) = delete;
- upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other);
- upgrade_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other);
-
- void swap(upgrade_lock& other);
+ upgrade_lock(upgrade_lock<Lockable> && other);
+ upgrade_lock& operator=(upgrade_lock<Lockable> && other);
void lock();
+ bool try_lock();
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock();
- operator ``['unspecified-bool-type]``() const;
- bool operator!() const;
+ #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION
+ // Conversion from shared locking
+ upgrade_lock(shared_lock<mutex_type>&& sl, try_to_lock_t);
+ template <class Clock, class Duration>
+ upgrade_lock(shared_lock<mutex_type>&& sl,
+ const chrono::time_point<Clock, Duration>& abs_time);
+ template <class Rep, class Period>
+ upgrade_lock(shared_lock<mutex_type>&& sl,
+ const chrono::duration<Rep, Period>& rel_time);
+ #endif
+
+ // Conversion from exclusive locking
+ explicit upgrade_lock(unique_lock<Lockable> && other);
+
+ // Setters
+ void swap(upgrade_lock& other);
+ mutex_type* release() noexcept;
+
+ // Getters
+ explicit operator bool() const;
bool owns_lock() const;
+ mutex_type mutex() const;
};
Like __unique_lock__, __upgrade_lock__ models the __lockable_concept__, but rather than acquiring unique ownership of the supplied
@@ -917,7 +1582,7 @@ pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] t
is destroyed, then the destructor will invoke [unlock_upgrade_ref_link `mutex()->unlock_upgrade()`].
The member functions of __upgrade_lock__ are not thread-safe. In particular, __upgrade_lock__ is intended to model the upgrade
-ownership of a __lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock
+ownership of a __upgrade_lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock
state (including the destructor) must be called by the same thread that acquired ownership of the lock state.
[endsect]
@@ -930,16 +1595,19 @@ state (including the destructor) must be called by the same thread that acquired
class upgrade_to_unique_lock
{
public:
+ typedef Lockable mutex_type;
explicit upgrade_to_unique_lock(upgrade_lock<Lockable>& m_);
-
~upgrade_to_unique_lock();
- upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Lockable> > other);
- upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Lockable> > other);
+ upgrade_to_unique_lock(upgrade_to_unique_lock const& other) = delete;
+ upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Lockable> const& other) = delete;
+
+ upgrade_to_unique_lock(upgrade_to_unique_lock<Lockable> && other);
+ upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Lockable> && other);
+
void swap(upgrade_to_unique_lock& other);
- operator ``['unspecified-bool-type]``() const;
- bool operator!() const;
+ explicit operator bool() const;
bool owns_lock() const;
};
@@ -972,14 +1640,12 @@ __lockable_concept_type__ is downgraded back to ['upgrade ownership].
void lock();
bool try_lock();
void unlock();
- bool owns_lock() const;
MutexType* mutex() const;
MutexType* release();
- bool operator!() const;
- typedef ``['unspecified-bool-type]`` bool_type;
- operator bool_type() const;
+ explicit operator bool() const;
+ bool owns_lock() const;
};
The member typedef `scoped_try_lock` is provided for each distinct
@@ -989,11 +1655,157 @@ those of [unique_lock_link `boost::unique_lock<MutexType>`] for the same `MutexT
that the constructor that takes a single reference to a mutex will
call [try_lock_ref_link `m.try_lock()`] rather than `m.lock()`.
+[endsect]
+[endsect]
+
+[/
+[section:other_mutex Other Mutex Types]
+
+[section: reverse_mutex Class template `reverse_mutex`]
+
+ #include <boost/thread/reverse_mutex.hpp>
+
+ template<typename BasicLockable>
+ class reverse_mutex
+ {
+ public:
+ typedef BasicLockable mutex_type;
+ reverse_mutex(reverse_mutex const&) = delete;
+ reverse_mutex& operator=(reverse_mutex const&) = delete;
+
+ explicit reverse_mutex(mutex_type& m_);
+ ~reverse_mutex();
+
+ void lock();
+ void unlock();
+ };
+
+__reverse_mutex reverse the operations of a __BasicLockable, that unlocks the lockable when `lock()` is called and locks it when `unlock()` is called.
+
+[endsect]
+[endsect]
+
+]
+
+[section:other_locks Other Lock Types]
+
+
+[section:shared_lock_guard Class template `shared_lock_guard`]
+
+ #include <boost/thread/shared_lock_guard.hpp>
+
+ template<typename SharedLockable>
+ class shared_lock_guard
+ {
+ public:
+ explicit shared_lock_guard(SharedLockable& m_);
+ shared_lock_guard(SharedLockable& m_,boost::adopt_lock_t);
+
+ ~shared_lock_guard();
+ };
+
+__shared_lock_guard is very simple: on construction it
+acquires shared ownership of the implementation of the __shared_lockable_concept__ supplied as
+the constructor parameter. On destruction, the ownership is released. This
+provides simple RAII-style locking of a __shared_lockable_concept_type__ object, to facilitate exception-safe
+shared locking and unlocking.
+In addition, the `__shared_lock_guard_ca(SharedLockable &m, boost::adopt_lock_t)` constructor allows the __shared_lock_guard object to
+take shared ownership of a lock already held by the current thread.
+
+[section:constructor `shared_lock_guard(SharedLockable & m)`]
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`. Invokes `m.__lock_shared()`.]]
+
+[[Throws:] [Any exception thrown by the call to `m.__lock_shared()`.]]
+
+]
+
+[endsect]
+
+[section:constructor_adopt `shared_lock_guard(SharedLockable & m,boost::adopt_lock_t)`]
+
+[variablelist
+
+[[Precondition:] [The current thread owns a lock on `m` equivalent to one
+obtained by a call to `m.__lock_shared()`.]]
+
+[[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of
+`m`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:destructor `~shared_lock_guard()`]
+
+[variablelist
+
+[[Effects:] [Invokes `m.__unlock_shared()` on the __shared_lockable_concept_type__ object passed to the constructor.]]
+
+[[Throws:] [Nothing.]]
+
+]
[endsect]
[endsect]
+[section:reverse_lock Class template `reverse_lock`]
+
+ #include <boost/thread/reverse_lock.hpp>
+
+ template<typename Lock>
+ class reverse_lock
+ {
+ public:
+ reverse_lock(reverse_lock const&) = delete;
+ reverse_lock& operator=(reverse_lock const&) = delete;
+
+ explicit reverse_lock(Lock& m_);
+ ~reverse_lock();
+ };
+
+__reverse_lock reverse the operations of a lock: it provide for RAII-style, that unlocks the lock at construction time and lock it at destruction time. In addition, it transfer ownership temporarily, so that the mutex can not be locked using the Lock.
+
+An instance of __reverse_lock doesn't ['own] the lock never.
+
+[section:constructor `reverse_lock(Lock & m)`]
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`. Invokes `m.__unlock()` if `m` owns his lock and then stores the mutex by calling `m.__release()`.]]
+
+[[Postcondition:] [`!m.__owns_lock() && m.__mutex()==0`.]]
+
+[[Throws:] [Any exception thrown by the call to `m.__unlock()`.]]
+
+]
+
+[endsect]
+
+
+[section:destructor `~reverse_lock()`]
+
+[variablelist
+
+[[Effects:] [Let be mtx the stored mutex*. If not 0 Invokes `mtx->__lock()` and gives again the `mtx` to the `Lock` using the `adopt_lock_t` overload.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+[endsect]
+
+[endsect]
+
+
[section:lock_functions Lock functions]
[section:lock_multiple Non-member function `lock(Lockable1,Lockable2,...)`]
diff --git a/libs/thread/doc/mutexes.qbk b/libs/thread/doc/mutexes.qbk
index ddea86a4bb..72c22d98b9 100644
--- a/libs/thread/doc/mutexes.qbk
+++ b/libs/thread/doc/mutexes.qbk
@@ -1,5 +1,6 @@
[/
- (C) Copyright 2007-8 Anthony Williams.
+ (C) Copyright 2007-11 Anthony Williams
+ (C) Copyright 2011-12 Vicente J. Botet Escriba
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
@@ -75,10 +76,11 @@ __try_mutex__ is a `typedef` to __mutex__, provided for backwards compatibility
void lock();
void unlock();
bool try_lock();
- bool timed_lock(system_time const & abs_time);
- template<typename TimeDuration>
- bool timed_lock(TimeDuration const & relative_time);
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& t);
typedef platform-specific-type native_handle_type;
native_handle_type native_handle();
@@ -86,6 +88,13 @@ __try_mutex__ is a `typedef` to __mutex__, provided for backwards compatibility
typedef unique_lock<timed_mutex> scoped_timed_lock;
typedef unspecified-type scoped_try_lock;
typedef scoped_timed_lock scoped_lock;
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
+ bool timed_lock(system_time const & abs_time);
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time);
+ #endif
+
};
__timed_mutex__ implements the __timed_lockable_concept__ to provide an exclusive-ownership mutex. At most one thread can own the
@@ -181,10 +190,11 @@ __recursive_try_mutex__ is a `typedef` to __recursive_mutex__, provided for back
bool try_lock();
void unlock();
- bool timed_lock(system_time const & abs_time);
- template<typename TimeDuration>
- bool timed_lock(TimeDuration const & relative_time);
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& t);
typedef platform-specific-type native_handle_type;
native_handle_type native_handle();
@@ -192,6 +202,13 @@ __recursive_try_mutex__ is a `typedef` to __recursive_mutex__, provided for back
typedef unique_lock<recursive_timed_mutex> scoped_lock;
typedef unspecified-type scoped_try_lock;
typedef scoped_lock scoped_timed_lock;
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
+ bool timed_lock(system_time const & abs_time);
+ template<typename TimeDuration>
+ bool timed_lock(TimeDuration const & relative_time);
+ #endif
+
};
__recursive_timed_mutex__ implements the __timed_lockable_concept__ to provide an exclusive-ownership recursive mutex. At most one
diff --git a/libs/thread/doc/once.qbk b/libs/thread/doc/once.qbk
index ecbdcb2290..dc960999e3 100644
--- a/libs/thread/doc/once.qbk
+++ b/libs/thread/doc/once.qbk
@@ -7,16 +7,37 @@
[section:once One-time Initialization]
+ #include <boost/thread/once.hpp>
+
+ namespace boost
+ {
+ struct once_flag;
+ template<typename Callable>
+ void call_once(once_flag& flag,Callable func);
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
+ void call_once(void (*func)(),once_flag& flag);
+ #endif
+
+ }
+
`boost::call_once` provides a mechanism for ensuring that an initialization routine is run exactly once without data races or deadlocks.
[section:once_flag Typedef `once_flag`]
- #include <boost/thread/once.hpp>
-
+ #ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+ struct once_flag
+ {
+ constexprr once_flag() noexcept;
+ once_flag(const once_flag&) = delete;
+ once_flag& operator=(const once_flag&) = delete;
+ };
+ #else
typedef platform-specific-type once_flag;
#define BOOST_ONCE_INIT platform-specific-initializer
+ #endif
-Objects of type `boost::once_flag` shall be initialized with `BOOST_ONCE_INIT`:
+Objects of type `boost::once_flag` shall be initialized with `BOOST_ONCE_INIT` if BOOST_THREAD_PROVIDES_ONCE_CXX11 is not defined
boost::once_flag f=BOOST_ONCE_INIT;
@@ -24,8 +45,6 @@ Objects of type `boost::once_flag` shall be initialized with `BOOST_ONCE_INIT`:
[section:call_once Non-member function `call_once`]
- #include <boost/thread/once.hpp>
-
template<typename Callable>
void call_once(once_flag& flag,Callable func);
diff --git a/libs/thread/doc/overview.qbk b/libs/thread/doc/overview.qbk
index c647a6d219..b95a3bd2af 100644
--- a/libs/thread/doc/overview.qbk
+++ b/libs/thread/doc/overview.qbk
@@ -1,5 +1,6 @@
[/
- (C) Copyright 2007-8 Anthony Williams.
+ (C) Copyright 2007-12 Anthony Williams.
+ (C) Copyright 20012 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
@@ -11,7 +12,7 @@ __boost_thread__ enables the use of multiple threads of execution with shared da
functions for managing the threads themselves, along with others for synchronizing data between the threads or providing separate
copies of data specific to individual threads.
-The __boost_thread__ library was originally written and designed by William E. Kempf. This version is a major rewrite designed to
+The __boost_thread__ library was originally written and designed by William E. Kempf (version 0). Anthony Williams version (version 1) was a major rewrite designed to
closely follow the proposals presented to the C++ Standards Committee, in particular
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html N2497],
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2320.html N2320],
@@ -19,6 +20,9 @@ closely follow the proposals presented to the C++ Standards Committee, in partic
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2139.html N2139], and
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2094.html N2094]
+Vicente J. Botet Escriba started in version 2 the adaptation to comply with the accepted Thread C++11 library (Make use of Boost.Chrono and Boost.Move) and the [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking] Howard Hinnant proposal except for the upward conversions.
+Some minor features have been added also as thread attributes, reverse_lock, shared_lock_guard.
+
In order to use the classes and functions described here, you can
either include the specific headers specified by the descriptions of
each class or function, or include the master thread library header:
@@ -28,3 +32,20 @@ each class or function, or include the master thread library header:
which includes all the other headers in turn.
[endsect]
+
+
+[section:build Using and building the library]
+
+Boost.Thread is configured following the conventions used to build [@http://www.boost.org/doc/libs/1_48_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_for_libraries_with_separate_source_code libraries with separate source code]. Boost.Thread will import/export the code only if the user has specifically asked for it, by defining either BOOST_ALL_DYN_LINK if they want all boost libraries to be dynamically linked, or BOOST_THREAD_DYN_LINK if they want just this one to be dynamically liked.
+
+The definition of these macros determines whether BOOST_THREAD_USE_DLL is defined. If BOOST_THREAD_USE_DLL is not defined, the library will define BOOST_THREAD_USE_DLL or BOOST_THREAD_USE_LIB depending on whether the platform. On non windows platforms BOOST_THREAD_USE_LIB is defined if is not defined. In windows platforms, BOOST_THREAD_USE_LIB is defined if BOOST_THREAD_USE_DLL and the compiler supports auto-tss cleanup with Boost.Threads (for the time been Msvc and Intel)
+
+The source code compiled when building the library defines a macros BOOST_THREAD_SOURCE that is used to import or export it. The user must not define this macro in any case.
+
+The following section describes all the macros used to configure Boost.Thread.
+
+[include configuration.qbk]
+
+
+[endsect]
+
diff --git a/libs/thread/doc/shared_mutex_ref.qbk b/libs/thread/doc/shared_mutex_ref.qbk
index 49cd16737a..8f1b5e2d42 100644
--- a/libs/thread/doc/shared_mutex_ref.qbk
+++ b/libs/thread/doc/shared_mutex_ref.qbk
@@ -12,19 +12,30 @@
class shared_mutex
{
public:
+ shared_mutex(shared_mutex const&) = delete;
+ shared_mutex& operator=(shared_mutex const&) = delete;
+
shared_mutex();
~shared_mutex();
void lock_shared();
bool try_lock_shared();
- bool timed_lock_shared(system_time const& timeout);
+ template <class Rep, class Period>
+ bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock_shared();
void lock();
bool try_lock();
- bool timed_lock(system_time const& timeout);
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock();
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
+ // use upgrade_mutex instead.
void lock_upgrade();
void unlock_upgrade();
@@ -32,13 +43,101 @@
void unlock_and_lock_upgrade();
void unlock_and_lock_shared();
void unlock_upgrade_and_lock_shared();
+ #endif
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
+ bool timed_lock_shared(system_time const& timeout);
+ bool timed_lock(system_time const& timeout);
+ #endif
+
};
The class `boost::shared_mutex` provides an implementation of a multiple-reader / single-writer mutex. It implements the
+__shared_lockable_concept__.
+
+Multiple concurrent calls to __lock_ref__, __try_lock_ref__, `__try_lock_for()`, `__try_lock_until()`, __timed_lock_ref__, __lock_shared_ref__,
+`__try_lock_shared_for()`, `__try_lock_shared_until()`, __try_lock_shared_ref__ and __timed_lock_shared_ref__ are permitted.
+
+
+[endsect]
+
+[section:upgrade_mutex Class `upgrade_mutex`]
+
+ #include <boost/thread/shared_mutex.hpp>
+
+ class upgrade_mutex
+ {
+ public:
+ upgrade_mutex(upgrade_mutex const&) = delete;
+ upgrade_mutex& operator=(upgrade_mutex const&) = delete;
+
+ upgrade_mutex();
+ ~upgrade_mutex();
+
+ void lock_shared();
+ bool try_lock_shared();
+ template <class Rep, class Period>
+ bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
+ void unlock_shared();
+
+ void lock();
+ bool try_lock();
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+ void unlock();
+
+ void lock_upgrade();
+ template <class Rep, class Period>
+ bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time);
+ void unlock_upgrade();
+
+ // Shared <-> Exclusive
+
+ #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ bool try_unlock_shared_and_lock();
+ template <class Rep, class Period>
+ bool try_unlock_shared_and_lock_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_unlock_shared_and_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+ #endif
+ void unlock_and_lock_shared();
+
+ // Shared <-> Upgrade
+
+ #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ bool try_unlock_shared_and_lock_upgrade();
+ template <class Rep, class Period>
+ bool try_unlock_shared_and_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_unlock_shared_and_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time);
+ #endif
+ void unlock_upgrade_and_lock_shared();
+
+ // Upgrade <-> Exclusive
+
+ void unlock_upgrade_and_lock();
+ #if defined(BOOST_THREAD_PLATFORM_PTHREAD)
+ || defined(BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN)
+ bool try_unlock_upgrade_and_lock();
+ template <class Rep, class Period>
+ bool try_unlock_upgrade_and_lock_for(const chrono::duration<Rep, Period>& rel_time);
+ template <class Clock, class Duration>
+ bool try_unlock_upgrade_and_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+ #endif
+ void unlock_and_lock_upgrade();
+ };
+
+The class `boost::upgrade_mutex` provides an implementation of a multiple-reader / single-writer mutex. It implements the
__upgrade_lockable_concept__.
-Multiple concurrent calls to __lock_ref__, __try_lock_ref__, __timed_lock_ref__, __lock_shared_ref__, __try_lock_shared_ref__ and
-__timed_lock_shared_ref__ shall be permitted.
+Multiple concurrent calls to __lock_ref__, __try_lock_ref__, `__try_lock_for()`, `__try_lock_until()`, __timed_lock_ref__, __lock_shared_ref__,
+`__try_lock_shared_for()`, `__try_lock_shared_until()`, __try_lock_shared_ref__ and __timed_lock_shared_ref__ are permitted.
[endsect]
diff --git a/libs/thread/doc/sync_tutorial.qbk b/libs/thread/doc/sync_tutorial.qbk
new file mode 100644
index 0000000000..70d61d7749
--- /dev/null
+++ b/libs/thread/doc/sync_tutorial.qbk
@@ -0,0 +1,14 @@
+[/
+ (C) Copyright 2012 Vicente J. Botet Escriba.
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt).
+]
+
+[section:tutorial Tutorial]
+
+[@http://home.roadrunner.com/~hinnant/mutexes/locking.html Handling mutexes in C++] is an excellent tutorial. You need just replace std and ting by boost.
+
+[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html Mutex, Lock, Condition Variable Rationale] adds rationale for the design decisions made for mutexes, locks and condition variables.
+
+[endsect]
diff --git a/libs/thread/doc/thread.qbk b/libs/thread/doc/thread.qbk
index c1a236c677..6e4abcc063 100644
--- a/libs/thread/doc/thread.qbk
+++ b/libs/thread/doc/thread.qbk
@@ -1,14 +1,17 @@
[/
- (C) Copyright 2007-8 Anthony Williams.
+ (C) Copyright 2008-11 Anthony Williams
+ (C) Copyright 2011-12 Vicente J. Botet Escriba
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
]
-[article Thread
- [quickbook 1.4]
- [authors [Williams, Anthony]]
- [copyright 2007-8 Anthony Williams]
+[library Thread
+ [quickbook 1.5]
+ [version 3.0.1]
+ [authors [Williams, Anthony] [Botet Escriba, Vicente J.]]
+ [copyright 2007-11 Anthony Williams]
+ [copyright 2011-12 Vicente J. Botet Escriba]
[purpose C++ Library for launching threads and synchronizing data between them]
[category text]
[license
@@ -21,6 +24,11 @@
[template lockable_concept_link[link_text] [link thread.synchronization.mutex_concepts.lockable [link_text]]]
[def __lockable_concept__ [lockable_concept_link `Lockable` concept]]
[def __lockable_concept_type__ [lockable_concept_link `Lockable`]]
+[def __BasicLockable [link thread.synchronization.mutex_concepts.basic_lockable `BasicLockable`]]
+[def __Lockable [link thread.synchronization.mutex_concepts.lockable `Lockable`]]
+[def __TimedLockable [link thread.synchronization.mutex_concepts.timed_lockable `TimedLockable `]]
+[def __SharedLockable [link thread.synchronization.mutex_concepts.shared_lockable `SharedLockable `]]
+[def __UpgradeLockable [link thread.synchronization.mutex_concepts.upgrade_lockable `UpgradeLockable `]]
[template timed_lockable_concept_link[link_text] [link thread.synchronization.mutex_concepts.timed_lockable [link_text]]]
[def __timed_lockable_concept__ [timed_lockable_concept_link `TimedLockable` concept]]
@@ -35,8 +43,9 @@
[def __upgrade_lockable_concept_type__ [upgrade_lockable_concept_link `UpgradeLockable`]]
-[template lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.lockable.lock [link_text]]]
+[template lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.basic_lockable.lock [link_text]]]
[def __lock_ref__ [lock_ref_link `lock()`]]
+[def __lock [link thread.synchronization.mutex_concepts.basic_lockable.lock `lock`]]
[template lock_multiple_ref_link[link_text] [link thread.synchronization.lock_functions.lock_multiple [link_text]]]
[def __lock_multiple_ref__ [lock_multiple_ref_link `lock()`]]
@@ -44,47 +53,85 @@
[template try_lock_multiple_ref_link[link_text] [link thread.synchronization.lock_functions.try_lock_multiple [link_text]]]
[def __try_lock_multiple_ref__ [try_lock_multiple_ref_link `try_lock()`]]
-[template unlock_ref_link[link_text] [link thread.synchronization.mutex_concepts.lockable.unlock [link_text]]]
+[template unlock_ref_link[link_text] [link thread.synchronization.mutex_concepts.basic_lockable.unlock [link_text]]]
[def __unlock_ref__ [unlock_ref_link `unlock()`]]
+[def __unlock [link thread.synchronization.mutex_concepts.basic_lockable.unlock `unlock`]]
[template try_lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.lockable.try_lock [link_text]]]
[def __try_lock_ref__ [try_lock_ref_link `try_lock()`]]
+[def __try_lock [link thread.synchronization.mutex_concepts.lockable.try_lock `try_lock`]]
[template timed_lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.timed_lockable.timed_lock [link_text]]]
[def __timed_lock_ref__ [timed_lock_ref_link `timed_lock()`]]
+[def __timed_lock [link thread.synchronization.mutex_concepts.timed_lockable.timed_lock `timed_lock`]]
+
+[def __try_lock_for [link thread.synchronization.mutex_concepts.timed_lockable.try_lock_for `try_lock_for`]]
+[def __try_lock_until [link thread.synchronization.mutex_concepts.timed_lockable.try_lock_until `try_lock_until`]]
[template timed_lock_duration_ref_link[link_text] [link thread.synchronization.mutex_concepts.timed_lockable.timed_lock_duration [link_text]]]
[def __timed_lock_duration_ref__ [timed_lock_duration_ref_link `timed_lock()`]]
+[def __timed_lock_duration [link thread.synchronization.mutex_concepts.timed_lockable.timed_lock_duration `timed_lock`]]
[template lock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.lock_shared [link_text]]]
[def __lock_shared_ref__ [lock_shared_ref_link `lock_shared()`]]
+[def __lock_shared [link thread.synchronization.mutex_concepts.shared_lockable.lock_shared `lock_shared()`]]
[template unlock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.unlock_shared [link_text]]]
[def __unlock_shared_ref__ [unlock_shared_ref_link `unlock_shared()`]]
+[def __unlock_shared [link thread.synchronization.mutex_concepts.shared_lockable.unlock_shared `unlock_shared()`]]
[template try_lock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared [link_text]]]
[def __try_lock_shared_ref__ [try_lock_shared_ref_link `try_lock_shared()`]]
+[def __try_lock_shared [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared `try_lock_shared`]]
[template timed_lock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.timed_lock_shared [link_text]]]
[def __timed_lock_shared_ref__ [timed_lock_shared_ref_link `timed_lock_shared()`]]
+[def __try_lock_shared_for [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared_for `try_lock_shared_for`]]
+[def __try_lock_shared_for [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared_until `try_lock_shared_until`]]
[template timed_lock_shared_duration_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.timed_lock_shared_duration [link_text]]]
[def __timed_lock_shared_duration_ref__ [timed_lock_shared_duration_ref_link `timed_lock_shared()`]]
+[def __try_lock_shared_for [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared_for `try_lock_shared_for`]]
+[def __try_lock_shared_until [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared_until `try_lock_shared_until`]]
[template lock_upgrade_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.lock_upgrade [link_text]]]
[def __lock_upgrade_ref__ [lock_upgrade_ref_link `lock_upgrade()`]]
+[def __lock_upgrade [link thread.synchronization.mutex_concepts.upgrade_lockable.lock_upgrade `lock_upgrade`]]
+[def __try_lock_upgrade [link thread.synchronization.mutex_concepts.upgrade_lockable.try_lock_upgrade `try_lock_upgrade`]]
+[def __try_lock_upgrade_for [link thread.synchronization.mutex_concepts.upgrade_lockable.try_lock_upgrade_for `try_lock_upgrade_for`]]
+[def __try_lock_upgrade_until [link thread.synchronization.mutex_concepts.upgrade_lockable.try_lock_upgrade_until `try_lock_upgrade_until`]]
[template unlock_upgrade_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade [link_text]]]
[def __unlock_upgrade_ref__ [unlock_upgrade_ref_link `unlock_upgrade()`]]
+[def __unlock_upgrade [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade `unlock_upgrade`]]
[template unlock_upgrade_and_lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade_and_lock [link_text]]]
[def __unlock_upgrade_and_lock_ref__ [unlock_upgrade_and_lock_ref_link `unlock_upgrade_and_lock()`]]
+[def __unlock_upgrade_and_lock [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade_and_lock `unlock_upgrade_and_lock`]]
[template unlock_and_lock_upgrade_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_and_lock_upgrade [link_text]]]
[def __unlock_and_lock_upgrade_ref__ [unlock_and_lock_upgrade_ref_link `unlock_and_lock_upgrade()`]]
+[def __unlock_and_lock_upgrade [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_and_lock_upgrade `unlock_and_lock_upgrade`]]
[template unlock_upgrade_and_lock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade_and_lock_shared [link_text]]]
[def __unlock_upgrade_and_lock_shared_ref__ [unlock_upgrade_and_lock_shared_ref_link `unlock_upgrade_and_lock_shared()`]]
+[def __unlock_upgrade_and_lock_shared [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade_and_lock_shared `unlock_upgrade_and_lock_shared`]]
+
+
+[def __try_unlock_shared_and_lock [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_shared_and_lock `try_unlock_shared_and_lock`]]
+[def __try_unlock_shared_and_lock_for [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_shared_and_lock_for `try_unlock_shared_and_lock_for`]]
+[def __try_unlock_shared_and_lock_until [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_shared_and_lock_until `try_unlock_shared_and_lock_until`]]
+
+[def __unlock_and_lock_shared [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_and_lock_shared `unlock_and_lock_shared`]]
+
+[def __try_unlock_shared_and_lock_upgrade [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_shared_and_lock_upgrade `try_unlock_shared_and_lock_upgrade`]]
+[def __try_unlock_shared_and_lock_upgrade_for [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_shared_and_lock_upgrade_for `try_unlock_shared_and_lock_upgrade_for`]]
+[def __try_unlock_shared_and_lock_upgrade_until [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_shared_and_lock_upgrade_until `try_unlock_shared_and_lock_upgrade_until`]]
+
+[def __try_unlock_upgrade_and_lock [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_upgrade_and_lock `try_unlock_upgrade_and_lock`]]
+[def __try_unlock_upgrade_and_lock_for [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_upgrade_and_lock_for `try_unlock_upgrade_and_lock_for`]]
+[def __try_unlock_upgrade_and_lock_until [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_upgrade_and_lock_until `try_unlock_upgrade_and_lock_until`]]
+
[template owns_lock_ref_link[link_text] [link thread.synchronization.locks.unique_lock.owns_lock [link_text]]]
[def __owns_lock_ref__ [owns_lock_ref_link `owns_lock()`]]
@@ -114,17 +161,29 @@
[def __shared_lock__ [link thread.synchronization.locks.shared_lock `boost::shared_lock`]]
[def __upgrade_lock__ [link thread.synchronization.locks.upgrade_lock `boost::upgrade_lock`]]
[def __upgrade_to_unique_lock__ [link thread.synchronization.locks.upgrade_to_unique_lock `boost::upgrade_to_unique_lock`]]
+[def __reverse_lock [link thread.synchronization.other_locks.reverse_lock `reverse_lock`]]
+[def __shared_lock_guard [link thread.synchronization.other_locks.shared_lock_guard `shared_lock_guard`]]
[def __thread__ [link thread.thread_management.thread `boost::thread`]]
+[def __thread [link thread.thread_management.thread `boost::thread`]]
[def __thread_id__ [link thread.thread_management.thread.id `boost::thread::id`]]
[template join_link[link_text] [link thread.thread_management.thread.join [link_text]]]
[def __join__ [join_link `join()`]]
+
+[def __try_join_for [link thread.thread_management.thread.try_join_for `try_join_for`]]
+[def __try_join_until [link thread.thread_management.thread.try_join_until `try_join_until`]]
+
+
[template timed_join_link[link_text] [link thread.thread_management.thread.timed_join [link_text]]]
[def __timed_join__ [timed_join_link `timed_join()`]]
[def __detach__ [link thread.thread_management.thread.detach `detach()`]]
[def __interrupt__ [link thread.thread_management.thread.interrupt `interrupt()`]]
[def __sleep__ [link thread.thread_management.this_thread.sleep `boost::this_thread::sleep()`]]
+[def __sleep_for [link thread.thread_management.this_thread.sleep_for `sleep_for`]]
+[def __sleep_until [link thread.thread_management.this_thread.sleep_until `sleep_until`]]
+[def __yield [link thread.thread_management.this_thread.yield `yield`]]
+[def __get_id [link thread.thread_management.thread.get_id `get_id`]]
[def __interruption_enabled__ [link thread.thread_management.this_thread.interruption_enabled `boost::this_thread::interruption_enabled()`]]
[def __interruption_requested__ [link thread.thread_management.this_thread.interruption_requested `boost::this_thread::interruption_requested()`]]
@@ -140,11 +199,21 @@
[def __cond_wait__ [cond_wait_link `wait()`]]
[template cond_timed_wait_link[link_text] [link thread.synchronization.condvar_ref.condition_variable.timed_wait [link_text]]]
[def __cond_timed_wait__ [cond_timed_wait_link `timed_wait()`]]
+
+[def __condition_variable [link thread.synchronization.condvar_ref.condition_variable `condition_variable`]]
+[def __wait_for [link thread.synchronization.condvar_ref.condition_variable.wait_for `wait_for`]]
+[def __wait_until [link thread.synchronization.condvar_ref.condition_variable.wait_until `wait_until`]]
+
+
[template cond_any_wait_link[link_text] [link thread.synchronization.condvar_ref.condition_variable_any.wait [link_text]]]
[def __cond_any_wait__ [cond_any_wait_link `wait()`]]
[template cond_any_timed_wait_link[link_text] [link thread.synchronization.condvar_ref.condition_variable_any.timed_wait [link_text]]]
[def __cond_any_timed_wait__ [cond_any_timed_wait_link `timed_wait()`]]
+[def __condition_variable_any [link thread.synchronization.condvar_ref.condition_variable_any `condition_variable_any`]]
+[def __cvany_wait_for [link thread.synchronization.condvar_ref.condition_variable_any.wait_for `wait_for`]]
+[def __cvany_wait_until [link thread.synchronization.condvar_ref.condition_variable_any.wait_until `wait_until`]]
+
[def __blocked__ ['blocked]]
[include overview.qbk]
@@ -153,6 +222,7 @@
[include thread_ref.qbk]
[section:synchronization Synchronization]
+[include sync_tutorial.qbk]
[include mutex_concepts.qbk]
[include mutexes.qbk]
[include condition_variables.qbk]
@@ -165,6 +235,8 @@
[include time.qbk]
+[include emulations.qbk]
+
[include acknowledgements.qbk]
[include compliance.qbk]
diff --git a/libs/thread/doc/thread_ref.qbk b/libs/thread/doc/thread_ref.qbk
index aa0d5e94f2..3927de22cb 100644
--- a/libs/thread/doc/thread_ref.qbk
+++ b/libs/thread/doc/thread_ref.qbk
@@ -1,5 +1,6 @@
[/
(C) Copyright 2007-8 Anthony Williams.
+ (C) Copyright 2011-12 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
@@ -7,7 +8,46 @@
[section:thread_management Thread Management]
-[heading Synopsis]
+[section:synopsis Synopsis]
+
+ #include <boost/thread/thread.hpp>
+
+ namespace boost
+ {
+ class thread;
+ void swap(thread& lhs,thread& rhs) noexcept;
+
+ namespace this_thread
+ {
+ thread::id get_id() noexcept;
+ template<typename TimeDuration>
+ void yield() noexcept;
+ template <class Clock, class Duration>
+ void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
+ template <class Rep, class Period>
+ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
+
+ template<typename Callable>
+ void at_thread_exit(Callable func); // EXTENSION
+
+ void interruption_point(); // EXTENSION
+ bool interruption_requested() noexcept; // EXTENSION
+ bool interruption_enabled() noexcept; // EXTENSION
+ class disable_interruption; // EXTENSION
+ class restore_interruption; // EXTENSION
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
+ void sleep(TimeDuration const& rel_time);
+ void sleep(system_time const& abs_time);
+ #endif
+ }
+ class thread_group; // EXTENSION
+
+ }
+
+[endsect] [/section:synopsis Synopsis]
+
+[section:tutorial Tutorial]
The __thread__ class is responsible for launching and managing threads. Each __thread__ object represents a single thread of execution,
or __not_a_thread__, and at most one __thread__ object represents a given thread of execution: objects of type __thread__ are not
@@ -24,14 +64,14 @@ allows the details of thread creation to be wrapped in a function.
some_thread.join();
}
-[Note: On compilers that support rvalue references, __thread__ provides a proper move constructor and move-assignment operator, and
+[note On compilers that support rvalue references, __thread__ provides a proper move constructor and move-assignment operator, and
therefore meets the C++0x ['MoveConstructible] and ['MoveAssignable] concepts. With such compilers, __thread__ can therefore be used
with containers that support those concepts.
For other compilers, move support is provided with a move emulation layer, so containers must explicitly detect that move emulation
layer. See <boost/thread/detail/move.hpp> for details.]
-[heading Launching threads]
+[section:launching Launching threads]
A new thread is launched by passing an object of a callable type that can be invoked with no parameters to the constructor. The
object is then copied into internal storage, and invoked on the newly-created thread of execution. If the object must not (or
@@ -68,12 +108,99 @@ to callable functions.
There is an unspecified limit on the number of additional arguments that can be passed.
-[heading Exceptions in thread functions]
+[endsect]
+
+[section:attributes Thread attributes]
+
+Thread launched in this way are created with implementation defined thread attributes as stack size, scheduling,
+priority, ... or any platform specific attributes. It is not evident how to provide a portable interface that allows
+the user to set the platform specific attributes. Boost.Thread stay in the middle road through the class
+thread::attributes which allows to set at least in a portable way the stack size as follows:
+
+ boost::thread::attributes attrs;
+ attrs.set_size(4096*10);
+ boost::thread deep_thought_2(attrs, find_the_question, 42);
+
+Even for this simple attribute there could be portable issues as some platforms could require that the stack size
+should have a minimal size and/or be a multiple of a given page size.
+The library adapts the requested size to the platform constraints so that the user doesn't need to take care of it.
+
+This is the single attribute that is provided in a portable way. In order to set any other thread attribute at
+construction time the user needs to use non portable code.
+
+On PThread platforms the user will need to get the thread attributes handle and use it for whatever attribute.
+
+Next follows how the user could set the stack size and the scheduling policy on PThread platforms.
+
+ boost::thread::attributes attrs;
+ // set portable attributes
+ // ...
+ attr.set_stack_size(4096*10);
+ #if defined(BOOST_THREAD_PLATFORM_WIN32)
+ // ... window version
+ #elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+ // ... pthread version
+ pthread_attr_setschedpolicy(attr.get_native_handle(), SCHED_RR);
+ #else
+ #error "Boost threads unavailable on this platform"
+ #endif
+ boost::thread th(attrs, find_the_question, 42);
+
+On Windows platforms it is not so simple as there is no type that compiles the thread attributes.
+There is a linked to the creation of a thread on Windows that is emulated via the thread::attributes class. This is the LPSECURITY_ATTRIBUTES lpThreadAttributes.
+Boost.Thread provides a non portable set_security function so that the user can provide it before the thread creation as follows
+
+[/Boost.Thread creates Windows threads that are suspended. Then it calls to the virtual function set_attributes and last it resumes the thread.
+The user needs to define a class that inherits from the class thread::attributes that defines a virtual function set_attributes to set any specific Windows thread attribute.
+
+
+ class MyWinTthreadAttributes : boost::thread::attributes
+ {
+ public:
+ void set_attributes(boost::thread::native_handle_type h)
+ {
+ // use any specific windows thread setting
+
+ }
+ };
+ #if defined(BOOST_THREAD_PLATFORM_WIN32)
+
+ MyWinTthreadAttributes attrs;
+ // set portable attributes
+ // ...
+ attr.set_stack_size(4096*10);
+ boost::thread th(attrs, find_the_question, 42);
+ #else
+ #error "Platform not supported"
+ #endif
+
+]
+
+ #if defined(BOOST_THREAD_PLATFORM_WIN32)
+ boost::thread::attributes attrs;
+ // set portable attributes
+ attr.set_stack_size(4096*10);
+ // set non portable attribute
+ LPSECURITY_ATTRIBUTES sec;
+ // init sec
+ attr.set_security(sec);
+ boost::thread th(attrs, find_the_question, 42);
+ // Set other thread attributes using the native_handle_type.
+ //...
+ #else
+ #error "Platform not supported"
+ #endif
+
+[endsect]
+
+[section:exceptions Exceptions in thread functions]
If the function or callable object passed to the __thread__ constructor propagates an exception when invoked that is not of type
__thread_interrupted__, `std::terminate()` is called.
-[heading Joining and detaching]
+[endsect]
+
+[section:join Joining and detaching]
When the __thread__ object that represents a thread of execution is destroyed the thread becomes ['detached]. Once a thread is
detached, it will continue executing until the invocation of the function or callable object supplied on construction has completed,
@@ -86,7 +213,9 @@ execution represented by the __thread__ object has already completed, or the __t
returns immediately. __timed_join__ is similar, except that a call to __timed_join__ will also return if the thread being waited for
does not complete when the specified time has elapsed.
-[heading Interruption]
+[endsect]
+
+[section:interruption Interruption]
A running thread can be ['interrupted] by invoking the __interrupt__ member function of the corresponding __thread__ object. When the
interrupted thread next executes one of the specified __interruption_points__ (or if it is currently __blocked__ whilst executing one)
@@ -143,15 +272,24 @@ current thread, and interruption is requested for the current thread:
* [join_link `boost::thread::join()`]
* [timed_join_link `boost::thread::timed_join()`]
+* `boost::__thread::__try_join_for()`,
+* `boost::__thread::__try_join_until()`,
* [cond_wait_link `boost::condition_variable::wait()`]
* [cond_timed_wait_link `boost::condition_variable::timed_wait()`]
+* `boost::__condition_variable::__wait_for()`
+* `boost::__condition_variable::__wait_until()`
* [cond_any_wait_link `boost::condition_variable_any::wait()`]
* [cond_any_timed_wait_link `boost::condition_variable_any::timed_wait()`]
+* `boost::__condition_variable_any::__cvany_wait_for()`
+* `boost::__condition_variable_any::__cvany_wait_until()`
* [link thread.thread_management.thread.sleep `boost::thread::sleep()`]
-* __sleep__
+* `boost::this_thread::__sleep_for()`
+* `boost::this_thread::__sleep_until()`
* __interruption_point__
-[heading Thread IDs]
+[endsect]
+
+[section:id Thread IDs]
Objects of class __thread_id__ can be used to identify threads. Each running thread of execution has a unique ID obtainable
from the corresponding __thread__ by calling the `get_id()` member function, or by calling `boost::this_thread::get_id()` from
@@ -163,14 +301,15 @@ Each instance of __thread_id__ either refers to some thread, or __not_a_thread__
compare equal to each other, but not equal to any instances that refer to an actual thread of execution. The comparison operators on
__thread_id__ yield a total order for every non-equal thread ID.
-[heading Using native interfaces with Boost.Thread resources]
+[endsect]
+
+[section:native_in Using native interfaces with Boost.Thread resources]
__thread__ class has members `native_handle_type` and `native_handle` providing access to the underlying native handle.
This native handle can be used to change for example the scheduling.
-
In general, it is not safe to use this handle with operations that can conflict with the ones provided by Boost.Thread. An example of bad usage could be detaching a thread directly as it will not change the internals of the __thread__ instance, so for example the joinable function will continue to return true, while the native thread is no more joinable.
thread t(fct);
@@ -178,19 +317,21 @@ In general, it is not safe to use this handle with operations that can conflict
pthread_detach(hnd);
assert(t.joinable());
-[heading Using Boost.Thread interfaces in a native thread]
+[endsect]
+
+[section:native_from Using Boost.Thread interfaces in a native thread]
Any thread of execution created using the native interface is called a native thread in this documentation.
The first example of a native thread of execution is the main thread.
-The user can access to some synchronization functions related to the native current thread using the `boost::this_thread` `yield`, `sleep`, functions.
+The user can access to some synchronization functions related to the native current thread using the `boost::this_thread` `yield`, `sleep`, __sleep_for, __sleep_until, functions.
int main() {
// ...
- boost::this_thread::sleep();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
// ...
}
@@ -201,6 +342,16 @@ The `boost::this_thread` interrupt related functions behave in a degraded mode w
As the single way to interrupt a thread is through a __thread__ instance, `interruption_request()` wiil returns false for the native threads.
+[heading `pthread_exit` POSIX limitation]
+
+`pthread_exit` in glibc/NPTL causes a "forced unwind" that is almost like a C++ exception, but not quite. On Mac OS X, for example, `pthread_exit` unwinds without calling C++ destructors.
+
+This behavior is incompatible with the current Boost.Thread design, so the use of this function in a POSIX thread result in undefined behavior of any Boost.Thread function.
+
+[endsect]
+
+[endsect] [/section:tutorial Tutorial]
+
[section:thread Class `thread`]
#include <boost/thread/thread.hpp>
@@ -208,65 +359,88 @@ As the single way to interrupt a thread is through a __thread__ instance, `inter
class thread
{
public:
- thread();
+ thread() noexcept;
+ thread(const thread&) = delete;
+ thread& operator=(const thread&) = delete;
+
+ thread(thread&&) noexcept;
+ thread& operator=(thread&&) noexcept;
~thread();
template <class F>
explicit thread(F f);
+ template <class F>
+ thread(F &&f);
template <class F,class A1,class A2,...>
thread(F f,A1 a1,A2 a2,...);
+ // template <class F, class ...Args>
+ // explicit thread(F&& f, Args&&... args); // NOT YET IMPLEMENTED
template <class F>
- thread(detail::thread_move_t<F> f);
+ explicit thread(attributes& attrs, F f); // EXTENSION
+ template <class F>
+ thread(attributes& attrs, F &&f); // EXTENSION
+ // template <class F, class ...Args>
+ // explicit thread(attributes& attrs, F&& f, Args&&... args); // NOT YET IMPLEMENTED
// move support
- thread(detail::thread_move_t<thread> x);
- thread& operator=(detail::thread_move_t<thread> x);
- operator detail::thread_move_t<thread>();
- detail::thread_move_t<thread> move();
+ thread(thread && x) noexcept;
+ thread& operator=(thread && x) noexcept;
- void swap(thread& x);
+ void swap(thread& x) noexcept;
class id;
- id get_id() const;
+ class attributes;
- bool joinable() const;
- void join();
- bool timed_join(const system_time& wait_until);
+ id get_id() const noexcept;
- template<typename TimeDuration>
- bool timed_join(TimeDuration const& rel_time);
+ bool joinable() const noexcept;
+ void join();
+ template <class Rep, class Period>
+ bool try_join_for(const chrono::duration<Rep, Period>& rel_time); // EXTENSION
+ template <class Clock, class Duration>
+ bool try_join_until(const chrono::time_point<Clock, Duration>& t); // EXTENSION
void detach();
- static unsigned hardware_concurrency();
+ static unsigned hardware_concurrency() noexcept;
typedef platform-specific-type native_handle_type;
native_handle_type native_handle();
- void interrupt();
- bool interruption_requested() const;
+ void interrupt(); // EXTENSION
+ bool interruption_requested() const noexcept; // EXTENSION
+
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
+ bool timed_join(const system_time& wait_until);
+ template<typename TimeDuration>
+ bool timed_join(TimeDuration const& rel_time);
+ #endif
- // backwards compatibility
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
bool operator==(const thread& other) const;
bool operator!=(const thread& other) const;
static void yield();
static void sleep(const system_time& xt);
+ #endif
+
};
- void swap(thread& lhs,thread& rhs);
- detail::thread_move_t<thread> move(detail::thread_move_t<thread> t);
+ void swap(thread& lhs,thread& rhs) noexcept;
[section:default_constructor Default Constructor]
- thread();
+ thread() noexcept;
[variablelist
[[Effects:] [Constructs a __thread__ instance that refers to __not_a_thread__.]]
+[[Postconditions:] [`this->get_id()==thread::id()`]]
+
[[Throws:] [Nothing]]
]
@@ -275,13 +449,13 @@ As the single way to interrupt a thread is through a __thread__ instance, `inter
[section:move_constructor Move Constructor]
- thread(detail::thread_move_t<thread> other);
+ thread(thread&& other) noexcept;
[variablelist
[[Effects:] [Transfers ownership of the thread managed by `other` (if any) to the newly constructed __thread__ instance.]]
-[[Postconditions:] [`other->get_id()==thread::id()`]]
+[[Postconditions:] [`other.get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the construction]]
[[Throws:] [Nothing]]
@@ -291,15 +465,15 @@ As the single way to interrupt a thread is through a __thread__ instance, `inter
[section:move_assignment Move assignment operator]
- thread& operator=(detail::thread_move_t<thread> other);
+ thread& operator=(thread&& other) noexcept;
[variablelist
[[Effects:] [Transfers ownership of the thread managed by `other` (if
-any) to `*this`. If there was a thread previously associated with
-`*this` then that thread is detached.]]
+any) to `*this`. Version 1: If there was a thread previously associated with
+`*this` then that thread is detached, version 2: If the thread is joinable calls to std::terminate.]]
-[[Postconditions:] [`other->get_id()==thread::id()`]]
+[[Postconditions:] [`other->get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the assignment.]]
[[Throws:] [Nothing]]
@@ -314,20 +488,110 @@ any) to `*this`. If there was a thread previously associated with
[variablelist
+[[Requires:] [`Callable` must by Copyable and `func()` must be a valid expression.]]
+
+[[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
+thread of execution. If this invocation results in an exception being propagated into the internals of the thread library that is
+not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored.]]
+
+[[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs. ]]
+
+[[Error Conditions:] [
+
+[*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded.
+
+]]
+
+]
+
+[endsect]
+
+[section:attr_callable_constructor Thread Attributes Constructor EXTENSION]
+
+ template<typename Callable>
+ thread(attributes& attrs, Callable func);
+
+[variablelist
+
[[Preconditions:] [`Callable` must by copyable.]]
[[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
+thread of execution with the specified attributes. If this invocation results in an exception being propagated into the internals of the thread library that is
+not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored.
+If the attributes declare the native thread as detached, the boost::thread will be detached.]]
+
+[[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs. ]]
+
+[[Error Conditions:] [
+
+[*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded.
+
+]]
+
+]
+
+[endsect]
+
+[section:callable_move_constructor Thread Callable Move Constructor]
+
+ template<typename Callable>
+ thread(Callable &&func);
+
+[variablelist
+
+[[Preconditions:] [`Callable` must by Movable.]]
+
+[[Effects:] [`func` is moved into storage managed internally by the thread library, and that copy is invoked on a newly-created
thread of execution. If this invocation results in an exception being propagated into the internals of the thread library that is
-not of type __thread_interrupted__, then `std::terminate()` will be called.]]
+not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored.]]
-[[Postconditions:] [`*this` refers to the newly created thread of execution.]]
+[[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
-[[Throws:] [__thread_resource_error__ if an error occurs.]]
+[[Throws:] [__thread_resource_error__ if an error occurs. ]]
+
+[[Error Conditions:] [
+
+[*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded.
+
+]]
]
[endsect]
+[section:attr_callable_move_constructor Thread Attributes Move Constructor EXTENSION]
+
+ template<typename Callable>
+ thread(attributes& attrs, Callable func);
+
+[variablelist
+
+[[Preconditions:] [`Callable` must by copyable.]]
+
+[[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
+thread of execution with the specified attributes. If this invocation results in an exception being propagated into the internals of the thread library that is
+not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored.
+If the attributes declare the native thread as detached, the boost::thread will be detached.]]
+
+[[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs. ]]
+
+[[Error Conditions:] [
+
+[*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded.
+
+]]
+
+]
+
+[endsect]
+
+
[section:multiple_argument_constructor Thread Constructor with arguments]
template <class F,class A1,class A2,...>
@@ -346,6 +610,12 @@ are copied into internal storage for access by the new thread.]]]
[[Throws:] [__thread_resource_error__ if an error occurs.]]
+[[Error Conditions:] [
+
+[*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded.
+
+]]
+
[[Note:] [Currently up to nine additional arguments `a1` to `a9` can be specified in addition to the function `f`.]]
]
@@ -358,7 +628,7 @@ are copied into internal storage for access by the new thread.]]]
[variablelist
-[[Effects:] [If `*this` has an associated thread of execution, calls __detach__. Destroys `*this`.]]
+[[Effects:] [Version 1: If `*this` has an associated thread of execution, calls __detach__, Version 2: If the thread is joinable calls to std::terminate. Destroys `*this`.]]
[[Throws:] [Nothing.]]
@@ -366,9 +636,28 @@ are copied into internal storage for access by the new thread.]]]
[endsect]
+[/
+[section:v2_destructor V3 Thread Destructor]
+
+ ~thread();
+
+[variablelist
+
+[[Effects:] [If `*this` has an associated thread of execution, calls terminate. Destroys `*this`.]]
+
+[[Note:] [Either implicitly detaching or joining a `joinable()` thread in its destructor could result in difficult to debug correctness (for `detach`) or performance (for `join`) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable.]]
+
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+]
+
[section:joinable Member function `joinable()`]
- bool joinable() const;
+ bool joinable() const noexcept;
[variablelist
@@ -387,13 +676,25 @@ are copied into internal storage for access by the new thread.]]]
[variablelist
-[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
+[[Preconditions:] [the thread is joinable.]]
[[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete.]]
[[Postconditions:] [If `*this` refers to a thread of execution on entry, that thread of execution has completed. `*this` no longer refers to any thread of execution.]]
-[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
+[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted or `system_error`]]
+
+[[Error Conditions:] [
+
+[*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == std::this_thread::get_id().
+
+[/
+[*no_such_process]: if the thread is not valid.
+
+[*invalid_argument]: if the thread is not joinable.
+]
+
+]]
[[Notes:] [`join()` is one of the predefined __interruption_points__.]]
@@ -422,7 +723,19 @@ times out, `false` otherwise.]]
has completed, and `*this` no longer refers to any thread of execution. If this call to `timed_join` returns `false`, `*this` is
unchanged.]]
-[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
+[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted or `system_error`]]
+
+[[Error Conditions:] [
+
+[*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == std::this_thread::get_id().
+
+[/
+[*no_such_process]: if the thread is not valid.
+
+[*invalid_argument]: if the thread is not joinable.
+]
+
+]]
[[Notes:] [`timed_join()` is one of the predefined __interruption_points__.]]
@@ -430,13 +743,95 @@ unchanged.]]
[endsect]
+[section:try_join_for Member function `try_join_for()` EXTENSION]
+
+ template <class Rep, class Period>
+ bool try_join_for(const chrono::duration<Rep, Period>& rel_time);
+
+[variablelist
+
+[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
+
+[[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete,
+the specified duration `rel_time` has elapsed. If `*this` doesn't refer to a thread of execution, returns immediately.]]
+
+[[Returns:] [`true` if `*this` refers to a thread of execution on entry, and that thread of execution has completed before the call
+times out, `false` otherwise.]]
+
+[[Postconditions:] [If `*this` refers to a thread of execution on entry, and `try_join_for` returns `true`, that thread of execution
+has completed, and `*this` no longer refers to any thread of execution. If this call to `try_join_for` returns `false`, `*this` is
+unchanged.]]
+
+[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted or `system_error`]]
+
+[[Error Conditions:] [
+
+[*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == std::this_thread::get_id().
+
+[/
+[*no_such_process]: if the thread is not valid.
+
+[*invalid_argument]: if the thread is not joinable.
+]
+
+]]
+
+[[Notes:] [`try_join_for()` is one of the predefined __interruption_points__.]]
+
+]
+
+[endsect]
+
+[section:try_join_until Member function `try_join_until()` EXTENSION]
+
+ template <class Clock, class Duration>
+ bool try_join_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+[variablelist
+
+[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
+
+[[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete, the time `abs_time` has
+been reach. If `*this` doesn't refer to a thread of execution, returns immediately.]]
+
+[[Returns:] [`true` if `*this` refers to a thread of execution on entry, and that thread of execution has completed before the call
+times out, `false` otherwise.]]
+
+[[Postconditions:] [If `*this` refers to a thread of execution on entry, and `try_join_until` returns `true`, that thread of execution
+has completed, and `*this` no longer refers to any thread of execution. If this call to `try_join_until` returns `false`, `*this` is
+unchanged.]]
+
+[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted or `system_error`]]
+
+[[Error Conditions:] [
+
+[*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == std::this_thread::get_id().
+
+[/
+[*no_such_process]: if the thread is not valid.
+
+[*invalid_argument]: if the thread is not joinable.
+]
+
+]]
+
+[[Notes:] [`try_join_until()` is one of the predefined __interruption_points__.]]
+
+]
+
+[endsect]
+
+
+
[section:detach Member function `detach()`]
- void detach();
+ void detach() noexcept;
[variablelist
-[[Effects:] [If `*this` refers to a thread of execution, that thread of execution becomes detached, and no longer has an associated __thread__ object.]]
+[[Preconditions:] [the thread is joinable.]]
+
+[[Effects:] [The thread of execution becomes detached, and no longer has an associated __thread__ object.]]
[[Postconditions:] [`*this` no longer refers to any thread of execution.]]
@@ -449,7 +844,7 @@ unchanged.]]
[section:get_id Member function `get_id()`]
- thread::id get_id() const;
+ thread::id get_id() const noexcept;
[variablelist
@@ -481,7 +876,7 @@ predefined __interruption_points__ with interruption enabled .]]
[section:hardware_concurrency Static member function `hardware_concurrency()`]
- unsigned hardware_concurrency();
+ unsigned hardware_concurrency() noexecpt;
[variablelist
@@ -510,7 +905,7 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
[endsect]
-[section:equals `operator==`]
+[section:equals `operator==` DEPRECATED V3]
bool operator==(const thread& other) const;
@@ -518,11 +913,13 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
[[Returns:] [`get_id()==other.get_id()`]]
+[[See:] [Use `a.__get_id()==b.__get_id()` instead]]
+
]
[endsect]
-[section:not_equals `operator!=`]
+[section:not_equals `operator!=` DEPRECATED V3]
bool operator!=(const thread& other) const;
@@ -530,6 +927,8 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
[[Returns:] [`get_id()!=other.get_id()`]]
+[[See:] [Use `a.__get_id()!=b.__get_id()` instead`]]
+
]
[endsect]
@@ -546,6 +945,8 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
[[Notes:] [`sleep()` is one of the predefined __interruption_points__.]]
+[[See:] [Use `this_thread::__sleep_for()` or `this_thread::__sleep_until()`]]
+
]
[endsect]
@@ -558,13 +959,15 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
[[Effects:] [See [link thread.thread_management.this_thread.yield `boost::this_thread::yield()`].]]
+[[See:] [Use `this_thread::__yield()`]]
+
]
[endsect]
[section:swap Member function `swap()`]
- void swap(thread& other);
+ void swap(thread& other) noexcept;
[variablelist
@@ -584,7 +987,7 @@ value as `this->get_id()` prior to the call.]]
#include <boost/thread/thread.hpp>
- void swap(thread& lhs,thread& rhs);
+ void swap(thread& lhs,thread& rhs) noexcept;
[variablelist
@@ -594,26 +997,6 @@ value as `this->get_id()` prior to the call.]]
[endsect]
-[section:non_member_move Non-member function `move()`]
-
- #include <boost/thread/thread.hpp>
-
- detail::thread_move_t<thread> move(detail::thread_move_t<thread> t)
-
-[variablelist
-
-[[Returns:] [`t`.]]
-
-]
-
-Enables moving thread objects. e.g.
-
- extern void some_func();
- boost::thread t(some_func);
- boost::thread t2(boost::move(t)); // transfer thread from t to t2
-
-[endsect]
-
[section:id Class `boost::thread::id`]
@@ -622,14 +1005,14 @@ Enables moving thread objects. e.g.
class thread::id
{
public:
- id();
+ id() noexcept;
- bool operator==(const id& y) const;
- bool operator!=(const id& y) const;
- bool operator<(const id& y) const;
- bool operator>(const id& y) const;
- bool operator<=(const id& y) const;
- bool operator>=(const id& y) const;
+ bool operator==(const id& y) const noexcept;
+ bool operator!=(const id& y) const noexcept;
+ bool operator<(const id& y) const noexcept;
+ bool operator>(const id& y) const noexcept;
+ bool operator<=(const id& y) const noexcept;
+ bool operator>=(const id& y) const noexcept;
template<class charT, class traits>
friend std::basic_ostream<charT, traits>&
@@ -638,7 +1021,7 @@ Enables moving thread objects. e.g.
[section:constructor Default constructor]
- id();
+ id() noexcept;
[variablelist
@@ -652,7 +1035,7 @@ Enables moving thread objects. e.g.
[section:is_equal `operator==`]
- bool operator==(const id& y) const;
+ bool operator==(const id& y) const noexcept;
[variablelist
@@ -667,7 +1050,7 @@ otherwise.]]
[section:not_equal `operator!=`]
- bool operator!=(const id& y) const;
+ bool operator!=(const id& y) const noexcept;
[variablelist
@@ -682,7 +1065,7 @@ the other represent __not_a_thread__, `false` otherwise.]]
[section:less_than `operator<`]
- bool operator<(const id& y) const;
+ bool operator<(const id& y) const noexcept;
[variablelist
@@ -701,7 +1084,7 @@ execution.]]
[section:greater_than `operator>`]
- bool operator>(const id& y) const;
+ bool operator>(const id& y) const noexcept;
[variablelist
@@ -715,7 +1098,7 @@ execution.]]
[section:less_than_or_equal `operator<=`]
- bool operator<=(const id& y) const;
+ bool operator<=(const id& y) const noexcept;
[variablelist
@@ -729,7 +1112,7 @@ execution.]]
[section:greater_than_or_equal `operator>=`]
- bool operator>=(const id& y) const;
+ bool operator>=(const id& y) const noexcept;
[variablelist
@@ -761,17 +1144,124 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[endsect]
+[section:attributes Class `boost::thread::attributes` EXTENSION]
+
+ class thread::attributes {
+ public:
+ attributes() noexcept;
+ ~ attributes()=default;
+ // stack
+ void set_stack_size(std::size_t size) noexcept;
+ std::size_t get_stack_size() const noexcept;
+
+ #if defined BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE
+ typedef platform-specific-type native_handle_type;
+ native_handle_type* native_handle() noexcept;
+ const native_handle_type* native_handle() const noexcept;
+ #endif
+
+ };
+
+[section:constructor Default constructor]
+
+ thread_attributes() noexcept;
+
+[variablelist
+
+[[Effects:] [Constructs a thread atrributes instance with its default values.]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
+[section: set_stack_size Member function `set_stack_size()`]
+
+ void set_stack_size(std::size_t size) noexcept;
+
+[variablelist
+
+[[Effects:] [Stores the stack size to be used to create a thread. This is an hint that the implementation can choose a better size if to small or too big or not aligned to a page.]]
+
+[[Postconditions:] [`this-> get_stack_size()` returns the chosen stack size.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:get_stack_size Member function `get_stack_size()`]
+
+ std::size_t get_stack_size() const noexcept;
+
+[variablelist
+
+[[Returns:] [The stack size to be used on the creation of a thread. Note that this function can return 0 meaning the default.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
[endsect]
+[section:nativehandle Member function `native_handle()`]
+
+ typedef platform-specific-type native_handle_type;
+ typedef platform-specific-type native_handle_type;
+ native_handle_type* native_handle() noexcept;
+ const native_handle_type* native_handle() const noexcept;
+
+[variablelist
+
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+thread attributes implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present and `BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE` is not defined.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+[endsect] [/ thread::attributes ]
+[endsect] [/ thread ]
+
[section:this_thread Namespace `this_thread`]
+
+ namespace boost {
+ namespace this_thread {
+ thread::id get_id() noexcept;
+ template<typename TimeDuration>
+ void yield() noexcept;
+ template <class Clock, class Duration>
+ void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
+ template <class Rep, class Period>
+ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
+
+ template<typename Callable>
+ void at_thread_exit(Callable func); // EXTENSION
+
+ void interruption_point(); // EXTENSION
+ bool interruption_requested() noexcept; // EXTENSION
+ bool interruption_enabled() noexcept; // EXTENSION
+ class disable_interruption; // EXTENSION
+ class restore_interruption; // EXTENSION
+
+ #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
+ void sleep(TimeDuration const& rel_time);
+ void sleep(system_time const& abs_time)
+ #endif
+ }
+ }
+
[section:get_id Non-member function `get_id()`]
#include <boost/thread/thread.hpp>
namespace this_thread
{
- thread::id get_id();
+ thread::id get_id() noexcept;
}
[variablelist
@@ -784,7 +1274,7 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[endsect]
-[section:interruption_point Non-member function `interruption_point()`]
+[section:interruption_point Non-member function `interruption_point()` EXTENSION]
#include <boost/thread/thread.hpp>
@@ -803,13 +1293,13 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[endsect]
-[section:interruption_requested Non-member function `interruption_requested()`]
+[section:interruption_requested Non-member function `interruption_requested()` EXTENSION]
#include <boost/thread/thread.hpp>
namespace this_thread
{
- bool interruption_requested();
+ bool interruption_requested() noexcept;
}
[variablelist
@@ -822,13 +1312,13 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[endsect]
-[section:interruption_enabled Non-member function `interruption_enabled()`]
+[section:interruption_enabled Non-member function `interruption_enabled()` EXTENSION]
#include <boost/thread/thread.hpp>
namespace this_thread
{
- bool interruption_enabled();
+ bool interruption_enabled() noexcept;
}
[variablelist
@@ -862,17 +1352,68 @@ specified by `rel_time` has elapsed or the time point specified by
[[Notes:] [`sleep()` is one of the predefined __interruption_points__.]]
+[[See:] [Use `__sleep_for()` and `__sleep_until()` instead.]]
+
+]
+
+[endsect]
+
+[section:sleep_until Non-member function `sleep_until()`]
+
+ #include <boost/thread/thread.hpp>
+
+ namespace this_thread
+ {
+ template <class Clock, class Duration>
+ void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
+ }
+
+[variablelist
+
+[[Effects:] [Suspends the current thread until the time period
+specified by `rel_time` has elapsed or the time point specified by
+`abs_time` has been reached.]]
+
+[[Throws:] [Nothing if Clock satisfies the TrivialClock requirements and operations of Duration
+do not throw exceptions. __thread_interrupted__ if the current thread of execution is interrupted. ]]
+
+[[Notes:] [`sleep_until()` is one of the predefined __interruption_points__.]]
+
]
[endsect]
+[section:sleep_for Non-member function `sleep_for()`]
+
+ #include <boost/thread/thread.hpp>
+
+ namespace this_thread
+ {
+ template <class Rep, class Period>
+ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
+ }
+
+[variablelist
+
+[[Effects:] [Suspends the current thread until the time point specified by
+`abs_time` has been reached.]]
+
+[[Throws:] [Nothing if operations of chrono::duration<Rep, Period> do not throw exceptions. __thread_interrupted__ if the current thread of execution is interrupted.]]
+
+[[Notes:] [`sleep_for()` is one of the predefined __interruption_points__.]]
+
+]
+
+[endsect]
+
+
[section:yield Non-member function `yield()`]
#include <boost/thread/thread.hpp>
namespace this_thread
{
- void yield();
+ void yield() noexcept;
}
[variablelist
@@ -885,7 +1426,7 @@ specified by `rel_time` has elapsed or the time point specified by
[endsect]
-[section:disable_interruption Class `disable_interruption`]
+[section:disable_interruption Class `disable_interruption` EXTENSION]
#include <boost/thread/thread.hpp>
@@ -894,8 +1435,10 @@ specified by `rel_time` has elapsed or the time point specified by
class disable_interruption
{
public:
- disable_interruption();
- ~disable_interruption();
+ disable_interruption(const disable_interruption&) = delete;
+ disable_interruption& operator=(const disable_interruption&) = delete;
+ disable_interruption() noexcept;
+ ~disable_interruption() noexcept;
};
}
@@ -904,7 +1447,7 @@ interruption state on destruction. Instances of `disable_interruption` cannot be
[section:constructor Constructor]
- disable_interruption();
+ disable_interruption() noexcept;
[variablelist
@@ -920,7 +1463,7 @@ interruption state on destruction. Instances of `disable_interruption` cannot be
[section:destructor Destructor]
- ~disable_interruption();
+ ~disable_interruption() noexcept;
[variablelist
@@ -938,7 +1481,7 @@ interruption state on destruction. Instances of `disable_interruption` cannot be
[endsect]
-[section:restore_interruption Class `restore_interruption`]
+[section:restore_interruption Class `restore_interruption` EXTENSION]
#include <boost/thread/thread.hpp>
@@ -947,8 +1490,10 @@ interruption state on destruction. Instances of `disable_interruption` cannot be
class restore_interruption
{
public:
- explicit restore_interruption(disable_interruption& disabler);
- ~restore_interruption();
+ restore_interruption(const restore_interruption&) = delete;
+ restore_interruption& operator=(const restore_interruption&) = delete;
+ explicit restore_interruption(disable_interruption& disabler) noexcept;
+ ~restore_interruption() noexcept;
};
}
@@ -958,7 +1503,7 @@ is destroyed, interruption is again disabled. Instances of `restore_interruption
[section:constructor Constructor]
- explicit restore_interruption(disable_interruption& disabler);
+ explicit restore_interruption(disable_interruption& disabler) noexcept;
[variablelist
@@ -976,7 +1521,7 @@ is destroyed, interruption is again disabled. Instances of `restore_interruption
[section:destructor Destructor]
- ~restore_interruption();
+ ~restore_interruption() noexcept;
[variablelist
@@ -994,7 +1539,7 @@ is destroyed, interruption is again disabled. Instances of `restore_interruption
[endsect]
-[section:atthreadexit Non-member function template `at_thread_exit()`]
+[section:atthreadexit Non-member function template `at_thread_exit()` EXTENSION]
#include <boost/thread/thread.hpp>
diff --git a/libs/thread/doc/time.qbk b/libs/thread/doc/time.qbk
index 879854279a..bf6af0b5a5 100644
--- a/libs/thread/doc/time.qbk
+++ b/libs/thread/doc/time.qbk
@@ -5,19 +5,31 @@
http://www.boost.org/LICENSE_1_0.txt).
]
-[section:time Date and Time Requirements]
+[section:time Time Requirements]
-As of Boost 1.35.0, the __boost_thread__ library uses the [link date_time Boost.Date_Time] library for all operations that require a
-time out. These include (but are not limited to):
+As of Boost 1.50.0, the __boost_thread__ library uses Boost.Chrono library for all operations that require a
+time out as defined in the standard c++11. These include (but are not limited to):
+
+* __sleep_for
+* __sleep_until
+* __try_join_for
+* __try_join_until
+* __wait_for
+* __wait_until
+* __try_lock_for
+* __try_lock_until
+
+[section:deprecated Deprecated]
+The time related functions introduced in Boost 1.35.0, using the [link date_time Boost.Date_Time] library are deprecated. These include (but are not limited to):
* __sleep__
* __timed_join__
* __cond_timed_wait__
* __timed_lock_ref__
-For the overloads that accept an absolute time parameter, an object of type [link thread.time.system_time `boost::system_time`] is
+For the overloads that accept an absolute time parameter, an object of type [link thread.time.deprecated.system_time `boost::system_time`] is
required. Typically, this will be obtained by adding a duration to the current time, obtained with a call to [link
-thread.time.get_system_time `boost::get_system_time()`]. e.g.
+thread.time.deprecated.get_system_time `boost::get_system_time()`]. e.g.
boost::system_time const timeout=boost::get_system_time() + boost::posix_time::milliseconds(500);
@@ -70,6 +82,7 @@ See the documentation for [link date_time.posix_time.ptime_class `boost::posix_t
]
[endsect]
+[endsect]
[endsect] \ No newline at end of file
diff --git a/libs/thread/example/condition.cpp b/libs/thread/example/condition.cpp
index 7430e4621d..52475d6c8d 100644
--- a/libs/thread/example/condition.cpp
+++ b/libs/thread/example/condition.cpp
@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <iostream>
diff --git a/libs/thread/example/monitor.cpp b/libs/thread/example/monitor.cpp
index 0a7383fb47..ff02f5b65a 100644
--- a/libs/thread/example/monitor.cpp
+++ b/libs/thread/example/monitor.cpp
@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <vector>
@@ -89,6 +89,7 @@ private:
template <typename M>
void do_test(M* dummy=0)
{
+ (void)dummy;
typedef buffer_t<M> buffer_type;
buffer_type::get_buffer();
boost::thread thrd1(&buffer_type::do_receiver_thread);
diff --git a/libs/thread/example/once.cpp b/libs/thread/example/once.cpp
index 5a5b6f5589..3de3c45b6f 100644
--- a/libs/thread/example/once.cpp
+++ b/libs/thread/example/once.cpp
@@ -1,15 +1,22 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#define BOOST_THREAD_PROVIDES_ONCE_CXX11
+
#include <boost/thread/thread.hpp>
#include <boost/thread/once.hpp>
#include <cassert>
int value=0;
+#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+boost::once_flag once;
+#else
boost::once_flag once = BOOST_ONCE_INIT;
+boost::once_flag once2 = once;
+#endif
void init()
{
@@ -21,7 +28,7 @@ void thread_proc()
boost::call_once(&init, once);
}
-int main(int argc, char* argv[])
+int main()
{
boost::thread_group threads;
for (int i=0; i<5; ++i)
diff --git a/libs/thread/example/shared_monitor.cpp b/libs/thread/example/shared_monitor.cpp
new file mode 100644
index 0000000000..c00cc3c0c5
--- /dev/null
+++ b/libs/thread/example/shared_monitor.cpp
@@ -0,0 +1,143 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#if defined BOOST_THREAD_DONT_USE_CHRONO
+#include <boost/chrono/chrono_io.hpp>
+#endif
+#include <cassert>
+#include <vector>
+
+#define EXCLUSIVE 1
+#define SHARED 2
+
+#define MODE SHARED
+
+class A
+{
+#if MODE == EXCLUSIVE
+ typedef boost::mutex mutex_type;
+#elif MODE == SHARED
+ typedef boost::shared_mutex mutex_type;
+#else
+#error MODE not set
+#endif
+ typedef std::vector<double> C;
+ mutable mutex_type mut_;
+ C data_;
+public:
+ A() : data_(10000000) {}
+ A(const A& a);
+ A& operator=(const A& a);
+
+ void compute(const A& x, const A& y);
+};
+
+A::A(const A& a)
+{
+#if MODE == EXCLUSIVE
+ boost::unique_lock<mutex_type> lk(a.mut_);
+#elif MODE == SHARED
+ boost::shared_lock<mutex_type> lk(a.mut_);
+#else
+#error MODE not set
+#endif
+ data_ = a.data_;
+}
+
+A&
+A::operator=(const A& a)
+{
+ if (this != &a)
+ {
+ boost::unique_lock<mutex_type> lk1(mut_, boost::defer_lock);
+#if MODE == EXCLUSIVE
+ boost::unique_lock<mutex_type> lk2(a.mut_, boost::defer_lock);
+#elif MODE == SHARED
+ boost::shared_lock<mutex_type> lk2(a.mut_, boost::defer_lock);
+#else
+#error MODE not set
+#endif
+ boost::lock(lk1, lk2);
+ data_ = a.data_;
+ }
+ return *this;
+}
+
+void
+A::compute(const A& x, const A& y)
+{
+ boost::unique_lock<mutex_type> lk1(mut_, boost::defer_lock);
+#if MODE == EXCLUSIVE
+ boost::unique_lock<mutex_type> lk2(x.mut_, boost::defer_lock);
+ boost::unique_lock<mutex_type> lk3(y.mut_, boost::defer_lock);
+#elif MODE == SHARED
+ boost::shared_lock<mutex_type> lk2(x.mut_, boost::defer_lock);
+ boost::shared_lock<mutex_type> lk3(y.mut_, boost::defer_lock);
+#else
+#error MODE not set
+#endif
+ boost::lock(lk1, lk2, lk3);
+ assert(data_.size() == x.data_.size());
+ assert(data_.size() == y.data_.size());
+ for (unsigned i = 0; i < data_.size(); ++i)
+ data_[i] = (x.data_[i] + y.data_[i]) / 2;
+}
+
+A a1;
+A a2;
+
+void test_s()
+{
+ A la3 = a1;
+ for (int i = 0; i < 150; ++i)
+ {
+ la3.compute(a1, a2);
+ }
+}
+
+void test_w()
+{
+ A la3 = a1;
+ for (int i = 0; i < 10; ++i)
+ {
+ la3.compute(a1, a2);
+ a1 = la3;
+ a2 = la3;
+#if defined BOOST_THREAD_DONT_USE_CHRONO
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+#endif
+ }
+}
+
+int main()
+{
+#if defined BOOST_THREAD_DONT_USE_CHRONO
+ typedef boost::chrono::high_resolution_clock Clock;
+ typedef boost::chrono::duration<double> sec;
+ Clock::time_point t0 = Clock::now();
+#endif
+ std::vector<boost::thread*> v;
+ boost::thread thw(test_w);
+ v.push_back(&thw);
+ boost::thread thr0(test_w);
+ v.push_back(&thr0);
+ boost::thread thr1(test_w);
+ v.push_back(&thr1);
+ boost::thread thr2(test_w);
+ v.push_back(&thr2);
+ boost::thread thr3(test_w);
+ v.push_back(&thr3);
+ for (std::size_t i = 0; i < v.size(); ++i)
+ v[i]->join();
+#if defined BOOST_THREAD_DONT_USE_CHRONO
+ Clock::time_point t1 = Clock::now();
+ std::cout << sec(t1-t0) << '\n';
+#endif
+ return 0;
+}
diff --git a/libs/thread/example/shared_mutex.cpp b/libs/thread/example/shared_mutex.cpp
new file mode 100644
index 0000000000..ead68c2df9
--- /dev/null
+++ b/libs/thread/example/shared_mutex.cpp
@@ -0,0 +1,745 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <iostream>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <vector>
+
+#if defined BOOST_THREAD_USES_CHRONO
+#include <boost/chrono/chrono_io.hpp>
+
+
+enum {reading, writing};
+int state = reading;
+
+#if 1
+
+boost::mutex&
+cout_mut()
+{
+ static boost::mutex m;
+ return m;
+}
+
+void
+print(const char* tag, unsigned count, char ch)
+{
+ boost::lock_guard<boost::mutex> _(cout_mut());
+ std::cout << tag << count << ch;
+}
+
+#elif 0
+
+boost::recursive_mutex&
+cout_mut()
+{
+ static boost::recursive_mutex m;
+ return m;
+}
+
+void print() {}
+
+template <class A0, class ...Args>
+void
+print(const A0& a0, const Args& ...args)
+{
+ boost::lock_guard<boost::recursive_mutex> _(cout_mut());
+ std::cout << a0;
+ print(args...);
+}
+
+#else
+
+template <class A0, class A1, class A2>
+void
+print(const A0&, const A1& a1, const A2&)
+{
+ assert(a1 > 10000);
+}
+
+#endif
+
+namespace S
+{
+
+boost::shared_mutex mut;
+
+void reader()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock_shared();
+ assert(state == reading);
+ ++count;
+ mut.unlock_shared();
+ }
+ print("reader = ", count, '\n');
+}
+
+void writer()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock();
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ ++count;
+ mut.unlock();
+ }
+ print("writer = ", count, '\n');
+}
+
+void try_reader()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_shared())
+ {
+ assert(state == reading);
+ ++count;
+ mut.unlock_shared();
+ }
+ }
+ print("try_reader = ", count, '\n');
+}
+
+void try_writer()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock())
+ {
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ ++count;
+ mut.unlock();
+ }
+ }
+ print("try_writer = ", count, '\n');
+}
+
+void try_for_reader()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_shared_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ ++count;
+ mut.unlock_shared();
+ }
+ }
+ print("try_for_reader = ", count, '\n');
+}
+
+void try_for_writer()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_for(boost::chrono::microseconds(5)))
+ {
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ ++count;
+ mut.unlock();
+ }
+ }
+ print("try_for_writer = ", count, '\n');
+}
+
+void
+test_shared_mutex()
+{
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(reader);
+ boost::thread t2(writer);
+ boost::thread t3(reader);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(try_reader);
+ boost::thread t2(try_writer);
+ boost::thread t3(try_reader);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(try_for_reader);
+ boost::thread t2(try_for_writer);
+ boost::thread t3(try_for_reader);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+}
+
+}
+
+namespace U
+{
+
+boost::upgrade_mutex mut;
+
+void reader()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock_shared();
+ assert(state == reading);
+ ++count;
+ mut.unlock_shared();
+ }
+ print("reader = ", count, '\n');
+}
+
+void writer()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock();
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ ++count;
+ mut.unlock();
+ }
+ print("writer = ", count, '\n');
+}
+
+void try_reader()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_shared())
+ {
+ assert(state == reading);
+ ++count;
+ mut.unlock_shared();
+ }
+ }
+ print("try_reader = ", count, '\n');
+}
+
+void try_writer()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock())
+ {
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ ++count;
+ mut.unlock();
+ }
+ }
+ print("try_writer = ", count, '\n');
+}
+
+void try_for_reader()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_shared_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ ++count;
+ mut.unlock_shared();
+ }
+ }
+ print("try_for_reader = ", count, '\n');
+}
+
+void try_for_writer()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_for(boost::chrono::microseconds(5)))
+ {
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ ++count;
+ mut.unlock();
+ }
+ }
+ print("try_for_writer = ", count, '\n');
+}
+
+void upgradable()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock_upgrade();
+ assert(state == reading);
+ ++count;
+ mut.unlock_upgrade();
+ }
+ print("upgradable = ", count, '\n');
+}
+
+void try_upgradable()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_upgrade())
+ {
+ assert(state == reading);
+ ++count;
+ mut.unlock_upgrade();
+ }
+ }
+ print("try_upgradable = ", count, '\n');
+}
+
+void try_for_upgradable()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_upgrade_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ ++count;
+ mut.unlock_upgrade();
+ }
+ }
+ print("try_for_upgradable = ", count, '\n');
+}
+
+void clockwise()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock_shared();
+ assert(state == reading);
+ if (mut.try_unlock_shared_and_lock())
+ {
+ state = writing;
+ }
+ else if (mut.try_unlock_shared_and_lock_upgrade())
+ {
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock();
+ state = writing;
+ }
+ else
+ {
+ mut.unlock_shared();
+ continue;
+ }
+ assert(state == writing);
+ state = reading;
+ mut.unlock_and_lock_upgrade();
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock_shared();
+ assert(state == reading);
+ mut.unlock_shared();
+ ++count;
+ }
+ print("clockwise = ", count, '\n');
+}
+
+void counter_clockwise()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ mut.lock_upgrade();
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock();
+ assert(state == reading);
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ mut.unlock_and_lock_shared();
+ assert(state == reading);
+ mut.unlock_shared();
+ ++count;
+ }
+ print("counter_clockwise = ", count, '\n');
+}
+
+void try_clockwise()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_shared())
+ {
+ assert(state == reading);
+ if (mut.try_unlock_shared_and_lock())
+ {
+ state = writing;
+ }
+ else if (mut.try_unlock_shared_and_lock_upgrade())
+ {
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock();
+ state = writing;
+ }
+ else
+ {
+ mut.unlock_shared();
+ continue;
+ }
+ assert(state == writing);
+ state = reading;
+ mut.unlock_and_lock_upgrade();
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock_shared();
+ assert(state == reading);
+ mut.unlock_shared();
+ ++count;
+ }
+ }
+ print("try_clockwise = ", count, '\n');
+}
+
+void try_for_clockwise()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_shared_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ if (mut.try_unlock_shared_and_lock_for(boost::chrono::microseconds(5)))
+ {
+ state = writing;
+ }
+ else if (mut.try_unlock_shared_and_lock_upgrade_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock();
+ state = writing;
+ }
+ else
+ {
+ mut.unlock_shared();
+ continue;
+ }
+ assert(state == writing);
+ state = reading;
+ mut.unlock_and_lock_upgrade();
+ assert(state == reading);
+ mut.unlock_upgrade_and_lock_shared();
+ assert(state == reading);
+ mut.unlock_shared();
+ ++count;
+ }
+ }
+ print("try_for_clockwise = ", count, '\n');
+}
+
+void try_counter_clockwise()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_upgrade())
+ {
+ assert(state == reading);
+ if (mut.try_unlock_upgrade_and_lock())
+ {
+ assert(state == reading);
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ mut.unlock_and_lock_shared();
+ assert(state == reading);
+ mut.unlock_shared();
+ ++count;
+ }
+ else
+ {
+ mut.unlock_upgrade();
+ }
+ }
+ }
+ print("try_counter_clockwise = ", count, '\n');
+}
+
+void try_for_counter_clockwise()
+{
+ typedef boost::chrono::steady_clock Clock;
+ unsigned count = 0;
+ Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
+ while (Clock::now() < until)
+ {
+ if (mut.try_lock_upgrade_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ if (mut.try_unlock_upgrade_and_lock_for(boost::chrono::microseconds(5)))
+ {
+ assert(state == reading);
+ state = writing;
+ assert(state == writing);
+ state = reading;
+ mut.unlock_and_lock_shared();
+ assert(state == reading);
+ mut.unlock_shared();
+ ++count;
+ }
+ else
+ {
+ mut.unlock_upgrade();
+ }
+ }
+ }
+ print("try_for_counter_clockwise = ", count, '\n');
+}
+
+void
+test_upgrade_mutex()
+{
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(reader);
+ boost::thread t2(writer);
+ boost::thread t3(reader);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(try_reader);
+ boost::thread t2(try_writer);
+ boost::thread t3(try_reader);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(try_for_reader);
+ boost::thread t2(try_for_writer);
+ boost::thread t3(try_for_reader);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(reader);
+ boost::thread t2(writer);
+ boost::thread t3(upgradable);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(reader);
+ boost::thread t2(writer);
+ boost::thread t3(try_upgradable);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ boost::thread t1(reader);
+ boost::thread t2(writer);
+ boost::thread t3(try_for_upgradable);
+ t1.join();
+ t2.join();
+ t3.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ state = reading;
+ boost::thread t1(clockwise);
+ boost::thread t2(counter_clockwise);
+ boost::thread t3(clockwise);
+ boost::thread t4(counter_clockwise);
+ t1.join();
+ t2.join();
+ t3.join();
+ t4.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ {
+ state = reading;
+ boost::thread t1(try_clockwise);
+ boost::thread t2(try_counter_clockwise);
+ t1.join();
+ t2.join();
+ }
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+// {
+// state = reading;
+// boost::thread t1(try_for_clockwise);
+// boost::thread t2(try_for_counter_clockwise);
+// t1.join();
+// t2.join();
+// }
+// std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+}
+
+}
+
+namespace Assignment
+{
+
+class A
+{
+ typedef boost::upgrade_mutex mutex_type;
+ typedef boost::shared_lock<mutex_type> SharedLock;
+ typedef boost::upgrade_lock<mutex_type> UpgradeLock;
+ typedef boost::unique_lock<mutex_type> Lock;
+
+ mutable mutex_type mut_;
+ std::vector<double> data_;
+
+public:
+
+ A(const A& a)
+ {
+ SharedLock _(a.mut_);
+ data_ = a.data_;
+ }
+
+ A& operator=(const A& a)
+ {
+ if (this != &a)
+ {
+ Lock this_lock(mut_, boost::defer_lock);
+ SharedLock that_lock(a.mut_, boost::defer_lock);
+ boost::lock(this_lock, that_lock);
+ data_ = a.data_;
+ }
+ return *this;
+ }
+
+ void swap(A& a)
+ {
+ Lock this_lock(mut_, boost::defer_lock);
+ Lock that_lock(a.mut_, boost::defer_lock);
+ boost::lock(this_lock, that_lock);
+ data_.swap(a.data_);
+ }
+
+ void average(A& a)
+ {
+ assert(data_.size() == a.data_.size());
+ assert(this != &a);
+
+ Lock this_lock(mut_, boost::defer_lock);
+ UpgradeLock share_that_lock(a.mut_, boost::defer_lock);
+ boost::lock(this_lock, share_that_lock);
+
+ for (unsigned i = 0; i < data_.size(); ++i)
+ data_[i] = (data_[i] + a.data_[i]) / 2;
+
+ SharedLock share_this_lock(boost::move(this_lock));
+ Lock that_lock(boost::move(share_that_lock));
+ a.data_ = data_;
+ }
+};
+
+} // Assignment
+
+void temp()
+{
+ using namespace boost;
+ static upgrade_mutex mut;
+ unique_lock<upgrade_mutex> ul(mut);
+ shared_lock<upgrade_mutex> sl;
+ sl = BOOST_THREAD_MAKE_RV_REF(shared_lock<upgrade_mutex>(boost::move(ul)));
+}
+
+int main()
+{
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ typedef boost::chrono::high_resolution_clock Clock;
+ typedef boost::chrono::duration<double> sec;
+ Clock::time_point t0 = Clock::now();
+
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ S::test_shared_mutex();
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ U::test_upgrade_mutex();
+ std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
+ Clock::time_point t1 = Clock::now();
+ std::cout << sec(t1 - t0) << '\n';
+ return 0;
+}
+
+#else
+#error "This platform doesn't support Boost.Chrono"
+#endif
diff --git a/libs/thread/example/starvephil.cpp b/libs/thread/example/starvephil.cpp
index 0ef2e0d32d..85e8c8928b 100644
--- a/libs/thread/example/starvephil.cpp
+++ b/libs/thread/example/starvephil.cpp
@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/mutex.hpp>
@@ -50,7 +50,7 @@ public:
<< "very hot ..." << std::endl;
}
boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
+ boost::xtime_get(&xt, boost::TIME_UTC_);
xt.sec += 3;
boost::thread::sleep(xt);
m_chickens += value;
@@ -85,7 +85,7 @@ void chef()
std::cout << "(" << clock() << ") Chef: cooking ..." << std::endl;
}
boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
+ boost::xtime_get(&xt, boost::TIME_UTC_);
xt.sec += 2;
boost::thread::sleep(xt);
{
@@ -111,7 +111,7 @@ struct phil
if (m_id > 0)
{
boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
+ boost::xtime_get(&xt, boost::TIME_UTC_);
xt.sec += 3;
boost::thread::sleep(xt);
}
@@ -164,7 +164,7 @@ private:
void* _param;
};
-int main(int argc, char* argv[])
+int main()
{
boost::thread thrd_chef(&chef);
phil p[] = { phil(0), phil(1), phil(2), phil(3), phil(4) };
diff --git a/libs/thread/example/tennis.cpp b/libs/thread/example/tennis.cpp
index 798f55e5d8..1a45eb1ffa 100644
--- a/libs/thread/example/tennis.cpp
+++ b/libs/thread/example/tennis.cpp
@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/mutex.hpp>
@@ -104,7 +104,7 @@ int main(int argc, char* argv[])
boost::thread thrdb(thread_adapter(&player, (void*)PLAYER_B));
boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
+ boost::xtime_get(&xt, boost::TIME_UTC_);
xt.sec += 1;
boost::thread::sleep(xt);
{
diff --git a/libs/thread/example/thread.cpp b/libs/thread/example/thread.cpp
index c21a3b5ea8..ebd77977e5 100644
--- a/libs/thread/example/thread.cpp
+++ b/libs/thread/example/thread.cpp
@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread.hpp>
@@ -14,7 +14,7 @@ struct thread_alarm
void operator()()
{
boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
+ boost::xtime_get(&xt, boost::TIME_UTC_);
xt.sec += m_secs;
boost::thread::sleep(xt);
@@ -25,7 +25,7 @@ struct thread_alarm
int m_secs;
};
-int main(int argc, char* argv[])
+int main()
{
int secs = 5;
std::cout << "setting alarm for 5 seconds..." << std::endl;
diff --git a/libs/thread/example/thread_group.cpp b/libs/thread/example/thread_group.cpp
index 232776dc62..fd11a57cf6 100644
--- a/libs/thread/example/thread_group.cpp
+++ b/libs/thread/example/thread_group.cpp
@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread.hpp>
@@ -16,7 +16,7 @@ void increment_count()
std::cout << "count = " << ++count << std::endl;
}
-int main(int argc, char* argv[])
+int main()
{
boost::thread_group threads;
for (int i = 0; i < 10; ++i)
diff --git a/libs/thread/example/tss.cpp b/libs/thread/example/tss.cpp
index f867a9180a..0b8a2b32a9 100644
--- a/libs/thread/example/tss.cpp
+++ b/libs/thread/example/tss.cpp
@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread.hpp>
@@ -27,7 +27,7 @@ void thread_proc()
}
}
-int main(int argc, char* argv[])
+int main()
{
boost::thread_group threads;
for (int i=0; i<5; ++i)
diff --git a/libs/thread/example/xtime.cpp b/libs/thread/example/xtime.cpp
index a9b1933908..91646e6bb5 100644
--- a/libs/thread/example/xtime.cpp
+++ b/libs/thread/example/xtime.cpp
@@ -1,16 +1,16 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
-int main(int argc, char* argv[])
+int main()
{
boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
+ boost::xtime_get(&xt, boost::TIME_UTC_);
xt.sec += 1;
boost::thread::sleep(xt); // Sleep for 1 second
}
diff --git a/libs/thread/src/future.cpp b/libs/thread/src/future.cpp
new file mode 100755
index 0000000000..84e823bdf2
--- /dev/null
+++ b/libs/thread/src/future.cpp
@@ -0,0 +1,61 @@
+// (C) Copyright 2012 Vicente J. Botet Escriba
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread/detail/config.hpp>
+#ifndef BOOST_NO_EXCEPTIONS
+
+
+#include <boost/thread/future.hpp>
+
+namespace boost
+{
+
+ namespace thread_detail
+ {
+
+ class future_error_category :
+ public boost::system::error_category
+ {
+ public:
+ virtual const char* name() const; //BOOST_NOEXCEPT;
+ virtual std::string message(int ev) const;
+ };
+
+ const char*
+ future_error_category::name() const //BOOST_NOEXCEPT
+ {
+ return "future";
+ }
+
+ std::string
+ future_error_category::message(int ev) const
+ {
+ switch (BOOST_SCOPED_ENUM_NATIVE(future_errc)(ev))
+ {
+ case future_errc::broken_promise:
+ return std::string("The associated promise has been destructed prior "
+ "to the associated state becoming ready.");
+ case future_errc::future_already_retrieved:
+ return std::string("The future has already been retrieved from "
+ "the promise or packaged_task.");
+ case future_errc::promise_already_satisfied:
+ return std::string("The state of the promise has already been set.");
+ case future_errc::no_state:
+ return std::string("Operation not permitted on an object without "
+ "an associated state.");
+ }
+ return std::string("unspecified future_errc value\n");
+ }
+ }
+
+ const system::error_category&
+ future_category()
+ {
+ static thread_detail::future_error_category f;
+ return f;
+ }
+
+}
+#endif
diff --git a/libs/thread/src/pthread/once.cpp b/libs/thread/src/pthread/once.cpp
index 6e0466f17e..a1d8a82dd4 100644
--- a/libs/thread/src/pthread/once.cpp
+++ b/libs/thread/src/pthread/once.cpp
@@ -1,6 +1,6 @@
// Copyright (C) 2007 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define __STDC_CONSTANT_MACROS
@@ -8,6 +8,7 @@
#include <boost/assert.hpp>
#include <pthread.h>
#include <stdlib.h>
+#include <memory>
namespace boost
{
@@ -21,7 +22,7 @@ namespace boost
{
pthread_key_t epoch_tss_key;
pthread_once_t epoch_tss_key_flag=PTHREAD_ONCE_INIT;
-
+
extern "C"
{
static void delete_epoch_tss_data(void* data)
@@ -34,8 +35,26 @@ namespace boost
BOOST_VERIFY(!pthread_key_create(&epoch_tss_key,delete_epoch_tss_data));
}
}
+
+#if defined BOOST_THREAD_PATCH
+ const pthread_once_t pthread_once_init_value=PTHREAD_ONCE_INIT;
+ struct BOOST_THREAD_DECL delete_epoch_tss_key_on_dlclose_t
+ {
+ delete_epoch_tss_key_on_dlclose_t()
+ {
+ }
+ ~delete_epoch_tss_key_on_dlclose_t()
+ {
+ if(memcmp(&epoch_tss_key_flag, &pthread_once_init_value, sizeof(pthread_once_t)))
+ {
+ pthread_key_delete(epoch_tss_key);
+ }
+ }
+ };
+ delete_epoch_tss_key_on_dlclose_t delete_epoch_tss_key_on_dlclose;
+#endif
}
-
+
boost::uintmax_t& get_once_per_thread_epoch()
{
BOOST_VERIFY(!pthread_once(&epoch_tss_key_flag,create_epoch_tss_key));
@@ -49,5 +68,5 @@ namespace boost
return *static_cast<boost::uintmax_t*>(data);
}
}
-
+
}
diff --git a/libs/thread/src/pthread/thread.cpp b/libs/thread/src/pthread/thread.cpp
index 07b8458bce..2b9b95f0bd 100644
--- a/libs/thread/src/pthread/thread.cpp
+++ b/libs/thread/src/pthread/thread.cpp
@@ -1,6 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
// Copyright (C) 2007-8 Anthony Williams
+// (C) Copyright 2011 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -23,7 +24,7 @@
#include <unistd.h>
#endif
-#include "timeconv.inl"
+#include <libs/thread/src/pthread/timeconv.inl>
namespace boost
{
@@ -45,7 +46,11 @@ namespace boost
namespace
{
+#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::once_flag current_thread_tls_init_flag;
+#else
boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT;
+#endif
pthread_key_t current_thread_tls_key;
extern "C"
@@ -87,6 +92,23 @@ namespace boost
}
}
+#if defined BOOST_THREAD_PATCH
+
+ struct delete_current_thread_tls_key_on_dlclose_t
+ {
+ delete_current_thread_tls_key_on_dlclose_t()
+ {
+ }
+ ~delete_current_thread_tls_key_on_dlclose_t()
+ {
+ if (current_thread_tls_init_flag.epoch!=BOOST_ONCE_INITIAL_FLAG_VALUE)
+ {
+ pthread_key_delete(current_thread_tls_key);
+ }
+ }
+ };
+ delete_current_thread_tls_key_on_dlclose_t delete_current_thread_tls_key_on_dlclose;
+#endif
void create_current_thread_tls_key()
{
@@ -116,16 +138,20 @@ namespace boost
boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->self;
thread_info->self.reset();
detail::set_current_thread_data(thread_info.get());
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
thread_info->run();
}
- catch(thread_interrupted const&)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(thread_interrupted const&) // BOOST_NO_EXCEPTIONS protected
{
}
+#endif
// Removed as it stops the debugger identifying the cause of the exception
// Unhandled exceptions still cause the application to terminate
-// catch(...)
+// catch(...) // BOOST_NO_EXCEPTIONS protected
// {
// std::terminate();
// }
@@ -177,7 +203,7 @@ namespace boost
}
- thread::thread()
+ thread::thread() BOOST_NOEXCEPT
{}
void thread::start_thread()
@@ -187,15 +213,47 @@ namespace boost
if (res != 0)
{
thread_info->self.reset();
- boost::throw_exception(thread_resource_error());
+ boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_create"));
}
}
- thread::~thread()
+ void thread::start_thread(const attributes& attr)
{
- detach();
+ thread_info->self=thread_info;
+ const attributes::native_handle_type* h = attr.native_handle();
+ int res = pthread_create(&thread_info->thread_handle, h, &thread_proxy, thread_info.get());
+ if (res != 0)
+ {
+ thread_info->self.reset();
+ boost::throw_exception(thread_resource_error());
+ }
+ int detached_state;
+ res = pthread_attr_getdetachstate(h, &detached_state);
+ if (res != 0)
+ {
+ thread_info->self.reset();
+ boost::throw_exception(thread_resource_error());
+ }
+ if (PTHREAD_CREATE_DETACHED==detached_state)
+ {
+ detail::thread_data_ptr local_thread_info;
+ thread_info.swap(local_thread_info);
+
+ if(local_thread_info)
+ {
+ //lock_guard<mutex> lock(local_thread_info->data_mutex);
+ if(!local_thread_info->join_started)
+ {
+ //BOOST_VERIFY(!pthread_detach(local_thread_info->thread_handle));
+ local_thread_info->join_started=true;
+ local_thread_info->joined=true;
+ }
+ }
+ }
}
+
+
detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const
{
return thread_info;
@@ -203,6 +261,10 @@ namespace boost
void thread::join()
{
+ if (this_thread::get_id() == get_id())
+ {
+ boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
+ }
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
if(local_thread_info)
{
@@ -244,8 +306,12 @@ namespace boost
}
}
- bool thread::timed_join(system_time const& wait_until)
+ bool thread::do_try_join_until(struct timespec const &timeout)
{
+ if (this_thread::get_id() == get_id())
+ {
+ boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
+ }
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
if(local_thread_info)
{
@@ -255,7 +321,7 @@ namespace boost
unique_lock<mutex> lock(local_thread_info->data_mutex);
while(!local_thread_info->done)
{
- if(!local_thread_info->done_condition.timed_wait(lock,wait_until))
+ if(!local_thread_info->done_condition.do_timed_wait(lock,timeout))
{
return false;
}
@@ -291,13 +357,13 @@ namespace boost
return true;
}
- bool thread::joinable() const
+ bool thread::joinable() const BOOST_NOEXCEPT
{
return (get_thread_info)();
}
- void thread::detach()
+ void thread::detach() BOOST_NOEXCEPT
{
detail::thread_data_ptr local_thread_info;
thread_info.swap(local_thread_info);
@@ -328,7 +394,7 @@ namespace boost
if(thread_info)
{
unique_lock<mutex> lk(thread_info->sleep_mutex);
- while(thread_info->sleep_condition.timed_wait(lk,st));
+ while(thread_info->sleep_condition.timed_wait(lk,st)) {}
}
else
{
@@ -354,14 +420,41 @@ namespace boost
cond.timed_wait(lock, xt);
# endif
xtime cur;
- xtime_get(&cur, TIME_UTC);
+ xtime_get(&cur, TIME_UTC_);
if (xtime_cmp(xt, cur) <= 0)
return;
}
}
}
- void yield()
+#ifdef BOOST_THREAD_USES_CHRONO
+ void
+ sleep_for(const chrono::nanoseconds& ns)
+ {
+ using namespace chrono;
+ if (ns >= nanoseconds::zero())
+ {
+ timespec ts;
+ ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count());
+ ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count());
+
+# if defined(BOOST_HAS_PTHREAD_DELAY_NP)
+ BOOST_VERIFY(!pthread_delay_np(&ts));
+# elif defined(BOOST_HAS_NANOSLEEP)
+ // nanosleep takes a timespec that is an offset, not
+ // an absolute time.
+ nanosleep(&ts, 0);
+# else
+ mutex mx;
+ mutex::scoped_lock lock(mx);
+ condition_variable cond;
+ cond.wait_for(lock, ns);
+# endif
+ }
+ }
+#endif
+
+ void yield() BOOST_NOEXCEPT
{
# if defined(BOOST_HAS_SCHED_YIELD)
BOOST_VERIFY(!sched_yield());
@@ -369,13 +462,12 @@ namespace boost
BOOST_VERIFY(!pthread_yield());
# else
xtime xt;
- xtime_get(&xt, TIME_UTC);
+ xtime_get(&xt, TIME_UTC_);
sleep(xt);
# endif
}
}
-
- unsigned thread::hardware_concurrency()
+ unsigned thread::hardware_concurrency() BOOST_NOEXCEPT
{
#if defined(PTW32_VERSION) || defined(__hpux)
return pthread_num_processors_np();
@@ -393,8 +485,12 @@ namespace boost
#endif
}
- thread::id thread::get_id() const
+ thread::id thread::get_id() const BOOST_NOEXCEPT
{
+ #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
+ //return local_thread_info->thread_handle;
+ return const_cast<thread*>(this)->native_handle();
+ #else
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
if(local_thread_info)
{
@@ -402,8 +498,9 @@ namespace boost
}
else
{
- return id();
+ return id();
}
+ #endif
}
void thread::interrupt()
@@ -421,7 +518,7 @@ namespace boost
}
}
- bool thread::interruption_requested() const
+ bool thread::interruption_requested() const BOOST_NOEXCEPT
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
if(local_thread_info)
@@ -453,14 +550,19 @@ namespace boost
namespace this_thread
{
- thread::id get_id()
+ thread::id get_id() BOOST_NOEXCEPT
{
+ #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
+ return pthread_self();
+ #else
boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data();
return thread::id(thread_info?thread_info->shared_from_this():detail::thread_data_ptr());
+ #endif
}
void interruption_point()
{
+#ifndef BOOST_NO_EXCEPTIONS
boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
if(thread_info && thread_info->interrupt_enabled)
{
@@ -471,15 +573,16 @@ namespace boost
throw thread_interrupted();
}
}
+#endif
}
- bool interruption_enabled()
+ bool interruption_enabled() BOOST_NOEXCEPT
{
boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
return thread_info && thread_info->interrupt_enabled;
}
- bool interruption_requested()
+ bool interruption_requested() BOOST_NOEXCEPT
{
boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
if(!thread_info)
@@ -493,7 +596,7 @@ namespace boost
}
}
- disable_interruption::disable_interruption():
+ disable_interruption::disable_interruption() BOOST_NOEXCEPT:
interruption_was_enabled(interruption_enabled())
{
if(interruption_was_enabled)
@@ -502,7 +605,7 @@ namespace boost
}
}
- disable_interruption::~disable_interruption()
+ disable_interruption::~disable_interruption() BOOST_NOEXCEPT
{
if(detail::get_current_thread_data())
{
@@ -510,7 +613,7 @@ namespace boost
}
}
- restore_interruption::restore_interruption(disable_interruption& d)
+ restore_interruption::restore_interruption(disable_interruption& d) BOOST_NOEXCEPT
{
if(d.interruption_was_enabled)
{
@@ -518,7 +621,7 @@ namespace boost
}
}
- restore_interruption::~restore_interruption()
+ restore_interruption::~restore_interruption() BOOST_NOEXCEPT
{
if(detail::get_current_thread_data())
{
diff --git a/libs/thread/src/pthread/timeconv.inl b/libs/thread/src/pthread/timeconv.inl
index 1c0a0cdca8..cab7c55a78 100644
--- a/libs/thread/src/pthread/timeconv.inl
+++ b/libs/thread/src/pthread/timeconv.inl
@@ -20,8 +20,8 @@ const int NANOSECONDS_PER_MICROSECOND = 1000;
inline void to_time(int milliseconds, boost::xtime& xt)
{
int res = 0;
- res = boost::xtime_get(&xt, boost::TIME_UTC);
- BOOST_ASSERT(res == boost::TIME_UTC); (void)res;
+ res = boost::xtime_get(&xt, boost::TIME_UTC_);
+ BOOST_ASSERT(res == boost::TIME_UTC_); (void)res;
xt.sec += (milliseconds / MILLISECONDS_PER_SECOND);
xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
@@ -56,8 +56,8 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts)
{
boost::xtime cur;
int res = 0;
- res = boost::xtime_get(&cur, boost::TIME_UTC);
- BOOST_ASSERT(res == boost::TIME_UTC); (void)res;
+ res = boost::xtime_get(&cur, boost::TIME_UTC_);
+ BOOST_ASSERT(res == boost::TIME_UTC_); (void)res;
if (boost::xtime_cmp(xt, cur) <= 0)
{
@@ -87,8 +87,8 @@ inline void to_duration(boost::xtime xt, int& milliseconds)
{
boost::xtime cur;
int res = 0;
- res = boost::xtime_get(&cur, boost::TIME_UTC);
- BOOST_ASSERT(res == boost::TIME_UTC); (void)res;
+ res = boost::xtime_get(&cur, boost::TIME_UTC_);
+ BOOST_ASSERT(res == boost::TIME_UTC_); (void)res;
if (boost::xtime_cmp(xt, cur) <= 0)
milliseconds = 0;
@@ -109,8 +109,8 @@ inline void to_microduration(boost::xtime xt, int& microseconds)
{
boost::xtime cur;
int res = 0;
- res = boost::xtime_get(&cur, boost::TIME_UTC);
- BOOST_ASSERT(res == boost::TIME_UTC); (void)res;
+ res = boost::xtime_get(&cur, boost::TIME_UTC_);
+ BOOST_ASSERT(res == boost::TIME_UTC_); (void)res;
if (boost::xtime_cmp(xt, cur) <= 0)
microseconds = 0;
diff --git a/libs/thread/src/win32/thread.cpp b/libs/thread/src/win32/thread.cpp
index 568eb217b9..9b6670a6f5 100644
--- a/libs/thread/src/win32/thread.cpp
+++ b/libs/thread/src/win32/thread.cpp
@@ -4,8 +4,13 @@
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2007 David Deakins
+#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x400
+#endif
+
+#ifndef WINVER
#define WINVER 0x400
+#endif
#include <boost/thread/thread.hpp>
#include <algorithm>
@@ -26,33 +31,36 @@ namespace boost
{
namespace
{
+#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+ boost::once_flag current_thread_tls_init_flag;
+#else
boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT;
- DWORD current_thread_tls_key=0;
+#endif
+#if defined(UNDER_CE)
+ // Windows CE does not define the TLS_OUT_OF_INDEXES constant.
+#define TLS_OUT_OF_INDEXES 0xFFFFFFFF
+#endif
+ DWORD current_thread_tls_key=TLS_OUT_OF_INDEXES;
void create_current_thread_tls_key()
{
tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in
current_thread_tls_key=TlsAlloc();
- #if defined(UNDER_CE)
- // Windows CE does not define the TLS_OUT_OF_INDEXES constant.
- BOOST_ASSERT(current_thread_tls_key!=0xFFFFFFFF);
- #else
- BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES);
- #endif
+ BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES);
}
void cleanup_tls_key()
{
- if(current_thread_tls_key)
+ if(current_thread_tls_key!=TLS_OUT_OF_INDEXES)
{
TlsFree(current_thread_tls_key);
- current_thread_tls_key=0;
+ current_thread_tls_key=TLS_OUT_OF_INDEXES;
}
}
detail::thread_data_base* get_current_thread_data()
{
- if(!current_thread_tls_key)
+ if(current_thread_tls_key==TLS_OUT_OF_INDEXES)
{
return 0;
}
@@ -62,7 +70,7 @@ namespace boost
void set_current_thread_data(detail::thread_data_base* new_data)
{
boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
- if(current_thread_tls_key)
+ if(current_thread_tls_key!=TLS_OUT_OF_INDEXES)
BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data));
else
boost::throw_exception(thread_resource_error());
@@ -88,7 +96,7 @@ namespace boost
typedef void* uintptr_t;
- inline uintptr_t const _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*),
+ inline uintptr_t _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*),
void* arglist, unsigned initflag, unsigned* thrdaddr)
{
DWORD threadID;
@@ -175,16 +183,20 @@ namespace boost
{
detail::thread_data_base* const thread_info(reinterpret_cast<detail::thread_data_base*>(param));
set_current_thread_data(thread_info);
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
thread_info->run();
}
- catch(thread_interrupted const&)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(thread_interrupted const&) // BOOST_NO_EXCEPTIONS protected
{
}
+#endif
// Removed as it stops the debugger identifying the cause of the exception
// Unhandled exceptions still cause the application to terminate
-// catch(...)
+// catch(...) // BOOST_NO_EXCEPTIONS protected
// {
// std::terminate();
// }
@@ -193,7 +205,7 @@ namespace boost
}
}
- thread::thread()
+ thread::thread() BOOST_NOEXCEPT
{}
void thread::start_thread()
@@ -208,6 +220,19 @@ namespace boost
ResumeThread(thread_info->thread_handle);
}
+ void thread::start_thread(const attributes& attr)
+ {
+ //uintptr_t const new_thread=_beginthreadex(attr.get_security(),attr.get_stack_size(),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
+ uintptr_t const new_thread=_beginthreadex(0,static_cast<unsigned int>(attr.get_stack_size()),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
+ if(!new_thread)
+ {
+ boost::throw_exception(thread_resource_error());
+ }
+ intrusive_ptr_add_ref(thread_info.get());
+ thread_info->thread_handle=(detail::win32::handle)(new_thread);
+ ResumeThread(thread_info->thread_handle);
+ }
+
thread::thread(detail::thread_data_ptr data):
thread_info(data)
{}
@@ -233,15 +258,19 @@ namespace boost
void make_external_thread_data()
{
externally_launched_thread* me=detail::heap_new<externally_launched_thread>();
- try
+#ifndef BOOST_NO_EXCEPTIONS
+ try // BOOST_NO_EXCEPTIONS protected
+#endif
{
set_current_thread_data(me);
}
- catch(...)
+#ifndef BOOST_NO_EXCEPTIONS
+ catch(...) // BOOST_NO_EXCEPTIONS protected
{
detail::heap_delete(me);
- throw;
+ throw; // BOOST_NO_EXCEPTIONS protected
}
+#endif
}
detail::thread_data_base* get_or_make_current_thread_data()
@@ -257,23 +286,28 @@ namespace boost
}
- thread::~thread()
- {
- detach();
- }
-
- thread::id thread::get_id() const
+ thread::id thread::get_id() const BOOST_NOEXCEPT
{
+ #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
+ detail::thread_data_ptr local_thread_info=(get_thread_info)();
+ return local_thread_info?local_thread_info->id:0;
+ //return const_cast<thread*>(this)->native_handle();
+ #else
return thread::id((get_thread_info)());
+ #endif
}
- bool thread::joinable() const
+ bool thread::joinable() const BOOST_NOEXCEPT
{
return (get_thread_info)();
}
void thread::join()
{
+ if (this_thread::get_id() == get_id())
+ {
+ boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
+ }
detail::thread_data_ptr local_thread_info=(get_thread_info)();
if(local_thread_info)
{
@@ -284,6 +318,10 @@ namespace boost
bool thread::timed_join(boost::system_time const& wait_until)
{
+ if (this_thread::get_id() == get_id())
+ {
+ boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
+ }
detail::thread_data_ptr local_thread_info=(get_thread_info)();
if(local_thread_info)
{
@@ -296,7 +334,30 @@ namespace boost
return true;
}
- void thread::detach()
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ bool thread::try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
+ {
+ if (this_thread::get_id() == get_id())
+ {
+ boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
+ }
+ detail::thread_data_ptr local_thread_info=(get_thread_info)();
+ if(local_thread_info)
+ {
+ chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
+ if(!this_thread::interruptible_wait(local_thread_info->thread_handle,rel_time.count()))
+ {
+ return false;
+ }
+ release_handle();
+ }
+ return true;
+ }
+
+#endif
+
+ void thread::detach() BOOST_NOEXCEPT
{
release_handle();
}
@@ -315,13 +376,13 @@ namespace boost
}
}
- bool thread::interruption_requested() const
+ bool thread::interruption_requested() const BOOST_NOEXCEPT
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
return local_thread_info.get() && (detail::win32::WaitForSingleObject(local_thread_info->interruption_handle,0)==0);
}
- unsigned thread::hardware_concurrency()
+ unsigned thread::hardware_concurrency() BOOST_NOEXCEPT
{
SYSTEM_INFO info={{0}};
GetSystemInfo(&info);
@@ -491,9 +552,14 @@ namespace boost
return false;
}
- thread::id get_id()
+ thread::id get_id() BOOST_NOEXCEPT
{
+ #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
+ //return detail::win32::GetCurrentThread();
+ return detail::win32::GetCurrentThreadId();
+ #else
return thread::id(get_or_make_current_thread_data());
+ #endif
}
void interruption_point()
@@ -505,22 +571,22 @@ namespace boost
}
}
- bool interruption_enabled()
+ bool interruption_enabled() BOOST_NOEXCEPT
{
return get_current_thread_data() && get_current_thread_data()->interruption_enabled;
}
- bool interruption_requested()
+ bool interruption_requested() BOOST_NOEXCEPT
{
return get_current_thread_data() && (detail::win32::WaitForSingleObject(get_current_thread_data()->interruption_handle,0)==0);
}
- void yield()
+ void yield() BOOST_NOEXCEPT
{
detail::win32::Sleep(0);
}
- disable_interruption::disable_interruption():
+ disable_interruption::disable_interruption() BOOST_NOEXCEPT:
interruption_was_enabled(interruption_enabled())
{
if(interruption_was_enabled)
@@ -529,7 +595,7 @@ namespace boost
}
}
- disable_interruption::~disable_interruption()
+ disable_interruption::~disable_interruption() BOOST_NOEXCEPT
{
if(get_current_thread_data())
{
@@ -537,7 +603,7 @@ namespace boost
}
}
- restore_interruption::restore_interruption(disable_interruption& d)
+ restore_interruption::restore_interruption(disable_interruption& d) BOOST_NOEXCEPT
{
if(d.interruption_was_enabled)
{
@@ -545,7 +611,7 @@ namespace boost
}
}
- restore_interruption::~restore_interruption()
+ restore_interruption::~restore_interruption() BOOST_NOEXCEPT
{
if(get_current_thread_data())
{
diff --git a/libs/thread/src/win32/timeconv.inl b/libs/thread/src/win32/timeconv.inl
index 5ec3b1798a..c6467832a7 100644
--- a/libs/thread/src/win32/timeconv.inl
+++ b/libs/thread/src/win32/timeconv.inl
@@ -17,8 +17,8 @@ const int NANOSECONDS_PER_MICROSECOND = 1000;
inline void to_time(int milliseconds, boost::xtime& xt)
{
int res = 0;
- res = boost::xtime_get(&xt, boost::TIME_UTC);
- assert(res == boost::TIME_UTC);
+ res = boost::xtime_get(&xt, boost::TIME_UTC_);
+ assert(res == boost::TIME_UTC_);
xt.sec += (milliseconds / MILLISECONDS_PER_SECOND);
xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
@@ -54,8 +54,8 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts)
{
boost::xtime cur;
int res = 0;
- res = boost::xtime_get(&cur, boost::TIME_UTC);
- assert(res == boost::TIME_UTC);
+ res = boost::xtime_get(&cur, boost::TIME_UTC_);
+ assert(res == boost::TIME_UTC_);
if (boost::xtime_cmp(xt, cur) <= 0)
{
@@ -85,8 +85,8 @@ inline void to_duration(boost::xtime xt, int& milliseconds)
{
boost::xtime cur;
int res = 0;
- res = boost::xtime_get(&cur, boost::TIME_UTC);
- assert(res == boost::TIME_UTC);
+ res = boost::xtime_get(&cur, boost::TIME_UTC_);
+ assert(res == boost::TIME_UTC_);
if (boost::xtime_cmp(xt, cur) <= 0)
milliseconds = 0;
@@ -107,8 +107,8 @@ inline void to_microduration(boost::xtime xt, int& microseconds)
{
boost::xtime cur;
int res = 0;
- res = boost::xtime_get(&cur, boost::TIME_UTC);
- assert(res == boost::TIME_UTC);
+ res = boost::xtime_get(&cur, boost::TIME_UTC_);
+ assert(res == boost::TIME_UTC_);
if (boost::xtime_cmp(xt, cur) <= 0)
microseconds = 0;
diff --git a/libs/thread/src/win32/tss_pe.cpp b/libs/thread/src/win32/tss_pe.cpp
index 1d07d6b42b..1654b19e73 100644
--- a/libs/thread/src/win32/tss_pe.cpp
+++ b/libs/thread/src/win32/tss_pe.cpp
@@ -1,4 +1,4 @@
-// $Id: tss_pe.cpp 72431 2011-06-06 08:28:31Z anthonyw $
+// $Id: tss_pe.cpp 79373 2012-07-09 05:55:01Z viboes $
// (C) Copyright Aaron W. LaFramboise, Roland Schwarz, Michael Glassford 2004.
// (C) Copyright 2007 Roland Schwarz
// (C) Copyright 2007 Anthony Williams
@@ -11,7 +11,7 @@
#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
-#if (defined(__MINGW32__) && !defined(_WIN64)) || defined(__MINGW64__)
+#if (defined(__MINGW32__) && !defined(_WIN64)) || defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR)
#include <boost/thread/detail/tss_hooks.hpp>
@@ -25,7 +25,7 @@ namespace boost
}
namespace {
- void NTAPI on_tls_callback(void* h, DWORD dwReason, PVOID pv)
+ void NTAPI on_tls_callback(void* , DWORD dwReason, PVOID )
{
switch (dwReason)
{
@@ -38,7 +38,7 @@ namespace {
}
}
-#if defined(__MINGW64__) || (__MINGW32_MAJOR_VERSION >3) || \
+#if defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR) || (__MINGW32_MAJOR_VERSION >3) || \
((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18))
extern "C"
{
diff --git a/libs/thread/test/Jamfile.v2 b/libs/thread/test/Jamfile.v2
index d1d61179cb..2217a64b2a 100644
--- a/libs/thread/test/Jamfile.v2
+++ b/libs/thread/test/Jamfile.v2
@@ -1,6 +1,7 @@
-# (C) Copyright William E. Kempf 2001.
-# (C) Copyright 2007 Anthony Williams.
-# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# (C) Copyright William E. Kempf 2001.
+# (C) Copyright 2007 Anthony Williams.
+# (C) Copyright 2011-2012 Vicente J.Botet Escriba.
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# Boost.Threads test Jamfile
@@ -19,72 +20,522 @@
import testing ;
project
- : requirements <library>/boost/test//boost_unit_test_framework/<link>static
- <threading>multi
+ : requirements
+ <threading>multi
+
+ <warnings>all
+ <toolset>gcc:<cxxflags>-Wextra
+ <toolset>gcc:<cxxflags>-pedantic
+ <toolset>gcc:<cxxflags>-Wno-long-long
+ #<toolset>gcc:<cxxflags>-ansi
+ #<toolset>gcc:<cxxflags>-fpermissive
+
+ <toolset>darwin:<cxxflags>-Wextra
+ <toolset>darwin:<cxxflags>-pedantic
+ <toolset>darwin:<cxxflags>-Wno-long-long
+ #<toolset>darwin:<cxxflags>-ansi # doesn't work for 4.1.2
+ <toolset>darwin:<cxxflags>-fpermissive
+
+ #<toolset>pathscale:<cxxflags>-Wextra
+ <toolset>pathscale:<cxxflags>-Wno-long-long
+ <toolset>pathscale:<cxxflags>-pedantic
+
+ <toolset>clang:<cxxflags>-Wextra
+ <toolset>clang:<cxxflags>-pedantic
+ <toolset>clang:<cxxflags>-Wno-long-long
+ <toolset>clang:<cxxflags>-ansi
+ #<toolset>clang:<cxxflags>-fpermissive # doesn't work
+
+ <toolset>gcc-mingw-4.4.0:<cxxflags>-fdiagnostics-show-option
+ <toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option
+ <toolset>gcc-mingw-4.6.0:<cxxflags>-fdiagnostics-show-option
+ <toolset>gcc-mingw-4.6.3:<cxxflags>-fdiagnostics-show-option
+ <toolset>gcc-mingw-4.7.0:<cxxflags>-fdiagnostics-show-option
+ <toolset>gcc-mingw-4.8.0:<cxxflags>-fdiagnostics-show-option
+
+ <toolset>darwin-4.6.2:<cxxflags>-ansi
+ #<toolset>darwin-4.6.2:<cxxflags>-Wno-delete-non-virtual-dtor # doesn't work
+ <toolset>darwin-4.7.0:<cxxflags>-ansi
+ <toolset>darwin-4.7.0:<cxxflags>-Wno-delete-non-virtual-dtor
+
+ #<toolset>clang-2.8:<cxxflags>-Wno-delete-non-virtual-dtor
+ #<toolset>clang-2.8:<cxxflags>-Wno-unused-function
+ #<toolset>clang-2.9:<cxxflags>-Wno-delete-non-virtual-dtor
+ #<toolset>clang-2.9:<cxxflags>-Wno-unused-function
+ <toolset>clang-3.0:<cxxflags>-Wno-delete-non-virtual-dtor
+ #<toolset>clang-3.0:<cxxflags>-Wno-unused-function
+ #<toolset>clang-3.0:<cxxflags>-Wno-unused-variable
+
;
rule thread-run ( sources )
{
- return
+ return
[ run $(sources) ../build//boost_thread ]
- [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
+ [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
: : : : $(sources[1]:B)_lib ]
;
-}
+}
+
+rule thread-test ( sources )
+{
+ return
+ [ run $(sources) ../build//boost_thread : : :
+ <library>/boost/test//boost_unit_test_framework/<link>static
+ ]
+ [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
+ : : :
+ <library>/boost/test//boost_unit_test_framework/<link>static
+ : $(sources[1]:B)_lib
+ ]
+ ;
+}
+rule thread-run2 ( sources : name )
{
- test-suite "threads"
- : [ thread-run test_thread.cpp ]
- [ thread-run test_thread_id.cpp ]
- [ thread-run test_hardware_concurrency.cpp ]
- [ thread-run test_thread_move.cpp ]
- [ thread-run test_thread_return_local.cpp ]
- [ thread-run test_thread_move_return.cpp ]
- [ thread-run test_thread_launching.cpp ]
- [ thread-run test_thread_mf.cpp ]
- [ thread-run test_thread_exit.cpp ]
- [ thread-run test_move_function.cpp ]
- [ thread-run test_mutex.cpp ]
- [ thread-run test_condition_notify_one.cpp ]
- [ thread-run test_condition_timed_wait_times_out.cpp ]
- [ thread-run test_condition_notify_all.cpp ]
- [ thread-run test_condition.cpp ]
- [ thread-run test_tss.cpp ]
- [ thread-run test_once.cpp ]
- [ thread-run test_xtime.cpp ]
- [ thread-run test_barrier.cpp ]
- [ thread-run test_shared_mutex.cpp ]
- [ thread-run test_shared_mutex_part_2.cpp ]
- [ thread-run test_shared_mutex_timed_locks.cpp ]
- [ thread-run test_lock_concept.cpp ]
- [ thread-run test_generic_locks.cpp ]
- [ thread-run test_futures.cpp ]
+ return
+ [ run $(sources) ../build//boost_thread : : :
+ : $(name) ]
+ [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
+ : : :
+ : $(name)_lib ]
+ ;
+}
+
+rule thread-run-lib2 ( sources : name )
+{
+ return
+ [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
+ : : :
+ : $(name)_lib ]
+ ;
+}
+
+
+rule thread-compile-fail ( sources : reqs * : name )
+{
+ return
+ [ compile-fail $(sources)
+ : $(reqs)
+ : $(name) ]
+ ;
+}
+
+{
+ test-suite t_threads
+ :
+ [ thread-test test_thread.cpp ]
+ [ thread-test test_thread_id.cpp ]
+ [ thread-test test_hardware_concurrency.cpp ]
+ [ thread-test test_thread_move.cpp ]
+ [ thread-test test_thread_return_local.cpp ]
+ [ thread-test test_thread_move_return.cpp ]
+ [ thread-test test_thread_launching.cpp ]
+ [ thread-test test_thread_mf.cpp ]
+ [ thread-test test_thread_exit.cpp ]
+ [ thread-test test_move_function.cpp ]
[ compile-fail no_implicit_move_from_lvalue_thread.cpp ]
[ compile-fail no_implicit_assign_from_lvalue_thread.cpp ]
+ [ thread-test test_tss.cpp ]
+ [ thread-test test_xtime.cpp ]
;
+ test-suite t_sync
+ :
+ [ thread-test test_mutex.cpp ]
+ [ thread-test test_condition_notify_one.cpp ]
+ [ thread-test test_condition_timed_wait_times_out.cpp ]
+ [ thread-test test_condition_notify_all.cpp ]
+ [ thread-test test_condition.cpp ]
+ [ thread-test test_once.cpp ]
+ [ thread-test test_barrier.cpp ]
+ [ thread-test test_lock_concept.cpp ]
+ [ thread-test test_generic_locks.cpp ]
+ ;
- #explicit tickets ;
- test-suite tickets
- :
- [ thread-run test_6170.cpp ]
+ test-suite t_shared
+ :
+ [ thread-test test_shared_mutex.cpp ]
+ [ thread-test test_shared_mutex_part_2.cpp ]
+ [ thread-test test_shared_mutex_timed_locks.cpp ]
+ [ thread-test test_shared_mutex_timed_locks_chrono.cpp ]
+ #uncomment the following once these works on windows
+ #[ thread-test test_vhh_shared_mutex.cpp ]
+ #[ thread-test test_vhh_shared_mutex_part_2.cpp ]
+ #[ thread-test test_vhh_shared_mutex_timed_locks.cpp ]
+ ;
+
+ #explicit t_futures ;
+ test-suite t_futures
+ :
+ [ thread-test test_futures.cpp ]
;
- explicit oth_tickets ;
- test-suite oth_tickets
- :
+ #explicit tickets ;
+ test-suite tickets
+ :
+ [ thread-test test_2309.cpp ]
[ thread-run test_2501.cpp ]
+ [ thread-test test_2741.cpp ]
[ thread-run test_4521.cpp ]
[ thread-run test_4648.cpp ]
[ thread-run test_4882.cpp ]
- [ thread-run test_5351.cpp ]
- [ thread-run test_5502.cpp ]
[ thread-run test_5542_1.cpp ]
[ thread-run test_5542_2.cpp ]
[ thread-run test_5542_3.cpp ]
+ [ thread-run test_5891.cpp ]
[ thread-run test_6130.cpp ]
+ [ thread-run test_6170.cpp ]
[ thread-run test_6174.cpp ]
;
+
+ explicit oth_tickets ;
+ test-suite oth_tickets
+ :
+ [ thread-run test_5351.cpp ]
+ [ thread-run test_5502.cpp ]
+ ;
+
+
+
+ #explicit ts_conditions ;
+ test-suite ts_conditions
+ :
+ [ thread-compile-fail ./sync/conditions/condition_variable/assign_fail.cpp : : condition_variable__assign_f ]
+ [ thread-compile-fail ./sync/conditions/condition_variable/copy_fail.cpp : : condition_variable__copy_f ]
+ [ thread-run2 ./sync/conditions/condition_variable/default_pass.cpp : condition_variable__default_p ]
+ [ thread-run2 ./sync/conditions/condition_variable/dtor_pass.cpp : condition_variable__dtor_p ]
+ [ thread-run2 ./sync/conditions/condition_variable/native_handle_pass.cpp : condition_variable__native_handle_p ]
+ [ thread-run2 ./sync/conditions/condition_variable/wait_for_pass.cpp : condition_variable__wait_for_p ]
+ [ thread-run2 ./sync/conditions/condition_variable/wait_for_pred_pass.cpp : condition_variable__wait_for_pred_p ]
+ [ thread-run2 ./sync/conditions/condition_variable/wait_until_pass.cpp : condition_variable__wait_until_p ]
+ [ thread-run2 ./sync/conditions/condition_variable/wait_until_pred_pass.cpp : condition_variable__wait_until_pred_p ]
+
+ [ thread-compile-fail ./sync/conditions/condition_variable_any/assign_fail.cpp : : condition_variable_any__assign_f ]
+ [ thread-compile-fail ./sync/conditions/condition_variable_any/copy_fail.cpp : : condition_variable_any__copy_f ]
+ [ thread-run2 ./sync/conditions/condition_variable_any/default_pass.cpp : condition_variable_any__default_p ]
+ [ thread-run2 ./sync/conditions/condition_variable_any/dtor_pass.cpp : condition_variable_any__dtor_p ]
+ [ thread-run2 ./sync/conditions/condition_variable_any/wait_for_pass.cpp : condition_variable_any__wait_for_p ]
+ [ thread-run2 ./sync/conditions/condition_variable_any/wait_for_pred_pass.cpp : condition_variable_any__wait_for_pred_p ]
+ [ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pass.cpp : condition_variable_any__wait_until_p ]
+ [ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pred_pass.cpp : condition_variable_any__wait_until_pred_p ]
+ [ thread-run2 ./sync/conditions/cv_status/cv_status_pass.cpp : cv_status__cv_status_p ]
+ ;
+
+ #explicit ts_async ;
+ test-suite ts_async
+ :
+ # [ thread-run2 ./sync/futures/async/async_pass.cpp : async__async_p ]
+ ;
+
+ #explicit ts_promise ;
+ test-suite ts_promise
+ :
+ [ thread-compile-fail ./sync/futures/promise/copy_assign_fail.cpp : : promise__copy_assign_f ]
+ [ thread-compile-fail ./sync/futures/promise/copy_ctor_fail.cpp : : promise__copy_ctor_f ]
+ [ thread-run2 ./sync/futures/promise/alloc_ctor_pass.cpp : promise__alloc_ctor_p ]
+ [ thread-run2 ./sync/futures/promise/default_pass.cpp : promise__default_p ]
+ [ thread-run2 ./sync/futures/promise/dtor_pass.cpp : promise__dtor_p ]
+ [ thread-run2 ./sync/futures/promise/get_future_pass.cpp : promise__get_future_p ]
+ [ thread-run2 ./sync/futures/promise/move_ctor_pass.cpp : promise__move_ctor_p ]
+ [ thread-run2 ./sync/futures/promise/move_assign_pass.cpp : promise__move_asign_p ]
+ [ thread-run2 ./sync/futures/promise/use_allocator_pass.cpp : promise__use_allocator_p ]
+ ;
+
+ #explicit ts_future ;
+ test-suite ts_future
+ :
+ [ thread-compile-fail ./sync/futures/future/copy_assign_fail.cpp : : future__copy_assign_f ]
+ [ thread-compile-fail ./sync/futures/future/copy_ctor_fail.cpp : : future__copy_ctor_f ]
+ [ thread-run2 ./sync/futures/future/default_pass.cpp : future__default_p ]
+ [ thread-run2 ./sync/futures/future/dtor_pass.cpp : future__dtor_p ]
+ #[ thread-run2 ./sync/futures/future/get_pass.cpp : future__get_p ]
+ [ thread-run2 ./sync/futures/future/move_ctor_pass.cpp : future__move_ctor_p ]
+ [ thread-run2 ./sync/futures/future/move_assign_pass.cpp : future__move_asign_p ]
+ [ thread-run2 ./sync/futures/future/share_pass.cpp : future__share_p ]
+ ;
+
+ #explicit ts_packaged_task ;
+ test-suite ts_packaged_task
+ :
+ [ thread-run2 ./sync/futures/packaged_task/alloc_ctor_pass.cpp : packaged_task__alloc_ctor_p ]
+ [ thread-compile-fail ./sync/futures/packaged_task/copy_assign_fail.cpp : : packaged_task__copy_assign_f ]
+ [ thread-compile-fail ./sync/futures/packaged_task/copy_ctor_fail.cpp : : packaged_task__copy_ctor_f ]
+ [ thread-run2 ./sync/futures/packaged_task/default_ctor_pass.cpp : packaged_task__default_ctor_p ]
+ [ thread-run2 ./sync/futures/packaged_task/func_ctor_pass.cpp : packaged_task__func_ctor_p ]
+ #[ thread-run2 ./sync/futures/packaged_task/dtor_pass.cpp : packaged_task__dtor_p ]
+ [ thread-run2 ./sync/futures/packaged_task/get_future_pass.cpp : packaged_task__get_future_p ]
+ [ thread-run2 ./sync/futures/packaged_task/move_ctor_pass.cpp : packaged_task__move_ctor_p ]
+ [ thread-run2 ./sync/futures/packaged_task/move_assign_pass.cpp : packaged_task__move_asign_p ]
+ #[ thread-run2 ./sync/futures/packaged_task/operator_pass.cpp : packaged_task__operator_p ]
+ [ thread-run2 ./sync/futures/packaged_task/reset_pass.cpp : packaged_task__reset_p ]
+ [ thread-run2 ./sync/futures/packaged_task/use_allocator_pass.cpp : packaged_task__use_allocator_p ]
+ [ thread-run2 ./sync/futures/packaged_task/types_pass.cpp : packaged_task__types_p ]
+ [ thread-run2 ./sync/futures/packaged_task/member_swap_pass.cpp : packaged_task__member_swap_p ]
+ [ thread-run2 ./sync/futures/packaged_task/non_member_swap_pass.cpp : packaged_task__non_member_swap_p ]
+ ;
+
+
+ #explicit ts_lock_guard ;
+ test-suite ts_lock_guard
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp : : lock_guard__cons__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp : : lock_guard__cons__copy_ctor_f ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp : lock_guard__cons__adopt_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/lock_guard/default_pass.cpp : lock_guard__cons__default_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/lock_guard/types_pass.cpp : lock_guard__types_p ]
+ ;
+
+ #explicit ts_unique_lock ;
+ test-suite ts_unique_lock
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp : : unique_lock__cons__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp : : unique_lock__cons__copy_ctor_f ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp : unique_lock__cons__adopt_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp : unique_lock__cons__default_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp : unique_lock__cons__defer_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp : unique_lock__cons__duration_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp : unique_lock__cons__move_assign_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp : unique_lock__cons__move_ctor_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp : unique_lock__cons__move_ctor_upgrade_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp : unique_lock__cons__move_ctor_upgrade_lock_try_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp : unique_lock__cons__move_ctor_upgrade_lock_for_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp : unique_lock__cons__move_ctor_upgrade_lock_until_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp : unique_lock__cons__mutex_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp : unique_lock__cons__time_point_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp : unique_lock__cons__try_to_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp : unique_lock__lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp : unique_lock__try_lock_for_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp : unique_lock__try_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp : unique_lock__try_lock_until_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp : unique_lock__unlock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp : unique_lock__member_swap_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp : unique_lock__non_member_swap_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp : unique_lock__release_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp : unique_lock__mutex_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp : unique_lock__op_bool_p ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp : : unique_lock__op_int_f ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp : unique_lock__owns_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/types_pass.cpp : unique_lock__types_p ]
+ ;
+
+ #explicit ts_shared_lock ;
+ test-suite ts_shared_lock
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp : : shared_lock__cons__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp : : shared_lock__cons__copy_ctor_f ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp : shared_lock__cons__adopt_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp : shared_lock__cons__default_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp : shared_lock__cons__defer_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp : shared_lock__cons__duration_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp : shared_lock__cons__move_assign_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp : shared_lock__cons__move_ctor_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp : shared_lock__cons__move_ctor_unique_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp : shared_lock__cons__move_ctor_upgrade_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp : shared_lock__cons__mutex_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp : shared_lock__cons__time_point_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp : shared_lock__cons__try_to_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp : shared_lock__lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp : shared_lock__try_lock_for_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp : shared_lock__try_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp : shared_lock__try_lock_until_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp : shared_lock__unlock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp : shared_lock__member_swap_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp : shared_lock__non_member_swap_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp : shared_lock__release_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp : shared_lock__mutex_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp : shared_lock__op_bool_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp : shared_lock__owns_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/types_pass.cpp : shared_lock__types_p ]
+ ;
+
+ #explicit ts_upgrade_lock ;
+ test-suite ts_upgrade_lock
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp : : upgrade_lock__cons__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp : : upgrade_lock__cons__copy_ctor_f ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp : upgrade_lock__cons__adopt_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp : upgrade_lock__cons__default_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp : upgrade_lock__cons__defer_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp : upgrade_lock__cons__duration_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp : upgrade_lock__cons__move_assign_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp : upgrade_lock__cons__move_ctor_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp : upgrade_lock__cons__move_ctor_unique_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp : upgrade_lock__cons__mutex_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp : upgrade_lock__cons__time_point_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp : upgrade_lock__cons__try_to_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp : upgrade_lock__lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp : upgrade_lock__try_lock_for_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp : upgrade_lock__try_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp : upgrade_lock__try_lock_until_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp : upgrade_lock__unlock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp : upgrade_lock__member_swap_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp : upgrade_lock__non_member_swap_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp : upgrade_lock__release_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp : upgrade_lock__mutex_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp : upgrade_lock__op_bool_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp : upgrade_lock__owns_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp : upgrade_lock__types_p ]
+ ;
+
+ #explicit ts_mutex ;
+ test-suite ts_mutex
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/mutex/assign_fail.cpp : : mutex__assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/mutex/copy_fail.cpp : : mutex__copy_f ]
+ [ thread-run2 ./sync/mutual_exclusion/mutex/default_pass.cpp : mutex__default_p ]
+ [ thread-run2 ./sync/mutual_exclusion/mutex/lock_pass.cpp : mutex__lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/mutex/native_handle_pass.cpp : mutex__native_handle_p ]
+ [ thread-run2 ./sync/mutual_exclusion/mutex/try_lock_pass.cpp : mutex__try_lock_p ]
+ ;
+
+ #explicit ts_recursive_mutex ;
+ test-suite ts_recursive_mutex
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/recursive_mutex/assign_fail.cpp : : recursive_mutex__assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/recursive_mutex/copy_fail.cpp : : recursive_mutex__copy_f ]
+ [ thread-run2 ./sync/mutual_exclusion/recursive_mutex/default_pass.cpp : recursive_mutex__default_p ]
+ [ thread-run2 ./sync/mutual_exclusion/recursive_mutex/lock_pass.cpp : recursive_mutex__lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp : recursive_mutex__native_handle_p ]
+ [ thread-run2 ./sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp : recursive_mutex__try_lock_p ]
+ ;
+
+ #explicit ts_recursive_timed_mutex ;
+ test-suite ts_recursive_timed_mutex
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp : : recursive_timed_mutex__assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp : : recursive_timed_mutex__copy_f ]
+ [ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp : recursive_timed_mutex__default_p ]
+ [ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp : recursive_timed_mutex__lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp : recursive_timed_mutex__native_handle_p ]
+ [ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp : recursive_timed_mutex__try_lock_for_p ]
+ [ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp : recursive_timed_mutex__try_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp : recursive_timed_mutex__try_lock_until_p ]
+ ;
+
+ #explicit ts_timed_mutex ;
+ test-suite ts_timed_mutex
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/timed_mutex/assign_fail.cpp : : timed_mutex__assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/timed_mutex/copy_fail.cpp : : timed_mutex__copy_f ]
+ [ thread-run2 ./sync/mutual_exclusion/timed_mutex/default_pass.cpp : timed_mutex__default_p ]
+ [ thread-run2 ./sync/mutual_exclusion/timed_mutex/lock_pass.cpp : timed_mutex__lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp : timed_mutex__native_handle_p ]
+ [ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp : timed_mutex__try_lock_for_p ]
+ [ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp : timed_mutex__try_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp : timed_mutex__try_lock_until_p ]
+ ;
+
+ #explicit ts_shared_mutex ;
+ test-suite ts_shared_mutex
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/shared_mutex/assign_fail.cpp : : shared_mutex__assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/shared_mutex/copy_fail.cpp : : shared_mutex__copy_f ]
+ [ thread-run2 ./sync/mutual_exclusion/shared_mutex/default_pass.cpp : shared_mutex__default_p ]
+ [ thread-run2 ./sync/mutual_exclusion/shared_mutex/lock_pass.cpp : shared_mutex__lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp : shared_mutex__try_lock_for_p ]
+ [ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp : shared_mutex__try_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp : shared_mutex__try_lock_until_p ]
+
+ ;
+
+ #explicit ts_this_thread ;
+ test-suite ts_this_thread
+ :
+ [ thread-run2 ./threads/this_thread/get_id/get_id_pass.cpp : this_thread__get_id_p ]
+ [ thread-run2 ./threads/this_thread/sleep_for/sleep_for_pass.cpp : this_thread__sleep_for_p ]
+ [ thread-run2 ./threads/this_thread/sleep_until/sleep_until_pass.cpp : this_thread__sleep_until_p ]
+ ;
+
+ #explicit ts_thread ;
+ test-suite ts_thread
+ :
+ [ thread-compile-fail ./threads/thread/assign/copy_fail.cpp : : thread__assign__copy_f ]
+ [ thread-run2 ./threads/thread/assign/move_pass.cpp : thread__assign__move_p ]
+ [ thread-compile-fail ./threads/thread/constr/copy_fail.cpp : : thread__constr__copy_f ]
+ [ thread-run2 ./threads/thread/constr/default_pass.cpp : thread__constr__default_p ]
+ [ thread-run-lib2 ./threads/thread/constr/F_pass.cpp : thread__constr__F_p ]
+ [ thread-run-lib2 ./threads/thread/constr/FArgs_pass.cpp : thread__constr__FArgs_p ]
+ [ thread-run2 ./threads/thread/constr/Frvalue_pass.cpp : thread__constr__Frvalue_p ]
+ #[ thread-run2 ./threads/thread/constr/FrvalueArgs_pass.cpp : thread__constr__FrvalueArgs_p ]
+ [ thread-run2 ./threads/thread/constr/move_pass.cpp : thread__constr__move_p ]
+ [ thread-run2 ./threads/thread/destr/dtor_pass.cpp : thread__destr__dtor_p ]
+ [ thread-run2 ./threads/thread/id/hash_pass.cpp : thread__id__hash_p ]
+ [ thread-run2 ./threads/thread/members/detach_pass.cpp : thread__detach_p ]
+ [ thread-run2 ./threads/thread/members/get_id_pass.cpp : thread__get_id_p ]
+ [ thread-run2 ./threads/thread/members/join_pass.cpp : thread__join_p ]
+ [ thread-run2 ./threads/thread/members/joinable_pass.cpp : thread__joinable_p ]
+ [ thread-run2 ./threads/thread/members/native_handle_pass.cpp : thread__native_handle_p ]
+ [ thread-run2 ./threads/thread/members/swap_pass.cpp : thread__swap_p ]
+ [ thread-run2 ./threads/thread/non_members/swap_pass.cpp : swap_threads_p ]
+ [ thread-run2 ./threads/thread/static/hardware_concurrency_pass.cpp : thread__hardware_concurrency_p ]
+ ;
+
+ #explicit ts_container ;
+ test-suite ts_container
+ :
+ [ thread-run2 ./threads/container/thread_vector_pass.cpp : container__thread_vector_p ]
+ [ thread-run2 ./threads/container/thread_ptr_list_pass.cpp : container__thread_ptr_list_p ]
+ ;
+
+ #explicit ts_examples ;
+ test-suite ts_examples
+ :
+ [ thread-run ../example/monitor.cpp ]
+ [ compile ../example/starvephil.cpp ]
+ #[ compile ../example/tennis.cpp ]
+ [ compile ../example/condition.cpp ]
+ [ thread-run ../example/mutex.cpp ]
+ [ thread-run ../example/once.cpp ]
+ [ thread-run ../example/recursive_mutex.cpp ]
+ [ thread-run2 ../example/thread.cpp : ex_thread ]
+ [ thread-run ../example/thread_group.cpp ]
+ [ thread-run ../example/tss.cpp ]
+ [ thread-run ../example/xtime.cpp ]
+ [ thread-run ../example/shared_monitor.cpp ]
+ [ thread-run ../example/shared_mutex.cpp ]
+ #[ thread-run ../example/vhh_shared_monitor.cpp ]
+ #[ thread-run ../example/vhh_shared_mutex.cpp ]
+ ;
+
+ #explicit ts_shared_upwards ;
+ test-suite ts_shared_upwards
+ :
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp : unique_lock__cons__move_ctor_shared_lock_try_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp : unique_lock__cons__move_ctor_shared_lock_for_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp : unique_lock__cons__move_ctor_shared_lock_until_p ]
+
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp : upgrade_lock__cons__move_ctor_shared_lock_try_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp : upgrade_lock__cons__move_ctor_shared_lock_for_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp : upgrade_lock__cons__move_ctor_shared_lock_until_p ]
+ ;
+
+
+ #explicit ts_shared_lock_guard ;
+ test-suite ts_shared_lock_guard
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp : : shared_lock_guard__cons__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp : : shared_lock_guard__cons__copy_ctor_f ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp : shared_lock_guard__cons__adopt_lock_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp : shared_lock_guard__cons__default_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp : shared_lock_guard__types_p ]
+ ;
+
+ #explicit ts_reverse_lock ;
+ test-suite ts_reverse_lock
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp : : reverse_lock__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp : : reverse_lock__copy_ctor_f ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp : reverse_lock__unique_lock_ctor_p ]
+ [ thread-run2 ./sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp : reverse_lock__types_p ]
+ ;
+
+ explicit ts ;
+ test-suite ts
+ :
+ [ thread-run test_ml.cpp ]
+ ;
+
}
diff --git a/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp b/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp
index 02b6893edd..bf95d5d3a6 100644
--- a/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp
+++ b/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp
@@ -1,6 +1,6 @@
// Copyright (C) 2008 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread.hpp>
@@ -13,3 +13,15 @@ void test()
boost::thread t2;
t2=t1;
}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+
+}
diff --git a/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp b/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp
index 5c4600ec26..2e11407204 100644
--- a/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp
+++ b/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp
@@ -1,6 +1,6 @@
// Copyright (C) 2008 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread.hpp>
@@ -12,3 +12,15 @@ void test()
boost::thread t1(do_nothing);
boost::thread t2(t1);
}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+
+}
diff --git a/libs/thread/test/sync/conditions/condition_variable/assign_fail.cpp b/libs/thread/test/sync/conditions/condition_variable/assign_fail.cpp
new file mode 100644
index 0000000000..586cf16e08
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable/assign_fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable& operator=(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+
+void fail()
+{
+ boost::condition_variable cv0;
+ boost::condition_variable cv1;
+ cv1 = cv0;
+
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/conditions/condition_variable/copy_fail.cpp b/libs/thread/test/sync/conditions/condition_variable/copy_fail.cpp
new file mode 100644
index 0000000000..23b6e6f475
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable/copy_fail.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+void fail()
+{
+ boost::condition_variable cv0;
+ boost::condition_variable cv1(cv0);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/conditions/condition_variable/default_pass.cpp b/libs/thread/test/sync/conditions/condition_variable/default_pass.cpp
new file mode 100644
index 0000000000..465a12de86
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable/default_pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::condition_variable cv0;
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/sync/conditions/condition_variable/dtor_pass.cpp b/libs/thread/test/sync/conditions/condition_variable/dtor_pass.cpp
new file mode 100644
index 0000000000..533898ed46
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable/dtor_pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::condition_variable* cv;
+boost::mutex m;
+typedef boost::unique_lock<boost::mutex> Lock;
+
+bool f_ready = false;
+bool g_ready = false;
+
+void f()
+{
+ Lock lk(m);
+ f_ready = true;
+ cv->notify_one();
+ cv->wait(lk);
+ delete cv;
+}
+
+void g()
+{
+ Lock lk(m);
+ g_ready = true;
+ cv->notify_one();
+ while (!f_ready)
+ {
+ cv->wait(lk);
+ }
+ cv->notify_one();
+}
+
+int main()
+{
+ cv = new boost::condition_variable;
+ boost::thread th2(g);
+ Lock lk(m);
+ while (!g_ready)
+ {
+ cv->wait(lk);
+ }
+ lk.unlock();
+ boost::thread th1(f);
+ th1.join();
+ th2.join();
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/conditions/condition_variable/native_handle_pass.cpp b/libs/thread/test/sync/conditions/condition_variable/native_handle_pass.cpp
new file mode 100644
index 0000000000..9835f5920f
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable/native_handle_pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+#if defined BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE
+ //BOOST_STATIC_ASSERT((boost::is_same<boost::condition_variable::native_handle_type, pthread_cond_t*>::value));
+ boost::condition_variable cv;
+ boost::condition_variable::native_handle_type h = cv.native_handle();
+ BOOST_TEST(h != 0);
+#else
+#error "Test not applicable: BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE not defined for this platform as not supported"
+#endif
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/conditions/condition_variable/wait_for_pass.cpp b/libs/thread/test/sync/conditions/condition_variable/wait_for_pass.cpp
new file mode 100644
index 0000000000..f9b4a8351b
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable/wait_for_pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <iostream>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::condition_variable cv;
+boost::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ typedef boost::chrono::steady_clock Clock;
+ typedef boost::chrono::milliseconds milliseconds;
+ boost::unique_lock<boost::mutex> lk(mut);
+ BOOST_TEST(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ int count=0;
+ while (test2 == 0 && cv.wait_for(lk, milliseconds(250)) == boost::cv_status::no_timeout)
+ count++;
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ BOOST_TEST(t1 - t0 < milliseconds(250));
+ BOOST_TEST(test2 != 0);
+ }
+ else
+ {
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(t1 - t0 - milliseconds(250) < milliseconds(count*250+5+1000));
+ BOOST_TEST(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ boost::unique_lock<boost::mutex> lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ boost::unique_lock<boost::mutex> lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/libs/thread/test/sync/conditions/condition_variable/wait_for_pred_pass.cpp b/libs/thread/test/sync/conditions/condition_variable/wait_for_pred_pass.cpp
new file mode 100644
index 0000000000..bfe12cf1ad
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable/wait_for_pred_pass.cpp
@@ -0,0 +1,110 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+class Pred
+{
+ int& i_;
+public:
+ explicit Pred(int& i) :
+ i_(i)
+ {
+ }
+
+ bool operator()()
+ {
+ return i_ != 0;
+ }
+};
+
+boost::condition_variable cv;
+boost::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds milliseconds;
+ boost::unique_lock < boost::mutex > lk(mut);
+ BOOST_TEST(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ int count=0;
+ //bool r =
+ (void)cv.wait_for(lk, milliseconds(250), Pred(test2));
+ count++;
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(t1 - t0 < milliseconds(250+1000));
+ BOOST_TEST(test2 != 0);
+ }
+ else
+ {
+ BOOST_TEST(t1 - t0 - milliseconds(250) < milliseconds(count*250+2));
+ BOOST_TEST(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ boost::unique_lock < boost::mutex > lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ boost::unique_lock < boost::mutex > lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/libs/thread/test/sync/conditions/condition_variable/wait_until_pass.cpp b/libs/thread/test/sync/conditions/condition_variable/wait_until_pass.cpp
new file mode 100644
index 0000000000..3c29d68787
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable/wait_until_pass.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+struct Clock
+{
+ typedef boost::chrono::milliseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef boost::chrono::time_point<Clock> time_point;
+ static const bool is_steady = true;
+
+ static time_point now()
+ {
+ using namespace boost::chrono;
+ return time_point(duration_cast<duration> (steady_clock::now().time_since_epoch()));
+ }
+};
+
+boost::condition_variable cv;
+boost::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ boost::unique_lock < boost::mutex > lk(mut);
+ BOOST_TEST(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ Clock::time_point t = t0 + Clock::duration(250);
+ int count=0;
+ while (test2 == 0 && cv.wait_until(lk, t) == boost::cv_status::no_timeout)
+ count++;
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ BOOST_TEST(t1 - t0 < Clock::duration(250));
+ BOOST_TEST(test2 != 0);
+ }
+ else
+ {
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(t1 - t0 - Clock::duration(250) < Clock::duration(count*250+5+1000));
+ BOOST_TEST(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ boost::unique_lock < boost::mutex > lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ boost::unique_lock < boost::mutex > lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/libs/thread/test/sync/conditions/condition_variable/wait_until_pred_pass.cpp b/libs/thread/test/sync/conditions/condition_variable/wait_until_pred_pass.cpp
new file mode 100644
index 0000000000..eb70ea2010
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable/wait_until_pred_pass.cpp
@@ -0,0 +1,122 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+struct Clock
+{
+ typedef boost::chrono::milliseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef boost::chrono::time_point<Clock> time_point;
+ static const bool is_steady = true;
+
+ static time_point now()
+ {
+ using namespace boost::chrono;
+ return time_point(duration_cast<duration> (steady_clock::now().time_since_epoch()));
+ }
+};
+
+class Pred
+{
+ int& i_;
+public:
+ explicit Pred(int& i) :
+ i_(i)
+ {
+ }
+
+ bool operator()()
+ {
+ return i_ != 0;
+ }
+};
+
+boost::condition_variable cv;
+boost::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ BOOST_TEST(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ Clock::time_point t = t0 + Clock::duration(250);
+ bool r = cv.wait_until(lk, t, Pred(test2));
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ BOOST_TEST(t1 - t0 < Clock::duration(250));
+ BOOST_TEST(test2 != 0);
+ BOOST_TEST(r);
+ }
+ else
+ {
+ BOOST_TEST(t1 - t0 - Clock::duration(250) < Clock::duration(250+2));
+ BOOST_TEST(test2 == 0);
+ BOOST_TEST(!r);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ boost::unique_lock<boost::mutex> lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ boost::unique_lock<boost::mutex> lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/libs/thread/test/sync/conditions/condition_variable_any/assign_fail.cpp b/libs/thread/test/sync/conditions/condition_variable_any/assign_fail.cpp
new file mode 100644
index 0000000000..0329598e98
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable_any/assign_fail.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any& operator=(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+
+void fail()
+{
+ boost::condition_variable_any cv0;
+ boost::condition_variable_any cv1;
+ cv1 = cv0;
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/conditions/condition_variable_any/copy_fail.cpp b/libs/thread/test/sync/conditions/condition_variable_any/copy_fail.cpp
new file mode 100644
index 0000000000..0b2e0ad719
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable_any/copy_fail.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+void fail()
+{
+ boost::condition_variable_any cv0;
+ boost::condition_variable_any cv1(cv0);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/conditions/condition_variable_any/default_pass.cpp b/libs/thread/test/sync/conditions/condition_variable_any/default_pass.cpp
new file mode 100644
index 0000000000..21116ebc48
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable_any/default_pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::condition_variable_any cv0;
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/conditions/condition_variable_any/dtor_pass.cpp b/libs/thread/test/sync/conditions/condition_variable_any/dtor_pass.cpp
new file mode 100644
index 0000000000..7734d93b74
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable_any/dtor_pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::condition_variable_any* cv;
+boost::timed_mutex m;
+typedef boost::unique_lock<boost::timed_mutex> Lock;
+
+bool f_ready = false;
+bool g_ready = false;
+
+void f()
+{
+ Lock lk(m);
+ f_ready = true;
+ cv->notify_one();
+ cv->wait(lk);
+ delete cv;
+}
+
+void g()
+{
+ Lock lk(m);
+ g_ready = true;
+ cv->notify_one();
+ while (!f_ready)
+ {
+ cv->wait(lk);
+ }
+ cv->notify_one();
+}
+
+int main()
+{
+ cv = new boost::condition_variable_any;
+ boost::thread th2(g);
+ Lock lk(m);
+ while (!g_ready)
+ {
+ cv->wait(lk);
+ }
+ lk.unlock();
+ boost::thread th1(f);
+ th1.join();
+ th2.join();
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pass.cpp b/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pass.cpp
new file mode 100644
index 0000000000..634376075b
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pass.cpp
@@ -0,0 +1,99 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::condition_variable_any cv;
+
+typedef boost::timed_mutex L0;
+typedef boost::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds milliseconds;
+ L1 lk(m0);
+ BOOST_TEST(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ int count=0;
+ Clock::time_point t0 = Clock::now();
+ while (test2 == 0 &&
+ cv.wait_for(lk, milliseconds(250)) == boost::cv_status::no_timeout)
+ count++;
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ BOOST_TEST(t1 - t0 < milliseconds(250));
+ BOOST_TEST(test2 != 0);
+ }
+ else
+ {
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(t1 - t0 - milliseconds(250) < milliseconds(count*250+5+1000));
+ BOOST_TEST(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pred_pass.cpp b/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pred_pass.cpp
new file mode 100644
index 0000000000..b616459d22
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pred_pass.cpp
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+class Pred
+{
+ int& i_;
+public:
+ explicit Pred(int& i) :
+ i_(i)
+ {
+ }
+
+ bool operator()()
+ {
+ return i_ != 0;
+ }
+};
+
+boost::condition_variable_any cv;
+
+typedef boost::timed_mutex L0;
+typedef boost::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ typedef boost::chrono::system_clock Clock;
+ typedef boost::chrono::milliseconds milliseconds;
+ L1 lk(m0);
+ BOOST_TEST(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ //bool r =
+ (void)cv.wait_for(lk, milliseconds(250), Pred(test2));
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ BOOST_TEST(t1 - t0 < milliseconds(250));
+ BOOST_TEST(test2 != 0);
+ }
+ else
+ {
+ BOOST_TEST(t1 - t0 - milliseconds(250) < milliseconds(250+5));
+ BOOST_TEST(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pass.cpp b/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pass.cpp
new file mode 100644
index 0000000000..8fe9ce3a44
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pass.cpp
@@ -0,0 +1,112 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+struct Clock
+{
+ typedef boost::chrono::milliseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef boost::chrono::time_point<Clock> time_point;
+ static const bool is_steady = true;
+
+ static time_point now()
+ {
+ using namespace boost::chrono;
+ return time_point(duration_cast<duration> (steady_clock::now().time_since_epoch()));
+ }
+};
+
+boost::condition_variable_any cv;
+
+typedef boost::timed_mutex L0;
+typedef boost::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ L1 lk(m0);
+ BOOST_TEST(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ Clock::time_point t = t0 + Clock::duration(250);
+ int count=0;
+ while (test2 == 0 && cv.wait_until(lk, t) == boost::cv_status::no_timeout)
+ count++;
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ BOOST_TEST(t1 - t0 < Clock::duration(250));
+ BOOST_TEST(test2 != 0);
+ }
+ else
+ {
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(t1 - t0 - Clock::duration(250) < Clock::duration(250*count+5+1000));
+ BOOST_TEST(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pred_pass.cpp b/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pred_pass.cpp
new file mode 100644
index 0000000000..1b80a1e8c6
--- /dev/null
+++ b/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pred_pass.cpp
@@ -0,0 +1,126 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+struct Clock
+{
+ typedef boost::chrono::milliseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef boost::chrono::time_point<Clock> time_point;
+ static const bool is_steady = true;
+
+ static time_point now()
+ {
+ using namespace boost::chrono;
+ return time_point(duration_cast<duration> (steady_clock::now().time_since_epoch()));
+ }
+};
+
+class Pred
+{
+ int& i_;
+public:
+ explicit Pred(int& i) :
+ i_(i)
+ {
+ }
+
+ bool operator()()
+ {
+ return i_ != 0;
+ }
+};
+
+boost::condition_variable_any cv;
+
+typedef boost::timed_mutex L0;
+typedef boost::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ L1 lk(m0);
+ BOOST_TEST(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ Clock::time_point t = t0 + Clock::duration(250);
+ bool r = cv.wait_until(lk, t, Pred(test2));
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ BOOST_TEST(t1 - t0 < Clock::duration(250));
+ BOOST_TEST(test2 != 0);
+ BOOST_TEST(r);
+ }
+ else
+ {
+ BOOST_TEST(t1 - t0 - Clock::duration(250) < Clock::duration(250+2));
+ BOOST_TEST(test2 == 0);
+ BOOST_TEST(!r);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/libs/thread/test/sync/conditions/cv_status/cv_status_pass.cpp b/libs/thread/test/sync/conditions/cv_status/cv_status_pass.cpp
new file mode 100644
index 0000000000..becac4da5e
--- /dev/null
+++ b/libs/thread/test/sync/conditions/cv_status/cv_status_pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// static unsigned hardware_concurrency();
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ BOOST_TEST(boost::cv_status::no_timeout != boost::cv_status::timeout);
+ }
+ {
+ boost::cv_status st = boost::cv_status::no_timeout;
+ BOOST_TEST(st == boost::cv_status::no_timeout);
+ BOOST_TEST(boost::cv_status::no_timeout==st);
+ BOOST_TEST(st != boost::cv_status::timeout);
+ BOOST_TEST(boost::cv_status::timeout!=st);
+ }
+ {
+ boost::cv_status st = boost::cv_status::timeout;
+ BOOST_TEST(st == boost::cv_status::timeout);
+ BOOST_TEST(boost::cv_status::timeout==st);
+ BOOST_TEST(st != boost::cv_status::no_timeout);
+ BOOST_TEST(boost::cv_status::no_timeout!=st);
+ }
+ {
+ boost::cv_status st;
+ st = boost::cv_status::no_timeout;
+ BOOST_TEST(st == boost::cv_status::no_timeout);
+ BOOST_TEST(boost::cv_status::no_timeout==st);
+ BOOST_TEST(st != boost::cv_status::timeout);
+ BOOST_TEST(boost::cv_status::timeout!=st);
+ }
+ {
+ boost::cv_status st;
+ st = boost::cv_status::timeout;
+ BOOST_TEST(st == boost::cv_status::timeout);
+ BOOST_TEST(boost::cv_status::timeout==st);
+ BOOST_TEST(st != boost::cv_status::no_timeout);
+ BOOST_TEST(boost::cv_status::no_timeout!=st);
+ }
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/async/async_pass.cpp b/libs/thread/test/sync/futures/async/async_pass.cpp
new file mode 100644
index 0000000000..a41aea56b6
--- /dev/null
+++ b/libs/thread/test/sync/futures/async/async_pass.cpp
@@ -0,0 +1,186 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// template <class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(F&& f, Args&&... args);
+
+// template <class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(launch policy, F&& f, Args&&... args);
+
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
+#include <memory>
+#include <boost/detail/lightweight_test.hpp>
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef boost::chrono::milliseconds ms;
+
+int f0()
+{
+ boost::this_thread::sleep_for(ms(200));
+ return 3;
+}
+
+int i = 0;
+
+int& f1()
+{
+ boost::this_thread::sleep_for(ms(200));
+ return i;
+}
+
+void f2()
+{
+ boost::this_thread::sleep_for(ms(200));
+}
+
+boost::interprocess::unique_ptr<int> f3(int i)
+{
+ boost::this_thread::sleep_for(ms(200));
+ return boost::interprocess::unique_ptr<int>(new int(i));
+}
+
+boost::interprocess::unique_ptr<int> f4(boost::interprocess::unique_ptr<int>&& p)
+{
+ boost::this_thread::sleep_for(ms(200));
+ return boost::move(p);
+}
+
+int main()
+{
+ {
+ boost::future<int> f = boost::async(f0);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(100));
+ }
+ {
+ boost::future<int> f = boost::async(boost::launch::async, f0);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(100));
+ }
+ {
+ boost::future<int> f = boost::async(boost::launch::any, f0);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(100));
+ }
+ {
+ boost::future<int> f = boost::async(boost::launch::deferred, f0);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 > ms(100));
+ }
+
+ {
+ boost::future<int&> f = boost::async(f1);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(&f.get() == &i);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(100));
+ }
+ {
+ boost::future<int&> f = boost::async(boost::launch::async, f1);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(&f.get() == &i);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(100));
+ }
+ {
+ boost::future<int&> f = boost::async(boost::launch::any, f1);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(&f.get() == &i);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(100));
+ }
+ {
+ boost::future<int&> f = boost::async(boost::launch::deferred, f1);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(&f.get() == &i);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 > ms(100));
+ }
+
+ {
+ boost::future<void> f = boost::async(f2);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ f.get();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(100));
+ }
+ {
+ boost::future<void> f = boost::async(boost::launch::async, f2);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ f.get();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(100));
+ }
+ {
+ boost::future<void> f = boost::async(boost::launch::any, f2);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ f.get();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(100));
+ }
+ {
+ boost::future<void> f = boost::async(boost::launch::deferred, f2);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ f.get();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 > ms(100));
+ }
+
+ {
+ boost::future<boost::interprocess::unique_ptr<int>> f = boost::async(f3, 3);
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(*f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(100));
+ }
+
+ {
+ boost::future<boost::interprocess::unique_ptr<int>> f = boost::async(f4, boost::interprocess::unique_ptr<int>(new int(3)));
+ boost::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ BOOST_TEST(*f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 < ms(100));
+ }
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/future/copy_assign_fail.cpp b/libs/thread/test/sync/futures/future/copy_assign_fail.cpp
new file mode 100755
index 0000000000..3c08aaf239
--- /dev/null
+++ b/libs/thread/test/sync/futures/future/copy_assign_fail.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// future& operator=(const future&) = delete;
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f0 = p.get_future();
+ boost::future<T> f;
+ f = f0;
+ }
+
+ return boost::report_errors();
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/futures/future/copy_ctor_fail.cpp b/libs/thread/test/sync/futures/future/copy_ctor_fail.cpp
new file mode 100644
index 0000000000..b8fed11afb
--- /dev/null
+++ b/libs/thread/test/sync/futures/future/copy_ctor_fail.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class future<R>
+
+// future(const future&) = delete;
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f0 = p.get_future();
+ boost::future<T> f = f0;
+ }
+
+ return boost::report_errors();
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/futures/future/default_pass.cpp b/libs/thread/test/sync/futures/future/default_pass.cpp
new file mode 100755
index 0000000000..1b4cf392f6
--- /dev/null
+++ b/libs/thread/test/sync/futures/future/default_pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// future();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::future<int> f;
+ BOOST_TEST(!f.valid());
+ }
+ {
+ boost::future<int&> f;
+ BOOST_TEST(!f.valid());
+ }
+ {
+ boost::future<void> f;
+ BOOST_TEST(!f.valid());
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/future/dtor_pass.cpp b/libs/thread/test/sync/futures/future/dtor_pass.cpp
new file mode 100755
index 0000000000..d1873f12f3
--- /dev/null
+++ b/libs/thread/test/sync/futures/future/dtor_pass.cpp
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// ~promise();
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/exception/exception.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include <libs/thread/test/sync/futures/test_allocator.hpp>
+#endif
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ typedef int T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p(boost::allocator_arg, test_allocator<T>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ typedef int& T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p(boost::allocator_arg, test_allocator<int>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ typedef void T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p(boost::allocator_arg, test_allocator<T>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+#endif
+ {
+ typedef int T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(f.valid());
+ }
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/future/get_pass.cpp b/libs/thread/test/sync/futures/future/get_pass.cpp
new file mode 100755
index 0000000000..85b2900347
--- /dev/null
+++ b/libs/thread/test/sync/futures/future/get_pass.cpp
@@ -0,0 +1,171 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// future<R> get_future();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+namespace boost
+{
+template <typename T>
+struct wrap
+{
+ wrap(T const& v) : value(v){}
+ T value;
+
+};
+
+template <typename T>
+exception_ptr make_exception_ptr(T v) {
+ return copy_exception(wrap<T>(v));
+}
+}
+
+void func1(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+void func2(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(3));
+}
+
+int j = 0;
+
+void func3(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func4(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(3.5));
+}
+
+void func5(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_value();
+}
+
+void func6(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr('c'));
+}
+
+
+int main()
+{
+ {
+ typedef int T;
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ boost::thread(func1, boost::move(p)).detach();
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 3);
+ BOOST_TEST(!f.valid());
+ }
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ boost::thread(func2, boost::move(p)).detach();
+ try
+ {
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 3);
+ BOOST_TEST(false);
+ }
+ catch (int i)
+ {
+ BOOST_TEST(i == 3);
+ }
+ BOOST_TEST(!f.valid());
+ }
+ }
+// {
+// typedef int& T;
+// {
+// boost::promise<T> p;
+// boost::future<T> f = p.get_future();
+// boost::thread(func3, boost::move(p)).detach();
+// BOOST_TEST(f.valid());
+// BOOST_TEST(f.get() == 5);
+// BOOST_TEST(!f.valid());
+// }
+// {
+// boost::promise<T> p;
+// boost::future<T> f = p.get_future();
+// boost::thread(func4, boost::move(p)).detach();
+// try
+// {
+// BOOST_TEST(f.valid());
+// BOOST_TEST(f.get() == 3);
+// BOOST_TEST(false);
+// }
+// catch (double i)
+// {
+// BOOST_TEST(i == 3.5);
+// }
+// BOOST_TEST(!f.valid());
+// }
+// }
+// {
+// typedef void T;
+// {
+// boost::promise<T> p;
+// boost::future<T> f = p.get_future();
+// boost::thread(func5, boost::move(p)).detach();
+// BOOST_TEST(f.valid());
+// f.get();
+// BOOST_TEST(!f.valid());
+// }
+// {
+// boost::promise<T> p;
+// boost::future<T> f = p.get_future();
+// boost::thread(func6, boost::move(p)).detach();
+// try
+// {
+// BOOST_TEST(f.valid());
+// f.get();
+// BOOST_TEST(false);
+// }
+// catch (char i)
+// {
+// BOOST_TEST(i == 'c');
+// }
+// BOOST_TEST(!f.valid());
+// }
+// }
+
+
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/future/move_assign_pass.cpp b/libs/thread/test/sync/futures/future/move_assign_pass.cpp
new file mode 100755
index 0000000000..67117efaa5
--- /dev/null
+++ b/libs/thread/test/sync/futures/future/move_assign_pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class promise<R>
+
+// promise& operator=(promise&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int T;
+ boost::future<T> f0;
+ boost::future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::future<T> f0;
+ boost::future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::future<T> f0;
+ boost::future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+
+ return boost::report_errors();
+
+}
+
diff --git a/libs/thread/test/sync/futures/future/move_ctor_pass.cpp b/libs/thread/test/sync/futures/future/move_ctor_pass.cpp
new file mode 100755
index 0000000000..c16891189c
--- /dev/null
+++ b/libs/thread/test/sync/futures/future/move_ctor_pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class promise<R>
+
+// promise(promise&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int T;
+ boost::future<T> f0;
+ boost::future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::future<T> f0;
+ boost::future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::future<T> f0;
+ boost::future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/future/share_pass.cpp b/libs/thread/test/sync/futures/future/share_pass.cpp
new file mode 100644
index 0000000000..91c07f5cd1
--- /dev/null
+++ b/libs/thread/test/sync/futures/future/share_pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// shared_future<R> share() &&;
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> sf = f0.share();
+ boost::shared_future<T> f = sf;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int T;
+ boost::future<T> f0;
+ boost::shared_future<T> sf = f0.share();
+ boost::shared_future<T> f = sf;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> sf = f0.share();
+ boost::shared_future<T> f = sf;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::future<T> f0;
+ boost::shared_future<T> sf = f0.share();
+ boost::shared_future<T> f = sf;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> sf = f0.share();
+ boost::shared_future<T> f = sf;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::future<T> f0;
+ boost::shared_future<T> sf = f0.share();
+ boost::shared_future<T> f = sf;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp b/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp
new file mode 100644
index 0000000000..6b5dac1cff
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp
@@ -0,0 +1,149 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R>
+
+// template <class F, class Allocator>
+// explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
+
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include <libs/thread/test/sync/futures/test_allocator.hpp>
+
+double fct()
+{
+ return 5.0;
+}
+long lfct()
+{
+ return 5;
+}
+
+class A
+{
+ long data_;
+
+public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(A)
+ static int n_moves;
+ static int n_copies;
+
+ explicit A(long i) : data_(i)
+ {
+ }
+ A(BOOST_THREAD_RV_REF(A) a) : data_(BOOST_THREAD_RV(a).data_)
+ {
+ ++n_moves; BOOST_THREAD_RV(a).data_ = -1;
+ }
+ A(const A& a) : data_(a.data_)
+ {
+ ++n_copies;
+ }
+ ~A()
+ {
+ }
+
+ long operator()() const
+ { return data_;}
+ long operator()(long i, long j) const
+ { return data_ + i + j;}
+};
+
+int A::n_moves = 0;
+int A::n_copies = 0;
+
+int main()
+{
+ {
+ boost::packaged_task<double> p(boost::allocator_arg,
+ test_allocator<A>(), BOOST_THREAD_MAKE_RV_REF(A(5)));
+ BOOST_TEST(test_alloc_base::count > 0);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ BOOST_TEST(A::n_copies == 0);
+ BOOST_TEST(A::n_moves > 0);
+ BOOST_TEST(test_alloc_base::count == 0);
+ A::n_copies = 0;
+ A::n_copies = 0;
+ {
+ A a(5);
+ boost::packaged_task<double> p(boost::allocator_arg,
+ test_allocator<A>(), a);
+ BOOST_TEST(test_alloc_base::count > 0);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ BOOST_TEST(A::n_copies > 0);
+ BOOST_TEST(A::n_moves > 0);
+ BOOST_TEST(test_alloc_base::count == 0);
+ A::n_copies = 0;
+ A::n_copies = 0;
+ {
+ const A a(5);
+ boost::packaged_task<double> p(boost::allocator_arg,
+ test_allocator<A>(), a);
+ BOOST_TEST(test_alloc_base::count > 0);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ BOOST_TEST(A::n_copies > 0);
+ BOOST_TEST(A::n_moves > 0);
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::packaged_task<double> p(boost::allocator_arg,
+ test_allocator<A>(), fct);
+ BOOST_TEST(test_alloc_base::count > 0);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double> p(boost::allocator_arg,
+ test_allocator<A>(), &lfct);
+ BOOST_TEST(test_alloc_base::count > 0);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+
+ return boost::report_errors();
+}
+
+#else
+int main()
+{
+ return boost::report_errors();
+}
+#endif
+
diff --git a/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp b/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp
new file mode 100755
index 0000000000..890a2d569e
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// packaged_task& operator=(packaged_task&) = delete;
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+
+int main()
+{
+ {
+ boost::packaged_task<double> p0(A(5));
+ boost::packaged_task<double> p;
+ p = p0;
+ }
+
+ return boost::report_errors();
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp b/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp
new file mode 100644
index 0000000000..206c1f7990
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// packaged_task(packaged_task&) = delete;
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+
+int main()
+{
+ {
+ boost::packaged_task<double> p0(A(5));
+ boost::packaged_task<double> p(p0);
+
+ }
+
+ return boost::report_errors();
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp b/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp
new file mode 100644
index 0000000000..b2a371f293
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// packaged_task();
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+ {
+ boost::packaged_task<int> p;
+ BOOST_TEST(!p.valid());
+
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp b/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp
new file mode 100755
index 0000000000..15048a9150
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R>
+
+// ~packaged_task();
+;
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+void func(boost::packaged_task<double> p)
+{
+}
+
+void func2(boost::packaged_task<double> p)
+{
+ //p(3, 'a');
+ p();
+}
+
+int main()
+{
+ {
+ boost::packaged_task<double> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::thread(func, boost::move(p)).detach();
+ try
+ {
+ double i = f.get();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise));
+ }
+ }
+ {
+ boost::packaged_task<double> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::thread(func2, boost::move(p)).detach();
+ BOOST_TEST(f.get() == 5.0);
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp b/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp
new file mode 100644
index 0000000000..9010a811f3
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp
@@ -0,0 +1,127 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// template <class F>
+// explicit packaged_task(F&& f);
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+double fct()
+{
+ return 5.0;
+}
+long lfct()
+{
+ return 5;
+}
+
+class A
+{
+ long data_;
+
+public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(A)
+ static int n_moves;
+ static int n_copies;
+
+ explicit A(long i) : data_(i)
+ {
+ }
+ A(BOOST_THREAD_RV_REF(A) a) : data_(BOOST_THREAD_RV(a).data_)
+ {
+ ++n_moves; BOOST_THREAD_RV(a).data_ = -1;
+ }
+ A(const A& a) : data_(a.data_)
+ {
+ ++n_copies;
+ }
+ ~A()
+ {
+ }
+
+ long operator()() const
+ { return data_;}
+ long operator()(long i, long j) const
+ { return data_ + i + j;}
+};
+
+int A::n_moves = 0;
+int A::n_copies = 0;
+
+
+int main()
+{
+ {
+ boost::packaged_task<double> p(BOOST_THREAD_MAKE_RV_REF(A(5)));
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ BOOST_TEST(A::n_copies == 0);
+ BOOST_TEST(A::n_moves > 0);
+ }
+ A::n_copies = 0;
+ A::n_copies = 0;
+ {
+ A a(5);
+ boost::packaged_task<double> p(a);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ BOOST_TEST(A::n_copies > 0);
+ BOOST_TEST(A::n_moves > 0);
+ }
+
+ A::n_copies = 0;
+ A::n_copies = 0;
+ {
+ const A a(5);
+ boost::packaged_task<double> p(a);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ BOOST_TEST(A::n_copies > 0);
+ BOOST_TEST(A::n_moves > 0);
+ }
+ {
+ boost::packaged_task<double> p(fct);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double> p(&lfct);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp b/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp
new file mode 100755
index 0000000000..05c686341c
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R>
+
+// future<R> get_future();
+
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ boost::packaged_task<double> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::future_already_retrieved));
+ }
+ }
+ {
+ boost::packaged_task<double> p;
+ try
+ {
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp b/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp
new file mode 100755
index 0000000000..4cd7a139dc
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R>
+
+// void swap(packaged_task& other);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) :
+ data_(i)
+ {
+ }
+
+ long operator()() const
+ {
+ return data_;
+ }
+ long operator()(long i, long j) const
+ {
+ return data_ + i + j;
+ }
+};
+
+int main()
+{
+ {
+ boost::packaged_task<double> p0(A(5));
+ boost::packaged_task<double> p;
+ p.swap(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double> p0;
+ boost::packaged_task<double> p;
+ p.swap(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(!p.valid());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp b/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp
new file mode 100755
index 0000000000..60c34ca38f
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class promise<R>
+
+// promise& operator=(promise&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+
+int main()
+{
+
+ {
+ boost::packaged_task<double> p0(A(5));
+ boost::packaged_task<double> p;
+ p = boost::move(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ // p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double> p0;
+ boost::packaged_task<double> p;
+ p = boost::move(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(!p.valid());
+ }
+
+ return boost::report_errors();
+
+}
+
diff --git a/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp b/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp
new file mode 100755
index 0000000000..4c383cf7e4
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R>
+
+// packaged_task(packaged_task&& other);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+
+int main()
+{
+ {
+ boost::packaged_task<double> p0(A(5));
+ boost::packaged_task<double> p = boost::move(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double> p0;
+ boost::packaged_task<double> p = boost::move(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(!p.valid());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp b/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp
new file mode 100755
index 0000000000..6f91d3c95f
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// template <class R>
+// void
+// swap(packaged_task<R>& x, packaged_task<R>& y);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ boost::packaged_task<double> p0(A(5));
+ boost::packaged_task<double> p;
+ p.swap(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double> p0;
+ boost::packaged_task<double> p;
+ p.swap(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(!p.valid());
+ }
+
+}
+
diff --git a/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp b/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp
new file mode 100644
index 0000000000..3d7fd9d043
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp
@@ -0,0 +1,126 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// void operator()();
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) :
+ data_(i)
+ {
+ }
+
+ long operator()() const
+ {
+ return data_;
+ }
+ long operator()(long i, long j) const
+ {
+ if (j == 'z') throw A(6);
+ return data_ + i + j;
+ }
+};
+
+void func0(boost::packaged_task<double> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ //p(3, 'a');
+ p();
+}
+
+void func1(boost::packaged_task<double(int, char)> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ //p(3, 'z');
+ p();
+}
+
+void func2(boost::packaged_task<double(int, char)> p)
+{
+ //p(3, 'a');
+ p();
+ try
+ {
+ //p(3, 'c');
+ p();
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+}
+
+void func3(boost::packaged_task<double(int, char)> p)
+{
+ try
+ {
+ //p(3, 'a');
+ p();
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == make_error_code(boost::future_errc::no_state));
+ }
+}
+
+int main()
+{
+ {
+ boost::packaged_task<double> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::thread(func0, boost::move(p)).detach();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::thread(func1, boost::move(p)).detach();
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (const A& e)
+ {
+ //BOOST_TEST(e(3, 'a') == 106);
+ BOOST_TEST(e() == 5);
+ }
+ }
+ {
+ boost::packaged_task<double> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::thread t(func2, boost::move(p));
+ BOOST_TEST(f.get() == 5.0);
+ t.join();
+ }
+ {
+ boost::packaged_task<double> p;
+ boost::thread t(func3, boost::move(p));
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp b/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp
new file mode 100644
index 0000000000..558c118dd5
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// void operator()();
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) :
+ data_(i)
+ {
+ }
+
+ long operator()() const
+ {
+ return data_;
+ }
+ long operator()(long i, long j) const
+ {
+ if (j == 'z') throw A(6);
+ return data_ + i + j;
+ }
+};
+
+int main()
+{
+ {
+ boost::packaged_task<double> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ p.reset();
+ //p(4, 'a');
+ p();
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<double> p;
+ try
+ {
+ p.reset();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/packaged_task/types_pass.cpp b/libs/thread/test/sync/futures/packaged_task/types_pass.cpp
new file mode 100755
index 0000000000..d574c76d6b
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/types_pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// template<class R, class... ArgTypes>
+// class packaged_task<R(ArgTypes...)>
+// {
+// public:
+// typedef R result_type;
+
+
+#include <boost/thread/future.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct A {};
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::packaged_task<A>::result_type, A>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp b/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp
new file mode 100644
index 0000000000..f3e2f420c7
--- /dev/null
+++ b/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R(ArgTypes...)>
+
+// template <class Callable, class Alloc>
+// struct uses_allocator<packaged_task<Callable>, Alloc>
+// : true_type { };
+
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include <libs/thread/test/sync/futures/test_allocator.hpp>
+
+int main()
+{
+
+ BOOST_STATIC_ASSERT_MSG((boost::uses_allocator<boost::packaged_task<double>, test_allocator<double> >::value), "");
+
+ return boost::report_errors();
+}
+
+#else
+int main()
+{
+ return boost::report_errors();
+}
+#endif
+
+
diff --git a/libs/thread/test/sync/futures/promise/alloc_ctor_pass.cpp b/libs/thread/test/sync/futures/promise/alloc_ctor_pass.cpp
new file mode 100644
index 0000000000..55c86a79d2
--- /dev/null
+++ b/libs/thread/test/sync/futures/promise/alloc_ctor_pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// promise(allocator_arg_t, const Allocator& a);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include <libs/thread/test/sync/futures/test_allocator.hpp>
+
+int main()
+{
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<int> p(boost::allocator_arg, test_allocator<int>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<int&> p(boost::allocator_arg, test_allocator<int>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<void> p(boost::allocator_arg, test_allocator<void>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+
+
+ return boost::report_errors();
+}
+
+#else
+int main()
+{
+ return boost::report_errors();
+}
+#endif
+
+
diff --git a/libs/thread/test/sync/futures/promise/copy_assign_fail.cpp b/libs/thread/test/sync/futures/promise/copy_assign_fail.cpp
new file mode 100755
index 0000000000..4625477f8d
--- /dev/null
+++ b/libs/thread/test/sync/futures/promise/copy_assign_fail.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class promise<R>
+// promise& operator=(const promise& rhs) = delete;
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ boost::promise<int> p0;
+ boost::promise<int> p;
+ p = p0;
+ }
+
+ return boost::report_errors();
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/futures/promise/copy_ctor_fail.cpp b/libs/thread/test/sync/futures/promise/copy_ctor_fail.cpp
new file mode 100644
index 0000000000..8cfcfdfc84
--- /dev/null
+++ b/libs/thread/test/sync/futures/promise/copy_ctor_fail.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class promise<R>
+// promise& operator=(const promise& rhs) = delete;
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ boost::promise<int> p0;
+ boost::promise<int> p(p0);
+ }
+
+ return boost::report_errors();
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/futures/promise/default_pass.cpp b/libs/thread/test/sync/futures/promise/default_pass.cpp
new file mode 100755
index 0000000000..566d659a8b
--- /dev/null
+++ b/libs/thread/test/sync/futures/promise/default_pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// promise();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::promise<int> p;
+ boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ {
+ boost::promise<int&> p;
+ boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ {
+ boost::promise<void> p;
+ std::cout << __LINE__ << std::endl;
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ std::cout << __LINE__ << std::endl;
+ BOOST_TEST(f.valid());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/promise/dtor_pass.cpp b/libs/thread/test/sync/futures/promise/dtor_pass.cpp
new file mode 100755
index 0000000000..e449c03787
--- /dev/null
+++ b/libs/thread/test/sync/futures/promise/dtor_pass.cpp
@@ -0,0 +1,116 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// ~promise();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ typedef int T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p.set_value(3);
+ }
+ BOOST_TEST(f.get() == 3);
+ }
+ {
+ typedef int T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+ try
+ {
+ //T i =
+ (void)f.get();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise));
+ }
+ }
+ {
+ typedef int& T;
+ int i = 4;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p.set_value(i);
+ }
+ BOOST_TEST(&f.get() == &i);
+ }
+ {
+ typedef int& T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+ try
+ {
+ //T i =
+ (void)f.get();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise));
+ }
+ }
+ {
+ typedef void T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p.set_value();
+ }
+ f.get();
+ BOOST_TEST(true);
+ }
+ {
+ typedef void T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise));
+ }
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/promise/get_future_pass.cpp b/libs/thread/test/sync/futures/promise/get_future_pass.cpp
new file mode 100755
index 0000000000..13a63b13dc
--- /dev/null
+++ b/libs/thread/test/sync/futures/promise/get_future_pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// future<R> get_future();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ boost::promise<double> p;
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p.set_value(105.5);
+ BOOST_TEST(f.get() == 105.5);
+ }
+ {
+ boost::promise<double> p;
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::future_already_retrieved));
+ }
+ }
+ {
+ boost::promise<double> p;
+ boost::promise<double> p0 = boost::move(p);
+ try
+ {
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/promise/move_assign_pass.cpp b/libs/thread/test/sync/futures/promise/move_assign_pass.cpp
new file mode 100755
index 0000000000..d41c9a7cf4
--- /dev/null
+++ b/libs/thread/test/sync/futures/promise/move_assign_pass.cpp
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class promise<R>
+
+// promise& operator=(promise&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include <libs/thread/test/sync/futures/test_allocator.hpp>
+#endif
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<int> p0(boost::allocator_arg, test_allocator<int>());
+ boost::promise<int> p(boost::allocator_arg, test_allocator<int>());
+ BOOST_TEST(test_alloc_base::count == 2);
+ p = boost::move(p0);
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+
+ {
+ boost::promise<int&> p0(boost::allocator_arg, test_allocator<int>());
+ boost::promise<int&> p(boost::allocator_arg, test_allocator<int>());
+ BOOST_TEST(test_alloc_base::count == 2);
+ p = boost::move(p0);
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<void> p0(boost::allocator_arg, test_allocator<void>());
+ boost::promise<void> p(boost::allocator_arg, test_allocator<void>());
+ BOOST_TEST(test_alloc_base::count == 2);
+ p = boost::move(p0);
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+
+#endif
+ {
+ boost::promise<int> p0;
+ boost::promise<int> p;
+ p = boost::move(p0);
+ boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+ {
+ boost::promise<int&> p0;
+ boost::promise<int&> p;
+ p = boost::move(p0);
+ boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+ {
+ boost::promise<void> p0;
+ boost::promise<void> p;
+ p = boost::move(p0);
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+ return boost::report_errors();
+
+}
+
diff --git a/libs/thread/test/sync/futures/promise/move_ctor_pass.cpp b/libs/thread/test/sync/futures/promise/move_ctor_pass.cpp
new file mode 100755
index 0000000000..44edaa497c
--- /dev/null
+++ b/libs/thread/test/sync/futures/promise/move_ctor_pass.cpp
@@ -0,0 +1,151 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class promise<R>
+
+// promise(promise&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include <libs/thread/test/sync/futures/test_allocator.hpp>
+#endif
+
+boost::mutex m;
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<int> p0(boost::allocator_arg, test_allocator<int>());
+ boost::promise<int> p(boost::move(p0));
+ BOOST_TEST(test_alloc_base::count == 1);
+ std::cout << __LINE__ << std::endl;
+ boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ std::cout << __LINE__ << std::endl;
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ std::cout << __LINE__ << std::endl;
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ std::cout << __LINE__ << std::endl;
+ BOOST_TEST(test_alloc_base::count == 1);
+ }
+ std::cout << __LINE__ << std::endl;
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<int&> p0(boost::allocator_arg, test_allocator<int>());
+ boost::promise<int&> p(boost::move(p0));
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<void> p0(boost::allocator_arg, test_allocator<void>());
+ boost::promise<void> p(boost::move(p0));
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+#endif
+ {
+ boost::promise<int> p0;
+ boost::promise<int> p(boost::move(p0));
+ std::cout << __LINE__ << std::endl;
+ boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ std::cout << __LINE__ << std::endl;
+ BOOST_TEST(f.valid());
+ std::cout << __LINE__ << std::endl;
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ std::cout << __LINE__ << std::endl;
+ }
+ std::cout << __LINE__ << std::endl;
+ {
+ boost::promise<int&> p0;
+ boost::promise<int&> p(boost::move(p0));
+ boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+ {
+ boost::promise<void> p0;
+ boost::promise<void> p(boost::move(p0));
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/futures/promise/use_allocator_pass.cpp b/libs/thread/test/sync/futures/promise/use_allocator_pass.cpp
new file mode 100644
index 0000000000..c11c06b39e
--- /dev/null
+++ b/libs/thread/test/sync/futures/promise/use_allocator_pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// promise(allocator_arg_t, const Allocator& a);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include <libs/thread/test/sync/futures/test_allocator.hpp>
+
+int main()
+{
+
+ BOOST_STATIC_ASSERT_MSG((boost::uses_allocator<boost::promise<int>, test_allocator<int> >::value), "");
+ BOOST_STATIC_ASSERT_MSG((boost::uses_allocator<boost::promise<int&>, test_allocator<int&> >::value), "");
+ BOOST_STATIC_ASSERT_MSG((boost::uses_allocator<boost::promise<void>, test_allocator<void> >::value), "");
+
+ return boost::report_errors();
+}
+
+#else
+int main()
+{
+ return boost::report_errors();
+}
+#endif
+
+
diff --git a/libs/thread/test/sync/futures/test_allocator.hpp b/libs/thread/test/sync/futures/test_allocator.hpp
new file mode 100644
index 0000000000..a73d7d8e33
--- /dev/null
+++ b/libs/thread/test/sync/futures/test_allocator.hpp
@@ -0,0 +1,158 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_THREAD_TEST_ALLOCATOR_HPP
+#define BOOST_THREAD_TEST_ALLOCATOR_HPP
+
+#include <cstddef>
+#include <boost/type_traits.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <cstdlib>
+#include <new>
+#include <climits>
+
+class test_alloc_base
+{
+public:
+ static int count;
+public:
+ static int throw_after;
+};
+
+int test_alloc_base::count = 0;
+int test_alloc_base::throw_after = INT_MAX;
+
+template <class T>
+class test_allocator
+ : public test_alloc_base
+{
+ int data_;
+
+ template <class U> friend class test_allocator;
+public:
+
+ typedef unsigned size_type;
+ typedef int difference_type;
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef typename boost::add_lvalue_reference<value_type>::type reference;
+ typedef typename boost::add_lvalue_reference<const value_type>::type const_reference;
+
+ template <class U> struct rebind {typedef test_allocator<U> other;};
+
+ test_allocator() throw() : data_(-1) {}
+ explicit test_allocator(int i) throw() : data_(i) {}
+ test_allocator(const test_allocator& a) throw()
+ : data_(a.data_) {}
+ template <class U> test_allocator(const test_allocator<U>& a) throw()
+ : data_(a.data_) {}
+ ~test_allocator() throw() {data_ = 0;}
+ pointer address(reference x) const {return &x;}
+ const_pointer address(const_reference x) const {return &x;}
+ pointer allocate(size_type n, const void* = 0)
+ {
+ if (count >= throw_after)
+ throw std::bad_alloc();
+ ++count;
+ return (pointer)std::malloc(n * sizeof(T));
+ }
+ void deallocate(pointer p, size_type)
+ {--count; std::free(p);}
+ size_type max_size() const throw()
+ {return UINT_MAX / sizeof(T);}
+ void construct(pointer p, const T& val)
+ {::new(p) T(val);}
+
+ void construct(pointer p, BOOST_THREAD_RV_REF(T) val)
+ {::new(p) T(boost::move(val));}
+
+ void destroy(pointer p) {p->~T();}
+
+ friend bool operator==(const test_allocator& x, const test_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const test_allocator& x, const test_allocator& y)
+ {return !(x == y);}
+};
+
+template <>
+class test_allocator<void>
+ : public test_alloc_base
+{
+ int data_;
+
+ template <class U> friend class test_allocator;
+public:
+
+ typedef unsigned size_type;
+ typedef int difference_type;
+ typedef void value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+
+ template <class U> struct rebind {typedef test_allocator<U> other;};
+
+ test_allocator() throw() : data_(-1) {}
+ explicit test_allocator(int i) throw() : data_(i) {}
+ test_allocator(const test_allocator& a) throw()
+ : data_(a.data_) {}
+ template <class U> test_allocator(const test_allocator<U>& a) throw()
+ : data_(a.data_) {}
+ ~test_allocator() throw() {data_ = 0;}
+
+ friend bool operator==(const test_allocator& x, const test_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const test_allocator& x, const test_allocator& y)
+ {return !(x == y);}
+};
+
+template <class T>
+class other_allocator
+{
+ int data_;
+
+ template <class U> friend class other_allocator;
+
+public:
+ typedef T value_type;
+
+ other_allocator() : data_(-1) {}
+ explicit other_allocator(int i) : data_(i) {}
+ template <class U> other_allocator(const other_allocator<U>& a)
+ : data_(a.data_) {}
+ T* allocate(std::size_t n)
+ {return (T*)std::malloc(n * sizeof(T));}
+ void deallocate(T* p, std::size_t)
+ {std::free(p);}
+
+ other_allocator select_on_container_copy_construction() const
+ {return other_allocator(-2);}
+
+ friend bool operator==(const other_allocator& x, const other_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const other_allocator& x, const other_allocator& y)
+ {return !(x == y);}
+
+ typedef boost::true_type propagate_on_container_copy_assignment;
+ typedef boost::true_type propagate_on_container_move_assignment;
+ typedef boost::true_type propagate_on_container_swap;
+
+#ifdef BOOST_NO_SFINAE_EXPR
+ std::size_t max_size() const
+ {return UINT_MAX / sizeof(T);}
+#endif // BOOST_NO_SFINAE_EXPR
+
+};
+
+#endif // BOOST_THREAD_TEST_ALLOCATOR_HPP
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp
new file mode 100755
index 0000000000..1f6fde9842
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard(mutex_type& m, adopt_lock_t);
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#endif
+boost::mutex m;
+
+void f()
+{
+#ifdef BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ m.lock();
+ boost::lock_guard<boost::mutex> lg(m, boost::adopt_lock);
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ m.lock();
+ boost::lock_guard<boost::mutex> lg(m, boost::adopt_lock);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#ifdef BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp
new file mode 100755
index 0000000000..5e90b4b3e8
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard& operator=(lock_guard const&) = delete;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::lock_guard<boost::mutex> lk0(m0);
+ boost::lock_guard<boost::mutex> lk1(m1);
+ lk1 = lk0;
+
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp
new file mode 100755
index 0000000000..81b2238171
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard(lock_guard const&) = delete;
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::lock_guard<boost::mutex> lk0(m0);
+ boost::lock_guard<boost::mutex> lk1 = lk0;
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/default_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/default_pass.cpp
new file mode 100755
index 0000000000..f57849646b
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/default_pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard(lock_guard const&) = delete;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#endif
+
+boost::mutex m;
+
+void f()
+{
+#ifdef BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ boost::lock_guard<boost::mutex> lg(m);
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ boost::lock_guard<boost::mutex> lg(m);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#ifdef BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/types_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/types_pass.cpp
new file mode 100755
index 0000000000..161d69d5f1
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/types_pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class lock_guard
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::lock_guard<boost::mutex>::mutex_type,
+ boost::mutex>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp
new file mode 100755
index 0000000000..77808fc028
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp
@@ -0,0 +1,41 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class reverse_lock;
+
+// reverse_lock& operator=(reverse_lock const&) = delete;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/reverse_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+ boost::mutex m0;
+ boost::mutex m1;
+ boost::unique_lock<boost::mutex> lk0(m0);
+ boost::unique_lock<boost::mutex> lk1(m1);
+ {
+ boost::reverse_lock<boost::unique_lock<boost::mutex> > lg0(lk0);
+ boost::reverse_lock<boost::unique_lock<boost::mutex> > lg1(lk1);
+ lg1 = lg0;
+ }
+
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp
new file mode 100755
index 0000000000..a5e2348457
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp
@@ -0,0 +1,40 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class reverse_lock;
+
+// reverse_lock(reverse_lock const&) = delete;
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/reverse_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::mutex m0;
+ boost::unique_lock<boost::mutex> lk0(m0);
+ {
+ boost::reverse_lock<boost::unique_lock<boost::mutex> > lg0(lk0);
+ boost::reverse_lock<boost::unique_lock<boost::mutex> > lg1(lg0);
+ }
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp
new file mode 100755
index 0000000000..30dafa1fa4
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp
@@ -0,0 +1,33 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class unlock_guard
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/reverse_lock.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::reverse_lock<boost::unique_lock<boost::mutex> >::mutex_type,
+ boost::mutex>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp
new file mode 100755
index 0000000000..99b4f00c33
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp
@@ -0,0 +1,52 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unlock_guard;
+
+// unlock_guard(unlock_guard const&) = delete;
+
+#include <boost/thread/reverse_lock.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+ {
+ boost::mutex m;
+ boost::unique_lock<boost::mutex> lk(m);
+ BOOST_TEST(lk.owns_lock());
+ BOOST_TEST(lk.mutex()==&m);
+
+ {
+ boost::reverse_lock<boost::unique_lock<boost::mutex> > lg(lk);
+ BOOST_TEST(!lk.owns_lock());
+ BOOST_TEST(lk.mutex()==0);
+ }
+ BOOST_TEST(lk.owns_lock());
+ BOOST_TEST(lk.mutex()==&m);
+ }
+
+ {
+ boost::mutex m;
+ boost::unique_lock<boost::mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(! lk.owns_lock());
+ BOOST_TEST(lk.mutex()==&m);
+ {
+ boost::reverse_lock<boost::unique_lock<boost::mutex> > lg(lk);
+ BOOST_TEST(!lk.owns_lock());
+ BOOST_TEST(lk.mutex()==0);
+ }
+ BOOST_TEST(lk.owns_lock());
+ BOOST_TEST(lk.mutex()==&m);
+ }
+
+
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp
new file mode 100755
index 0000000000..732ad6325a
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(mutex_type& m, adopt_lock_t);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+ boost::shared_mutex m;
+ m.lock();
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::adopt_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp
new file mode 100755
index 0000000000..55ef440c80
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock& operator=(shared_lock const&) = delete;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ boost::shared_lock<boost::shared_mutex> lk0(m0);
+ boost::shared_lock<boost::shared_mutex> lk1(m1);
+ lk1 = lk0;
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp
new file mode 100755
index 0000000000..1756a63342
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(shared_lock const&) = delete;
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ boost::shared_lock<boost::shared_mutex> lk0(m0);
+ boost::shared_lock<boost::shared_mutex> lk1 = lk0;
+ BOOST_TEST(lk1.mutex() == &m1);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp
new file mode 100755
index 0000000000..e7b8127711
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(shared_lock const&) = delete;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::shared_lock<boost::shared_mutex> ul;
+ BOOST_TEST(!ul.owns_lock());
+ BOOST_TEST(ul.mutex() == 0);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp
new file mode 100755
index 0000000000..caeec9c2db
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(mutex_type& m, adopt_lock_t);
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::shared_mutex m;
+ m.lock();
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp
new file mode 100755
index 0000000000..d08304f762
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Rep, class Period>
+// shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/chrono/chrono_io.hpp>
+
+boost::shared_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ boost::shared_lock<boost::shared_mutex> lk(m, ms(300)+ms(1000));
+ BOOST_TEST(lk.owns_lock() == true);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ boost::shared_lock<boost::shared_mutex> lk(m, ms(250));
+ BOOST_TEST(lk.owns_lock() == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ boost::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ boost::this_thread::sleep_for(ms(300)+ms(1000));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp
new file mode 100755
index 0000000000..b3348f706b
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(shared_lock const&) = delete;
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m0);
+ boost::shared_lock<boost::shared_mutex> lk1(m1);
+ lk1 = boost::move(lk0);
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+
+ boost::shared_lock<boost::shared_mutex> lk1;
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(m0));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex> lk0(m0);
+ boost::shared_lock<boost::shared_mutex> lk1(m1);
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(boost::move(lk0)));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+
+ boost::shared_lock<boost::shared_mutex> lk1;
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(boost::unique_lock<boost::shared_mutex>(m0)));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk0(m0);
+ boost::shared_lock<boost::shared_mutex> lk1(m1);
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(boost::move(lk0)));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+
+ boost::shared_lock<boost::shared_mutex> lk1;
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(boost::upgrade_lock<boost::shared_mutex>(m0)));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ }
+ return boost::report_errors();
+
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp
new file mode 100755
index 0000000000..173f6b5c99
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock& operator=(shared_lock&& u);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk( (BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(m))));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp
new file mode 100644
index 0000000000..90325ed6ad
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock& operator=(shared_lock&& u);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+
+ {
+ boost::unique_lock<boost::shared_mutex> lk0(m);
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk( (boost::unique_lock<boost::shared_mutex>(m)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp
new file mode 100644
index 0000000000..b98183e233
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock& operator=(shared_lock&& u);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk0(m);
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk( (boost::upgrade_lock<boost::shared_mutex>(m)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp
new file mode 100755
index 0000000000..0a0d191a82
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// explicit shared_lock(Mutex& m);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ boost::shared_lock<boost::shared_mutex> ul(m);
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(2000)); // within 2.5ms
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ boost::shared_lock<boost::shared_mutex> ul(m);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp
new file mode 100755
index 0000000000..9308b8550c
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Clock, class Duration>
+// shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ boost::shared_lock<boost::shared_mutex> lk(m, Clock::now() + ms(300)+ms(1000));
+ BOOST_TEST(lk.owns_lock() == true);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ boost::shared_lock<boost::shared_mutex> lk(m, Clock::now() + ms(250));
+ BOOST_TEST(lk.owns_lock() == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ boost::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(300)+ms(1000));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp
new file mode 100755
index 0000000000..9f4251e9b6
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(mutex_type& m, try_to_lock_t);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ {
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ while (true)
+ {
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ if (lk.owns_lock()) break;
+ }
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#else
+// time_point t0 = Clock::now();
+// {
+// boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+ while (true)
+ {
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ if (lk.owns_lock()) break;
+ }
+ //time_point t1 = Clock::now();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp
new file mode 100755
index 0000000000..3ef6f7c2c1
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp
@@ -0,0 +1,114 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// void lock();
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::shared_lock < boost::shared_mutex > lk(m, boost::defer_lock);
+ time_point t0 = Clock::now();
+ lk.lock();
+ time_point t1 = Clock::now();
+ BOOST_TEST(lk.owns_lock() == true);
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+#else
+ boost::shared_lock < boost::shared_mutex > lk(m, boost::defer_lock);
+ //time_point t0 = Clock::now();
+ lk.lock();
+ //time_point t1 = Clock::now();
+ BOOST_TEST(lk.owns_lock() == true);
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp
new file mode 100755
index 0000000000..027cf64d0a
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/locks.hpp>
+//#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_for_called = false;
+
+typedef boost::chrono::milliseconds ms;
+
+struct shared_mutex
+{
+ template <class Rep, class Period>
+ bool try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ BOOST_TEST(rel_time == ms(5));
+ try_lock_for_called = !try_lock_for_called;
+ return try_lock_for_called;
+ }
+ void unlock_shared()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock_for(ms(5)) == true);
+ BOOST_TEST(try_lock_for_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_for(ms(5));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock_for(ms(5)) == false);
+ BOOST_TEST(try_lock_for_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_for(ms(5));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp
new file mode 100755
index 0000000000..5ba50cc3e5
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/locks.hpp>
+//#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_called = false;
+
+struct shared_mutex
+{
+ bool try_lock_shared()
+ {
+ try_lock_called = !try_lock_called;
+ return try_lock_called;
+ }
+ void unlock_shared()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock() == true);
+ BOOST_TEST(try_lock_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock() == false);
+ BOOST_TEST(try_lock_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp
new file mode 100755
index 0000000000..77dd7dc8cc
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_until_called = false;
+
+struct shared_mutex
+{
+ template <class Clock, class Duration>
+ bool try_lock_shared_until(const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ typedef boost::chrono::milliseconds ms;
+ BOOST_TEST(Clock::now() - abs_time < ms(5));
+ try_lock_until_called = !try_lock_until_called;
+ return try_lock_until_called;
+ }
+ void unlock_shared()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ typedef boost::chrono::steady_clock Clock;
+ boost::shared_lock<shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock_until(Clock::now()) == true);
+ BOOST_TEST(try_lock_until_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock_until(Clock::now()) == false);
+ BOOST_TEST(try_lock_until_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp
new file mode 100755
index 0000000000..1eaba78c93
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/locks.hpp>
+//#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool unlock_called = false;
+
+struct shared_mutex
+{
+ void lock_shared()
+ {
+ }
+ void unlock_shared()
+ {
+ unlock_called = true;
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<shared_mutex> lk(m);
+ lk.unlock();
+ BOOST_TEST(unlock_called == true);
+ BOOST_TEST(lk.owns_lock() == false);
+ try
+ {
+ lk.unlock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+ lk.release();
+ try
+ {
+ lk.unlock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp
new file mode 100755
index 0000000000..949166f58b
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// void swap(shared_lock& u);
+
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct shared_mutex
+{
+ void lock_shared()
+ {
+ }
+ void unlock_shared()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<shared_mutex> lk1(m);
+ boost::shared_lock<shared_mutex> lk2;
+ lk1.swap(lk2);
+ BOOST_TEST(lk1.mutex() == 0);
+ BOOST_TEST(lk1.owns_lock() == false);
+ BOOST_TEST(lk2.mutex() == &m);
+ BOOST_TEST(lk2.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp
new file mode 100755
index 0000000000..766d63ec31
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex>
+// void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y);
+
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct shared_mutex
+{
+ void lock_shared()
+ {
+ }
+ void unlock_shared()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<shared_mutex> lk1(m);
+ boost::shared_lock<shared_mutex> lk2;
+ swap(lk1, lk2);
+ BOOST_TEST(lk1.mutex() == 0);
+ BOOST_TEST(lk1.owns_lock() == false);
+ BOOST_TEST(lk2.mutex() == &m);
+ BOOST_TEST(lk2.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp
new file mode 100755
index 0000000000..5a88c1f296
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// void Mutex* release();
+
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct shared_mutex
+{
+ static int lock_count;
+ static int unlock_count;
+ void lock_shared()
+ {
+ ++lock_count;
+ }
+ void unlock_shared()
+ {
+ ++unlock_count;
+ }
+};
+
+int shared_mutex::lock_count = 0;
+int shared_mutex::unlock_count = 0;
+
+shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<shared_mutex> lk(m);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(shared_mutex::lock_count == 1);
+ BOOST_TEST(shared_mutex::unlock_count == 0);
+ BOOST_TEST(lk.release() == &m);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(shared_mutex::lock_count == 1);
+ BOOST_TEST(shared_mutex::unlock_count == 0);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp
new file mode 100755
index 0000000000..49c051be92
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// Mutex *mutex() const;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<boost::shared_mutex> lk0;
+ BOOST_TEST(lk0.mutex() == 0);
+ boost::shared_lock<boost::shared_mutex> lk1(m);
+ BOOST_TEST(lk1.mutex() == &m);
+ lk1.unlock();
+ BOOST_TEST(lk1.mutex() == &m);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp
new file mode 100755
index 0000000000..71712feef5
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// explicit operator bool() const;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ boost::shared_lock < boost::shared_mutex > lk0;
+ BOOST_TEST(bool(lk0) == false);
+ boost::shared_lock < boost::shared_mutex > lk1(m);
+ BOOST_TEST(bool(lk1) == true);
+ lk1.unlock();
+ BOOST_TEST(bool(lk1) == false);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp
new file mode 100755
index 0000000000..900300b6fa
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// bool owns_lock() const;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<boost::shared_mutex> lk0;
+ BOOST_TEST(lk0.owns_lock() == false);
+ boost::shared_lock<boost::shared_mutex> lk1(m);
+ BOOST_TEST(lk1.owns_lock() == true);
+ lk1.unlock();
+ BOOST_TEST(lk1.owns_lock() == false);
+
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/types_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/types_pass.cpp
new file mode 100755
index 0000000000..f919586dff
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/types_pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class shared_lock
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::shared_lock<boost::shared_mutex>::mutex_type,
+ boost::shared_mutex>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp
new file mode 100755
index 0000000000..d8532f0971
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_lock_guard.hpp>
+
+// template <class Mutex> class shared_lock_guard;
+
+// shared_lock_guard(mutex_type& m, adopt_lock_t);
+
+#include <boost/thread/shared_lock_guard.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+boost::shared_mutex m;
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ m.lock();
+ boost::shared_lock_guard<boost::shared_mutex> lg(m, boost::adopt_lock);
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ m.lock();
+ boost::shared_lock_guard<boost::shared_mutex> lg(m, boost::adopt_lock);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp
new file mode 100755
index 0000000000..4f68b2efe6
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_lock_guard.hpp>
+
+// template <class Mutex> class shared_lock_guard;
+
+// shared_lock_guard& operator=(shared_lock_guard const&) = delete;
+
+#include <boost/thread/shared_lock_guard.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ boost::shared_lock_guard<boost::shared_mutex> lk0(m0);
+ boost::shared_lock_guard<boost::shared_mutex> lk1(m1);
+ lk1 = lk0;
+
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp
new file mode 100755
index 0000000000..a6659ab06f
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_lock_guard.hpp>
+
+// template <class Mutex> class shared_lock_guard;
+
+// shared_lock_guard(shared_lock_guard const&) = delete;
+
+
+#include <boost/thread/shared_lock_guard.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ boost::shared_lock_guard<boost::shared_mutex> lk0(m0);
+ boost::shared_lock_guard<boost::shared_mutex> lk1 = lk0;
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp
new file mode 100755
index 0000000000..1494e153ee
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_lock_guard.hpp>
+
+// template <class Mutex> class shared_lock_guard;
+
+// shared_lock_guard(shared_lock_guard const&) = delete;
+
+#include <boost/thread/shared_lock_guard.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+boost::shared_mutex m;
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ boost::shared_lock_guard<boost::shared_mutex> lg(m);
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ boost::shared_lock_guard<boost::shared_mutex> lg(m);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp
new file mode 100755
index 0000000000..2fe4c9a403
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_lock_guard.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class shared_lock_guard
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/shared_lock_guard.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::shared_lock_guard<boost::shared_mutex>::mutex_type,
+ boost::shared_mutex>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp
new file mode 100644
index 0000000000..1d40d903dc
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(mutex_type& m, adopt_lock_t);
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+ boost::mutex m;
+ m.lock();
+ boost::unique_lock<boost::mutex> lk(m, boost::adopt_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp
new file mode 100644
index 0000000000..58227670ec
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock& operator=(unique_lock const&) = delete;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::unique_lock<boost::mutex> lk0(m0);
+ boost::unique_lock<boost::mutex> lk1(m1);
+ lk1 = lk0;
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp
new file mode 100644
index 0000000000..4f666be29c
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(unique_lock const&) = delete;
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::unique_lock<boost::mutex> lk0(m0);
+ boost::unique_lock<boost::mutex> lk1 = lk0;
+ BOOST_TEST(lk1.mutex() == &m1);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp
new file mode 100644
index 0000000000..409d30e819
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(unique_lock const&) = delete;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::unique_lock<boost::mutex> ul;
+ BOOST_TEST(!ul.owns_lock());
+ BOOST_TEST(ul.mutex() == 0);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp
new file mode 100644
index 0000000000..9aae0544c9
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(mutex_type& m, adopt_lock_t);
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::mutex m;
+ m.lock();
+ boost::unique_lock<boost::mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp
new file mode 100644
index 0000000000..679b19f44f
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Rep, class Period>
+// unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/chrono/chrono_io.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::timed_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ boost::unique_lock<boost::timed_mutex> lk(m, ms(300)+ms(1000));
+ BOOST_TEST(lk.owns_lock() == true);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ boost::unique_lock<boost::timed_mutex> lk(m, ms(250));
+ BOOST_TEST(lk.owns_lock() == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ boost::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(300)+ms(1000));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp
new file mode 100644
index 0000000000..09e5d98fc2
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(unique_lock const&) = delete;
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ {
+ boost::unique_lock<boost::mutex> lk0(m0);
+ boost::unique_lock<boost::mutex> lk1(m1);
+ lk1 = boost::move(lk0);
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+
+ {
+
+ boost::unique_lock<boost::mutex> lk1;
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(m0));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ }
+ return boost::report_errors();
+
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp
new file mode 100644
index 0000000000..ee0d2a8c2c
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(unique_lock&& u);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ {
+ boost::unique_lock<boost::mutex> lk0(m);
+ boost::unique_lock<boost::mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk( (BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(m))));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp
new file mode 100644
index 0000000000..3c27882d4c
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Rep, class Period>
+// unique_lock(shared_lock<mutex_type>&&,
+// const chrono::duration<Rep, Period>&);
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex>
+ lk(boost::shared_lock<boost::shared_mutex>(m), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp
new file mode 100644
index 0000000000..796be4d996
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(shared_lock&& u, try_to_lock);
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock );
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex> lk(boost::shared_lock<boost::shared_mutex>(m), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp
new file mode 100644
index 0000000000..be61c91d08
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Clock, class Duration>
+// unique_lock(shared_lock<mutex_type>&&,
+// const chrono::time_point<Clock, Duration>&);
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex>
+ lk( boost::shared_lock<boost::shared_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp
new file mode 100644
index 0000000000..bfa2cbb2f4
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Clock, class Duration>
+// unique_lock(shared_lock<mutex_type>&&,
+// const chrono::duration<Rep, Period>&);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::upgrade_mutex m;
+
+int main()
+{
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m);
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::upgrade_mutex>
+ lk(boost::upgrade_lock<boost::upgrade_mutex>(m), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp
new file mode 100644
index 0000000000..ad7a8e7bf3
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(upgrade_lock&& u);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::upgrade_mutex m;
+
+int main()
+{
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m);
+ boost::unique_lock<boost::upgrade_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::upgrade_mutex> lk( (BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::upgrade_mutex>(m))));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::upgrade_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::upgrade_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp
new file mode 100644
index 0000000000..e1fa9fc4d7
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(upgrade_lock&& u, try_to_lock);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::upgrade_mutex m;
+
+int main()
+{
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m);
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::try_to_lock );
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::upgrade_lock<boost::upgrade_mutex>(m), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp
new file mode 100644
index 0000000000..11051e22a5
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Clock, class Duration>
+// unique_lock(shared_lock<mutex_type>&&,
+// const chrono::time_point<Clock, Duration>&);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::upgrade_mutex m;
+
+int main()
+{
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m);
+ boost::unique_lock<boost::upgrade_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::upgrade_mutex>
+ lk( boost::upgrade_lock<boost::upgrade_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::upgrade_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::upgrade_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp
new file mode 100644
index 0000000000..aa393be2c0
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// explicit unique_lock(Mutex& m);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+boost::mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ boost::unique_lock<boost::mutex> ul(m);
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ boost::unique_lock<boost::mutex> ul(m);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp
new file mode 100644
index 0000000000..629cb47049
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Clock, class Duration>
+// unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::timed_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ boost::unique_lock<boost::timed_mutex> lk(m, Clock::now() + ms(300)+ms(1000));
+ BOOST_TEST(lk.owns_lock() == true);
+ time_point t1 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ ns d = t1 - t0 - ms(250);
+ BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ boost::unique_lock<boost::timed_mutex> lk(m, Clock::now() + ms(250));
+ BOOST_TEST(lk.owns_lock() == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ boost::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp
new file mode 100644
index 0000000000..e542ff9caf
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(mutex_type& m, try_to_lock_t);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+boost::mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ {
+ boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ while (true)
+ {
+ boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+ if (lk.owns_lock()) break;
+ }
+ time_point t1 = Clock::now();
+ //m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#else
+// time_point t0 = Clock::now();
+// {
+// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+ while (true)
+ {
+ boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+ if (lk.owns_lock()) break;
+ }
+ //time_point t1 = Clock::now();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp
new file mode 100644
index 0000000000..919637c9ff
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp
@@ -0,0 +1,115 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// void lock();
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+
+boost::mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::unique_lock < boost::mutex > lk(m, boost::defer_lock);
+ time_point t0 = Clock::now();
+ lk.lock();
+ time_point t1 = Clock::now();
+ BOOST_TEST(lk.owns_lock() == true);
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+#else
+ boost::unique_lock < boost::mutex > lk(m, boost::defer_lock);
+ //time_point t0 = Clock::now();
+ lk.lock();
+ //time_point t1 = Clock::now();
+ BOOST_TEST(lk.owns_lock() == true);
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp
new file mode 100644
index 0000000000..078b8c7c42
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/locks.hpp>
+//#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+
+bool try_lock_for_called = false;
+
+typedef boost::chrono::milliseconds ms;
+
+struct mutex
+{
+ template <class Rep, class Period>
+ bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ BOOST_TEST(rel_time == ms(5));
+ try_lock_for_called = !try_lock_for_called;
+ return try_lock_for_called;
+ }
+ void unlock()
+ {
+ }
+};
+
+mutex m;
+
+int main()
+{
+ boost::unique_lock<mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock_for(ms(5)) == true);
+ BOOST_TEST(try_lock_for_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_for(ms(5));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock_for(ms(5)) == false);
+ BOOST_TEST(try_lock_for_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_for(ms(5));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp
new file mode 100644
index 0000000000..af7a8408b3
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/locks.hpp>
+//#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_called = false;
+
+struct mutex
+{
+ bool try_lock()
+ {
+ try_lock_called = !try_lock_called;
+ return try_lock_called;
+ }
+ void unlock()
+ {
+ }
+};
+
+mutex m;
+
+int main()
+{
+ boost::unique_lock<mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock() == true);
+ BOOST_TEST(try_lock_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock() == false);
+ BOOST_TEST(try_lock_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp
new file mode 100644
index 0000000000..a642cf8fb5
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+
+bool try_lock_until_called = false;
+
+struct mutex
+{
+ template <class Clock, class Duration>
+ bool try_lock_until(const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ typedef boost::chrono::milliseconds ms;
+ BOOST_TEST(Clock::now() - abs_time < ms(5));
+ try_lock_until_called = !try_lock_until_called;
+ return try_lock_until_called;
+ }
+ void unlock()
+ {
+ }
+};
+
+mutex m;
+
+int main()
+{
+ typedef boost::chrono::steady_clock Clock;
+ boost::unique_lock<mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock_until(Clock::now()) == true);
+ BOOST_TEST(try_lock_until_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock_until(Clock::now()) == false);
+ BOOST_TEST(try_lock_until_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp
new file mode 100644
index 0000000000..21a6306a86
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// bool unlock();
+
+#include <boost/thread/locks.hpp>
+//#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+bool unlock_called = false;
+
+struct mutex
+{
+ void lock()
+ {
+ }
+ void unlock()
+ {
+ unlock_called = true;
+ }
+};
+
+mutex m;
+
+int main()
+{
+ boost::unique_lock<mutex> lk(m);
+ lk.unlock();
+ BOOST_TEST(unlock_called == true);
+ BOOST_TEST(lk.owns_lock() == false);
+ try
+ {
+ lk.unlock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+ lk.release();
+ try
+ {
+ lk.unlock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp
new file mode 100644
index 0000000000..b0334907dd
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// void swap(unique_lock& u);
+
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct mutex
+{
+ void lock()
+ {
+ }
+ void unlock()
+ {
+ }
+};
+
+mutex m;
+
+int main()
+{
+ boost::unique_lock<mutex> lk1(m);
+ boost::unique_lock<mutex> lk2;
+ lk1.swap(lk2);
+ BOOST_TEST(lk1.mutex() == 0);
+ BOOST_TEST(lk1.owns_lock() == false);
+ BOOST_TEST(lk2.mutex() == &m);
+ BOOST_TEST(lk2.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp
new file mode 100644
index 0000000000..90ec4b0d3b
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex>
+// void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y);
+
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct mutex
+{
+ void lock()
+ {
+ }
+ void unlock()
+ {
+ }
+};
+
+mutex m;
+
+int main()
+{
+ boost::unique_lock<mutex> lk1(m);
+ boost::unique_lock<mutex> lk2;
+ swap(lk1, lk2);
+ BOOST_TEST(lk1.mutex() == 0);
+ BOOST_TEST(lk1.owns_lock() == false);
+ BOOST_TEST(lk2.mutex() == &m);
+ BOOST_TEST(lk2.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp
new file mode 100644
index 0000000000..c755bc4da1
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// void Mutex* release();
+
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct mutex
+{
+ static int lock_count;
+ static int unlock_count;
+ void lock()
+ {
+ ++lock_count;
+ }
+ void unlock()
+ {
+ ++unlock_count;
+ }
+};
+
+int mutex::lock_count = 0;
+int mutex::unlock_count = 0;
+
+mutex m;
+
+int main()
+{
+ boost::unique_lock<mutex> lk(m);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(mutex::lock_count == 1);
+ BOOST_TEST(mutex::unlock_count == 0);
+ BOOST_TEST(lk.release() == &m);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(mutex::lock_count == 1);
+ BOOST_TEST(mutex::unlock_count == 0);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp
new file mode 100644
index 0000000000..8eb924205f
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// Mutex *mutex() const;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ boost::unique_lock<boost::mutex> lk0;
+ BOOST_TEST(lk0.mutex() == 0);
+ boost::unique_lock<boost::mutex> lk1(m);
+ BOOST_TEST(lk1.mutex() == &m);
+ lk1.unlock();
+ BOOST_TEST(lk1.mutex() == &m);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp
new file mode 100644
index 0000000000..21b65a1eff
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// explicit operator bool() const;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ {
+ boost::unique_lock<boost::mutex> lk0;
+ BOOST_TEST(bool(lk0) == false);
+ boost::unique_lock<boost::mutex> lk1(m);
+ BOOST_TEST(bool(lk1) == true);
+ lk1.unlock();
+ BOOST_TEST(bool(lk1) == false);
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lk0;
+ if (lk0) BOOST_TEST(false);
+ boost::unique_lock<boost::mutex> lk1(m);
+ if (!lk1) BOOST_TEST(false);
+ lk1.unlock();
+ if (lk1) BOOST_TEST(false);
+ }
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp
new file mode 100644
index 0000000000..a4d46ec5c0
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// explicit operator bool() const;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ {
+ boost::unique_lock<boost::mutex> lk0;
+ int i = int(lk0);
+ BOOST_TEST(i == 0);
+ }
+
+ return boost::report_errors();
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp
new file mode 100644
index 0000000000..6a78db9c17
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// bool owns_lock() const;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ boost::unique_lock<boost::mutex> lk0;
+ BOOST_TEST(lk0.owns_lock() == false);
+ boost::unique_lock<boost::mutex> lk1(m);
+ BOOST_TEST(lk1.owns_lock() == true);
+ lk1.unlock();
+ BOOST_TEST(lk1.owns_lock() == false);
+
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/types_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/types_pass.cpp
new file mode 100644
index 0000000000..db65d79fca
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/types_pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class unique_lock
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::unique_lock<boost::mutex>::mutex_type,
+ boost::mutex>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp
new file mode 100755
index 0000000000..865301c108
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(mutex_type& m, adopt_lock_t);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+ boost::shared_mutex m;
+ m.lock();
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::adopt_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp
new file mode 100755
index 0000000000..a33c5e6b54
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock& operator=(upgrade_lock const&) = delete;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ boost::upgrade_lock<boost::shared_mutex> lk0(m0);
+ boost::upgrade_lock<boost::shared_mutex> lk1(m1);
+ lk1 = lk0;
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp
new file mode 100755
index 0000000000..1a8557a5d1
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(upgrade_lock const&) = delete;
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ boost::upgrade_lock<boost::shared_mutex> lk0(m0);
+ boost::upgrade_lock<boost::shared_mutex> lk1(lk0);
+ BOOST_TEST(lk1.mutex() == &m1);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp
new file mode 100755
index 0000000000..bd8108fb72
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(upgrade_lock const&) = delete;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::upgrade_lock<boost::shared_mutex> ul;
+ BOOST_TEST(!ul.owns_lock());
+ BOOST_TEST(ul.mutex() == 0);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp
new file mode 100755
index 0000000000..33a5bf8823
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(mutex_type& m, adopt_lock_t);
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::shared_mutex m;
+ m.lock();
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp
new file mode 100755
index 0000000000..a62438a8f6
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Rep, class Period>
+// upgrade_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/chrono/chrono_io.hpp>
+
+boost::shared_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ boost::upgrade_lock<boost::shared_mutex> lk(m, ms(300)+ms(1000));
+ BOOST_TEST(lk.owns_lock() == true);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ boost::upgrade_lock<boost::shared_mutex> lk(m, ms(250));
+ BOOST_TEST(lk.owns_lock() == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ boost::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp
new file mode 100755
index 0000000000..2bea7a406b
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(upgrade_lock const&) = delete;
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk0(m0);
+ boost::upgrade_lock<boost::shared_mutex> lk1(m1);
+ lk1 = boost::move(lk0);
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+
+ boost::upgrade_lock<boost::shared_mutex> lk1;
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::shared_mutex>(m0));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex> lk0(m0);
+ boost::upgrade_lock<boost::shared_mutex> lk1(m1);
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::shared_mutex>(boost::move(lk0)));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+
+ boost::upgrade_lock<boost::shared_mutex> lk1;
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::shared_mutex>(boost::unique_lock<boost::shared_mutex>(m0)));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ }
+ return boost::report_errors();
+
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp
new file mode 100755
index 0000000000..f41c7047b1
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock& operator=(upgrade_lock&& u);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk( (BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::shared_mutex>(m))));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp
new file mode 100644
index 0000000000..e2abb3944f
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Clock, class Duration>
+// upgrade_lock(shared_lock<mutex_type>&&,
+// const chrono::duration<Rep, Period>&);
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex>
+ lk(boost::shared_lock<boost::shared_mutex>(m), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp
new file mode 100644
index 0000000000..9cb798051e
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(shared_lock&& u, try_to_lock);
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock );
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::shared_lock<boost::shared_mutex>(m), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp
new file mode 100644
index 0000000000..66025c6fc4
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Clock, class Duration>
+// upgrade_lock(shared_lock<mutex_type>&&,
+// const chrono::time_point<Clock, Duration>&);
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex>
+ lk( boost::shared_lock<boost::shared_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp
new file mode 100644
index 0000000000..8afac6372a
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock& operator=(unique_lock&& u);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::unique_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk( (boost::unique_lock<boost::shared_mutex>(m)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp
new file mode 100755
index 0000000000..104a171ed9
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// explicit upgrade_lock(Mutex& m);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ boost::upgrade_lock<boost::shared_mutex> ul(m);
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ boost::upgrade_lock<boost::shared_mutex> ul(m);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp
new file mode 100755
index 0000000000..26ad92ace2
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Clock, class Duration>
+// upgrade_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ boost::upgrade_lock<boost::shared_mutex> lk(m, Clock::now() + ms(300)+ms(1000));
+ BOOST_TEST(lk.owns_lock() == true);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ boost::upgrade_lock<boost::shared_mutex> lk(m, Clock::now() + ms(250));
+ BOOST_TEST(lk.owns_lock() == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ boost::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp
new file mode 100755
index 0000000000..9cad5cb6ac
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp
@@ -0,0 +1,103 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(mutex_type& m, try_to_lock_t);
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ while (true)
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ if (lk.owns_lock()) break;
+ }
+ time_point t1 = Clock::now();
+ //m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#else
+// time_point t0 = Clock::now();
+// {
+// boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+ while (true)
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ if (lk.owns_lock()) break;
+ }
+ //time_point t1 = Clock::now();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp
new file mode 100755
index 0000000000..cf95c3725e
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp
@@ -0,0 +1,114 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// void lock();
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::upgrade_lock < boost::shared_mutex > lk(m, boost::defer_lock);
+ time_point t0 = Clock::now();
+ lk.lock();
+ time_point t1 = Clock::now();
+ BOOST_TEST(lk.owns_lock() == true);
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+#else
+ boost::upgrade_lock < boost::shared_mutex > lk(m, boost::defer_lock);
+ //time_point t0 = Clock::now();
+ lk.lock();
+ //time_point t1 = Clock::now();
+ BOOST_TEST(lk.owns_lock() == true);
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp
new file mode 100755
index 0000000000..9298e9473b
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/locks.hpp>
+//#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_for_called = false;
+
+typedef boost::chrono::milliseconds ms;
+
+struct shared_mutex
+{
+ template <class Rep, class Period>
+ bool try_lock_upgrade_for(const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ BOOST_TEST(rel_time == ms(5));
+ try_lock_for_called = !try_lock_for_called;
+ return try_lock_for_called;
+ }
+ void unlock_upgrade()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock_for(ms(5)) == true);
+ BOOST_TEST(try_lock_for_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_for(ms(5));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock_for(ms(5)) == false);
+ BOOST_TEST(try_lock_for_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_for(ms(5));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp
new file mode 100755
index 0000000000..1136ae48e9
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/locks.hpp>
+//#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_called = false;
+
+struct shared_mutex
+{
+ bool try_lock_upgrade()
+ {
+ try_lock_called = !try_lock_called;
+ return try_lock_called;
+ }
+ void unlock_upgrade()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock() == true);
+ BOOST_TEST(try_lock_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock() == false);
+ BOOST_TEST(try_lock_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp
new file mode 100755
index 0000000000..aca6708de3
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_until_called = false;
+
+struct shared_mutex
+{
+ template <class Clock, class Duration>
+ bool try_lock_upgrade_until(const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ typedef boost::chrono::milliseconds ms;
+ BOOST_TEST(Clock::now() - abs_time < ms(5));
+ try_lock_until_called = !try_lock_until_called;
+ return try_lock_until_called;
+ }
+ void unlock_upgrade()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ typedef boost::chrono::steady_clock Clock;
+ boost::upgrade_lock<shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock_until(Clock::now()) == true);
+ BOOST_TEST(try_lock_until_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock_until(Clock::now()) == false);
+ BOOST_TEST(try_lock_until_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp
new file mode 100755
index 0000000000..2116561d66
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/locks.hpp>
+//#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool unlock_called = false;
+
+struct shared_mutex
+{
+ void lock_upgrade()
+ {
+ }
+ void unlock_upgrade()
+ {
+ unlock_called = true;
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<shared_mutex> lk(m);
+ lk.unlock();
+ BOOST_TEST(unlock_called == true);
+ BOOST_TEST(lk.owns_lock() == false);
+ try
+ {
+ lk.unlock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+ lk.release();
+ try
+ {
+ lk.unlock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp
new file mode 100755
index 0000000000..e892aa6317
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// void swap(upgrade_lock& u);
+
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct shared_mutex
+{
+ void lock_upgrade()
+ {
+ }
+ void unlock_upgrade()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<shared_mutex> lk1(m);
+ boost::upgrade_lock<shared_mutex> lk2;
+ lk1.swap(lk2);
+ BOOST_TEST(lk1.mutex() == 0);
+ BOOST_TEST(lk1.owns_lock() == false);
+ BOOST_TEST(lk2.mutex() == &m);
+ BOOST_TEST(lk2.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp
new file mode 100755
index 0000000000..b7983bef34
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex>
+// void swap(upgrade_lock<Mutex>& x, upgrade_lock<Mutex>& y);
+
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct shared_mutex
+{
+ void lock_upgrade()
+ {
+ }
+ void unlock_upgrade()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<shared_mutex> lk1(m);
+ boost::upgrade_lock<shared_mutex> lk2;
+ swap(lk1, lk2);
+ BOOST_TEST(lk1.mutex() == 0);
+ BOOST_TEST(lk1.owns_lock() == false);
+ BOOST_TEST(lk2.mutex() == &m);
+ BOOST_TEST(lk2.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp
new file mode 100755
index 0000000000..b5976023c2
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// void Mutex* release();
+
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct shared_mutex
+{
+ static int lock_count;
+ static int unlock_count;
+ void lock_upgrade()
+ {
+ ++lock_count;
+ }
+ void unlock_upgrade()
+ {
+ ++unlock_count;
+ }
+};
+
+int shared_mutex::lock_count = 0;
+int shared_mutex::unlock_count = 0;
+
+shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<shared_mutex> lk(m);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(shared_mutex::lock_count == 1);
+ BOOST_TEST(shared_mutex::unlock_count == 0);
+ BOOST_TEST(lk.release() == &m);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(shared_mutex::lock_count == 1);
+ BOOST_TEST(shared_mutex::unlock_count == 0);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp
new file mode 100755
index 0000000000..a730f2c2bb
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// Mutex *mutex() const;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<boost::shared_mutex> lk0;
+ BOOST_TEST(lk0.mutex() == 0);
+ boost::upgrade_lock<boost::shared_mutex> lk1(m);
+ BOOST_TEST(lk1.mutex() == &m);
+ lk1.unlock();
+ BOOST_TEST(lk1.mutex() == &m);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp
new file mode 100755
index 0000000000..dedd389994
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// explicit operator bool() const;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock < boost::shared_mutex > lk0;
+ BOOST_TEST(bool(lk0) == false);
+ boost::upgrade_lock < boost::shared_mutex > lk1(m);
+ BOOST_TEST(bool(lk1) == true);
+ lk1.unlock();
+ BOOST_TEST(bool(lk1) == false);
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp
new file mode 100755
index 0000000000..e6969f2cbd
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// bool owns_lock() const;
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<boost::shared_mutex> lk0;
+ BOOST_TEST(lk0.owns_lock() == false);
+ boost::upgrade_lock<boost::shared_mutex> lk1(m);
+ BOOST_TEST(lk1.owns_lock() == true);
+ lk1.unlock();
+ BOOST_TEST(lk1.owns_lock() == false);
+
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp
new file mode 100755
index 0000000000..660ed5ef85
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class upgrade_lock
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::upgrade_lock<boost::upgrade_mutex>::mutex_type,
+ boost::upgrade_mutex>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/mutex/assign_fail.cpp b/libs/thread/test/sync/mutual_exclusion/mutex/assign_fail.cpp
new file mode 100644
index 0000000000..1ec3b2172a
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/mutex/assign_fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+// mutex& operator=(const mutex&) = delete;
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::mutex m0;
+ boost::mutex m1(m0);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/mutex/copy_fail.cpp b/libs/thread/test/sync/mutual_exclusion/mutex/copy_fail.cpp
new file mode 100644
index 0000000000..7966ebd44d
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/mutex/copy_fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+// mutex(const mutex&) = delete;
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::mutex m0;
+ boost::mutex m1(m0);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/mutex/default_pass.cpp b/libs/thread/test/sync/mutual_exclusion/mutex/default_pass.cpp
new file mode 100644
index 0000000000..a911eefcf4
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/mutex/default_pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+// mutex();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::mutex m0;
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/mutex/lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/mutex/lock_pass.cpp
new file mode 100644
index 0000000000..6839a77099
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/mutex/lock_pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+// void lock();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+boost::mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#else
+ //time_point t0 = Clock::now();
+ m.lock();
+ //time_point t1 = Clock::now();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
+
diff --git a/libs/thread/test/sync/mutual_exclusion/mutex/native_handle_pass.cpp b/libs/thread/test/sync/mutual_exclusion/mutex/native_handle_pass.cpp
new file mode 100644
index 0000000000..489ec375d2
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/mutex/native_handle_pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+// typedef pthread_mutex_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+#if defined BOOST_THREAD_DEFINES_MUTEX_NATIVE_HANDLE
+ boost::mutex m;
+ boost::mutex::native_handle_type h = m.native_handle();
+ BOOST_TEST(h);
+#else
+#error "Test not applicable: BOOST_THREAD_DEFINES_MUTEX_NATIVE_HANDLE not defined for this platform as not supported"
+#endif
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_pass.cpp
new file mode 100644
index 0000000000..3de59c5631
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+// bool try_lock();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+boost::mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#else
+ //time_point t0 = Clock::now();
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ //time_point t1 = Clock::now();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#endif
+
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
+
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_mutex/assign_fail.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/assign_fail.cpp
new file mode 100644
index 0000000000..6279734a8c
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/assign_fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_mutex;
+
+// recursive_mutex& operator=(const recursive_mutex&) = delete;
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::recursive_mutex m0;
+ boost::recursive_mutex m1(m0);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_mutex/copy_fail.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/copy_fail.cpp
new file mode 100644
index 0000000000..d2e657e3dc
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/copy_fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_mutex;
+
+// recursive_mutex(const recursive_mutex&) = delete;
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::recursive_mutex m0;
+ boost::recursive_mutex m1(m0);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_mutex/default_pass.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/default_pass.cpp
new file mode 100644
index 0000000000..6b61997201
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/default_pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_mutex;
+
+// recursive_mutex();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::recursive_mutex m0;
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_mutex/lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/lock_pass.cpp
new file mode 100644
index 0000000000..7f9427b30e
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/lock_pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_mutex;
+
+// void lock();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+boost::recursive_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.lock();
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#else
+ //time_point t0 = Clock::now();
+ m.lock();
+ //time_point t1 = Clock::now();
+ m.lock();
+ m.unlock();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
+
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp
new file mode 100644
index 0000000000..b46619cd65
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_mutex;
+
+// typedef pthread_recursive_mutex_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+#if defined BOOST_THREAD_DEFINES_RECURSIVE_MUTEX_NATIVE_HANDLE
+ boost::recursive_mutex m;
+ boost::recursive_mutex::native_handle_type h = m.native_handle();
+ BOOST_TEST(h);
+#else
+#error "Test not applicable: BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE not defined for this platform as not supported"
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp
new file mode 100644
index 0000000000..9a6f4d349a
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_mutex;
+
+// bool try_lock();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+boost::recursive_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+// BOOST_TEST(!m.try_lock());
+// BOOST_TEST(!m.try_lock());
+// BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ time_point t1 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#else
+ //time_point t0 = Clock::now();
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ //time_point t1 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
+
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp
new file mode 100644
index 0000000000..18e24533e1
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::recursive_timed_mutex m0;
+ boost::recursive_timed_mutex m1(m0);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp
new file mode 100644
index 0000000000..9970a27976
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// recursive_timed_mutex(const recursive_timed_mutex&) = delete;
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::recursive_timed_mutex m0;
+ boost::recursive_timed_mutex m1(m0);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp
new file mode 100644
index 0000000000..1e75b7b049
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// recursive_timed_mutex();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::recursive_timed_mutex m0;
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp
new file mode 100644
index 0000000000..1c46d57be0
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// void lock();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+
+boost::recursive_timed_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.lock();
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#else
+ //time_point t0 = Clock::now();
+ m.lock();
+ //time_point t1 = Clock::now();
+ m.lock();
+ m.unlock();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
+
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp
new file mode 100644
index 0000000000..bcd375e535
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// typedef pthread_recursive_mutex_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+#if defined BOOST_THREAD_DEFINES_RECURSIVE_TIMED_MUTEX_NATIVE_HANDLE
+ boost::recursive_timed_mutex m;
+ boost::recursive_timed_mutex::native_handle_type h = m.native_handle();
+ BOOST_TEST(h);
+#else
+#error "Test not applicable: BOOST_THREAD_DEFINES_RECURSIVE_TIMED_MUTEX_NATIVE_HANDLE not defined for this platform as not supported"
+#endif
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp
new file mode 100644
index 0000000000..bcbd53905f
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+
+boost::recursive_timed_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(m.try_lock_for(ms(300)+ms(1000)) == true);
+ time_point t1 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ BOOST_TEST(m.try_lock_for(ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ boost::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(400));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp
new file mode 100644
index 0000000000..0903020a0c
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// bool try_lock();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+
+boost::recursive_timed_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ time_point t1 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#else
+ //time_point t0 = Clock::now();
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ //time_point t1 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
+
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp
new file mode 100644
index 0000000000..523384ca09
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex>
+
+// class recursive_timed_mutex;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::recursive_timed_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(300) + ms(1000)) == true);
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ boost::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/libs/thread/test/sync/mutual_exclusion/shared_mutex/assign_fail.cpp b/libs/thread/test/sync/mutual_exclusion/shared_mutex/assign_fail.cpp
new file mode 100755
index 0000000000..1b2f0b17e7
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/shared_mutex/assign_fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// class shared_mutex;
+
+// shared_mutex& operator=(const shared_mutex&) = delete;
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::shared_mutex m0;
+ boost::shared_mutex m1(m0);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/shared_mutex/copy_fail.cpp b/libs/thread/test/sync/mutual_exclusion/shared_mutex/copy_fail.cpp
new file mode 100755
index 0000000000..38e91a0be8
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/shared_mutex/copy_fail.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// class shared_mutex;
+
+// shared_mutex(const shared_mutex&) = delete;
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::shared_mutex m0;
+ boost::shared_mutex m1(m0);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/shared_mutex/default_pass.cpp b/libs/thread/test/sync/mutual_exclusion/shared_mutex/default_pass.cpp
new file mode 100755
index 0000000000..730c9cafca
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/shared_mutex/default_pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class shared_mutex;
+
+// shared_mutex();
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::shared_mutex m0;
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/shared_mutex/lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/shared_mutex/lock_pass.cpp
new file mode 100755
index 0000000000..01111afe43
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/shared_mutex/lock_pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// class shared_mutex;
+
+// void lock();
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#else
+ //time_point t0 = Clock::now();
+ m.lock();
+ //time_point t1 = Clock::now();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp b/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp
new file mode 100755
index 0000000000..c961ef363d
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// class shared_mutex;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(m.try_lock_for(ms(300)+ms(1000)) == true);
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ BOOST_TEST(m.try_lock_for(ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ boost::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp
new file mode 100755
index 0000000000..2f18834a8d
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// class shared_mutex;
+
+// bool try_lock();
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#else
+ //time_point t0 = Clock::now();
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ //time_point t1 = Clock::now();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp b/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp
new file mode 100755
index 0000000000..2a4fb12d8e
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// class shared_mutex;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(300) + ms(1000)) == true);
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ boost::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/timed_mutex/assign_fail.cpp b/libs/thread/test/sync/mutual_exclusion/timed_mutex/assign_fail.cpp
new file mode 100644
index 0000000000..9ad3da7fac
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/timed_mutex/assign_fail.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// timed_mutex& operator=(const timed_mutex&) = delete;
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::timed_mutex m0;
+ boost::timed_mutex m1(m0);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/timed_mutex/copy_fail.cpp b/libs/thread/test/sync/mutual_exclusion/timed_mutex/copy_fail.cpp
new file mode 100644
index 0000000000..550d26860e
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/timed_mutex/copy_fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// timed_mutex(const timed_mutex&) = delete;
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::timed_mutex m0;
+ boost::timed_mutex m1(m0);
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+}
diff --git a/libs/thread/test/sync/mutual_exclusion/timed_mutex/default_pass.cpp b/libs/thread/test/sync/mutual_exclusion/timed_mutex/default_pass.cpp
new file mode 100644
index 0000000000..6b7c6f2b32
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/timed_mutex/default_pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// timed_mutex();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::timed_mutex m0;
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/timed_mutex/lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/timed_mutex/lock_pass.cpp
new file mode 100644
index 0000000000..cedb1eb276
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/timed_mutex/lock_pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// void lock();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::timed_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#else
+ //time_point t0 = Clock::now();
+ m.lock();
+ //time_point t1 = Clock::now();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(2500000)+ms(1000)); // within 2.5ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
+
diff --git a/libs/thread/test/sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp b/libs/thread/test/sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp
new file mode 100644
index 0000000000..b203e5d911
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// typedef pthread_timed_mutex_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+#if defined BOOST_THREAD_DEFINES_TIMED_MUTEX_NATIVE_HANDLE
+ boost::timed_mutex m;
+ boost::timed_mutex::native_handle_type h = m.native_handle();
+ BOOST_TEST(h);
+#else
+#error "Test not applicable: BOOST_THREAD_DEFINES_TIMED_MUTEX_NATIVE_HANDLE not defined for this platform as not supported"
+#endif
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp b/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp
new file mode 100644
index 0000000000..c3fa7a63c0
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::timed_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(m.try_lock_for(ms(300)+ms(2000)) == true);
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ BOOST_TEST(d < ns(5000000)+ms(2000)); // within 5ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ BOOST_TEST(m.try_lock_for(ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ boost::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp
new file mode 100644
index 0000000000..bc16df5035
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// bool try_lock();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+boost::timed_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(50000000)+ms(2000)); // within 50ms
+#else
+ //time_point t0 = Clock::now();
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ //time_point t1 = Clock::now();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ //BOOST_TEST(d < ns(50000000)+ms(1000)); // within 50ms
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(ms(250));
+#else
+#endif
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
+
diff --git a/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp b/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp
new file mode 100644
index 0000000000..d605b9c700
--- /dev/null
+++ b/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::timed_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(300) + ms(1000)) == true);
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST(d < ns(5000000)+ms(1000)); // within 5ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ boost::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(300)+ms(1000));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/libs/thread/test/test_2309.cpp b/libs/thread/test/test_2309.cpp
new file mode 100755
index 0000000000..a33c1e5021
--- /dev/null
+++ b/libs/thread/test/test_2309.cpp
@@ -0,0 +1,82 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+
+#include <iostream>
+
+#include <boost/thread.hpp>
+
+ using namespace std;
+
+ boost::mutex mutex_;
+
+ void perform()
+ {
+ try
+ {
+ boost::this_thread::sleep(boost::posix_time::seconds(100));
+ }
+ catch (boost::thread_interrupted& interrupt)
+ {
+ boost::mutex::scoped_lock lock(mutex_);
+ cerr << "Thread " << boost::this_thread::get_id() << " got interrupted" << endl;
+ throw(interrupt);
+ }
+ catch (std::exception& e)
+ {
+ boost::mutex::scoped_lock lock(mutex_);
+ cerr << "Thread " << boost::this_thread::get_id() << " caught std::exception" << e.what() << endl;
+ }
+ catch (...)
+ {
+ boost::mutex::scoped_lock lock(mutex_);
+ cerr << "Thread " << boost::this_thread::get_id() << " caught something else" << endl;
+ }
+ }
+
+ void test()
+ {
+ try
+ {
+ boost::thread_group threads;
+
+ for (int i = 0; i < 2; ++i)
+ {
+ threads.create_thread(perform);
+ }
+
+ //boost::this_thread::sleep(1);
+ threads.interrupt_all();
+ threads.join_all();
+ }
+ catch (...)
+ {
+ BOOST_CHECK(false && "exception raised");
+ }
+ }
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+ boost::unit_test_framework::test_suite* tests =
+ BOOST_TEST_SUITE("Boost.Threads: 2309");
+
+ tests->add(BOOST_TEST_CASE(&test));
+
+ return tests;
+}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_2501.cpp b/libs/thread/test/test_2501.cpp
index 5091338670..4a22637100 100644
--- a/libs/thread/test/test_2501.cpp
+++ b/libs/thread/test/test_2501.cpp
@@ -1,4 +1,5 @@
#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/locks.hpp>
int main() {
diff --git a/libs/thread/test/test_2741.cpp b/libs/thread/test/test_2741.cpp
new file mode 100644
index 0000000000..cbe3253e6e
--- /dev/null
+++ b/libs/thread/test/test_2741.cpp
@@ -0,0 +1,98 @@
+// Copyright (C) 2008 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/bind.hpp>
+#include <boost/ref.hpp>
+#include <boost/utility.hpp>
+
+#include <iostream>
+#include <boost/test/unit_test.hpp>
+
+#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
+#include <libs/thread/test/util.inl>
+
+int test_value;
+#ifdef PTHREAD_STACK_MIN
+#define MY_PTHREAD_STACK PTHREAD_STACK_MIN
+#else
+#define MY_PTHREAD_STACK 4*0x4000
+#endif
+void simple_thread()
+{
+ test_value = 999;
+}
+
+void test_native_handle()
+{
+
+ boost::thread_attributes attrs;
+
+ boost::thread_attributes::native_handle_type* h = attrs.native_handle();
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+ // ... window version
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+
+ int k = pthread_attr_setstacksize(h, MY_PTHREAD_STACK);
+ std::cout << k << std::endl;
+ BOOST_CHECK(!pthread_attr_setstacksize(h, MY_PTHREAD_STACK));
+ std::size_t res;
+ BOOST_CHECK(!pthread_attr_getstacksize(h, &res));
+ BOOST_CHECK(res >= (MY_PTHREAD_STACK));
+#else
+#error "Boost thread unavailable on this platform"
+#endif
+
+}
+
+void test_stack_size()
+{
+ boost::thread_attributes attrs;
+
+ attrs.set_stack_size(0x4000);
+ BOOST_CHECK(attrs.get_stack_size() >= 0x4000);
+
+}
+void do_test_creation_with_attrs()
+{
+ test_value = 0;
+ boost::thread_attributes attrs;
+ attrs.set_stack_size(0x4000);
+ boost::thread thrd(attrs, &simple_thread);
+ thrd.join();
+ BOOST_CHECK_EQUAL(test_value, 999);
+}
+
+void test_creation_with_attrs()
+{
+ timed_test(&do_test_creation_with_attrs, 1);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+ boost::unit_test_framework::test_suite* test = BOOST_TEST_SUITE("Boost.Threads: thread attributes test suite");
+
+ test->add(BOOST_TEST_CASE(test_native_handle));
+ test->add(BOOST_TEST_CASE(test_stack_size));
+ test->add(BOOST_TEST_CASE(test_creation_with_attrs));
+
+ return test;
+}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_4521.cpp b/libs/thread/test/test_4521.cpp
index 24e1b165ef..ae16219e80 100644
--- a/libs/thread/test/test_4521.cpp
+++ b/libs/thread/test/test_4521.cpp
@@ -7,7 +7,9 @@ int calculate_the_answer_to_life_the_universe_and_everything()
int main() {
boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
-boost::unique_future<int> fi=pt.get_future();
+
+//boost::unique_future<int> fi = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
+boost::unique_future<int> fi((BOOST_THREAD_MAKE_RV_REF(pt.get_future())));
boost::thread task(boost::move(pt)); // launch task on a thread
diff --git a/libs/thread/test/test_4648.cpp b/libs/thread/test/test_4648.cpp
index b0f95f8d14..1ece3df0cd 100644
--- a/libs/thread/test/test_4648.cpp
+++ b/libs/thread/test/test_4648.cpp
@@ -13,7 +13,7 @@ public:
boostThreadLocksTest()
:myMutex()
//, myLock(myMutex,boost::defer_lock_t())
- {};
+ {}
};
int boostThreadLocksTest::firstFunction(boostThreadLocksTest *pBoostThreadLocksTest)
@@ -25,7 +25,7 @@ int boostThreadLocksTest::firstFunction(boostThreadLocksTest *pBoostThreadLocksT
std::cout<<"Returning from "<<boost::this_thread::get_id()<<" "<<"firstFunction"<<std::endl;
return(0);
}
-int boostThreadLocksTest::secondFunction(boostThreadLocksTest *pBoostThreadLocksTest, boost::upgrade_lock<boost::shared_mutex>& upgr) {
+int boostThreadLocksTest::secondFunction(boostThreadLocksTest */*pBoostThreadLocksTest*/, boost::upgrade_lock<boost::shared_mutex>& upgr) {
std::cout<<"Before Exclusive Locking "<<boost::this_thread::get_id()<<" "<<"secondFunction"<<std::endl;
boost::upgrade_to_unique_lock<boost::shared_mutex> localUniqueLock(upgr);
std::cout<<"After Exclusive Locking "<<boost::this_thread::get_id()<<" "<<"secondFunction"<<std::endl;
diff --git a/libs/thread/test/test_4882.cpp b/libs/thread/test/test_4882.cpp
index 88dab8d9b6..2c9d031f47 100644
--- a/libs/thread/test/test_4882.cpp
+++ b/libs/thread/test/test_4882.cpp
@@ -8,7 +8,9 @@ boost::shared_mutex mutex;
void thread()
{
std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+#ifndef BOOST_NO_EXCEPTIONS
try
+#endif
{
for (int i =0; i<10; ++i)
{
@@ -23,10 +25,12 @@ void thread()
}
}
}
+#ifndef BOOST_NO_EXCEPTIONS
catch (boost::lock_error& le)
{
std::cerr << "lock_error exception\n";
}
+#endif
std::cout << __FILE__ << ":" << __LINE__ << std::endl;
}
diff --git a/libs/thread/test/test_5351.cpp b/libs/thread/test/test_5351.cpp
index 543bb34c4c..8ce10ac7d8 100644
--- a/libs/thread/test/test_5351.cpp
+++ b/libs/thread/test/test_5351.cpp
@@ -13,7 +13,7 @@ int foo()
}
-int main(int argc, char** argv)
+int main()
{
boost::packaged_task<int> pt(&foo);
boost::unique_future<int> fi = pt.get_future();
diff --git a/libs/thread/test/test_5502.cpp b/libs/thread/test/test_5502.cpp
index 3baf9bb4a5..4a29934f29 100644
--- a/libs/thread/test/test_5502.cpp
+++ b/libs/thread/test/test_5502.cpp
@@ -10,15 +10,17 @@ int YYY = 10;
#include <boost/thread.hpp>
#include <boost/thread/shared_mutex.hpp>
-#include <unistd.h>
+//#include <unistd.h>
#include <iostream>
#include <boost/detail/lightweight_test.hpp>
using namespace std;
-void sleepmillis(useconds_t miliis)
+//void sleepmillis(useconds_t miliis)
+void sleepmillis(int miliis)
{
- usleep(miliis * 1000);
+ //usleep(miliis * 1000);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(miliis));
}
void worker1(boost::shared_mutex * lk, int * x)
diff --git a/libs/thread/test/test_5542_1.cpp b/libs/thread/test/test_5542_1.cpp
index 79dfd60db6..dcd1ab9720 100644
--- a/libs/thread/test/test_5542_1.cpp
+++ b/libs/thread/test/test_5542_1.cpp
@@ -12,9 +12,9 @@ public:
void start(int N)
{
- std::cout << "start\n";
+// std::cout << "start\n";
m_Thread = boost::thread(&Worker::processQueue, this, N);
- std::cout << "started\n";
+// std::cout << "started\n";
}
void join()
@@ -27,14 +27,14 @@ public:
float ms = N * 1e3;
boost::posix_time::milliseconds workTime(ms);
- std::cout << "Worker: started, will work for "
- << ms << "ms"
- << std::endl;
+// std::cout << "Worker: started, will work for "
+// << ms << "ms"
+// << std::endl;
// We're busy, honest!
boost::this_thread::sleep(workTime);
- std::cout << "Worker: completed" << std::endl;
+// std::cout << "Worker: completed" << std::endl;
}
private:
@@ -42,21 +42,21 @@ private:
boost::thread m_Thread;
};
-int main(int argc, char* argv[])
+int main()
{
- std::cout << "main: startup" << std::endl;
+// std::cout << "main: startup" << std::endl;
Worker worker;
- std::cout << "main: create worker" << std::endl;
+// std::cout << "main: create worker" << std::endl;
worker.start(3);
- std::cout << "main: waiting for thread" << std::endl;
+// std::cout << "main: waiting for thread" << std::endl;
worker.join();
- std::cout << "main: done" << std::endl;
+// std::cout << "main: done" << std::endl;
return 0;
}
diff --git a/libs/thread/test/test_5542_3.cpp b/libs/thread/test/test_5542_3.cpp
index 0c1ac40bb2..ea80f04ccf 100644
--- a/libs/thread/test/test_5542_3.cpp
+++ b/libs/thread/test/test_5542_3.cpp
@@ -14,7 +14,7 @@ void workerFunc()
std::cout << "Worker: finished" << std::endl;
}
-int main(int argc, char* argv[])
+int main()
{
std::cout << "main: startup" << std::endl;
diff --git a/libs/thread/test/test_5891.cpp b/libs/thread/test/test_5891.cpp
new file mode 100755
index 0000000000..9a8c33440f
--- /dev/null
+++ b/libs/thread/test/test_5891.cpp
@@ -0,0 +1,33 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <boost/thread.hpp>
+
+using namespace std;
+using namespace boost;
+
+ struct X {
+ void operator()()
+ {
+ boost::this_thread::sleep(posix_time::seconds(2));
+ }
+ };
+int main()
+{
+ X run;
+ boost::thread myThread(run);
+ boost::this_thread::yield();
+ if(myThread.timed_join(posix_time::seconds(5)))
+ {
+ cout << "thats ok";
+ return 0;
+ }
+ else
+ {
+ cout << "too late";
+ return 1;
+ }
+}
diff --git a/libs/thread/test/test_6130.cpp b/libs/thread/test/test_6130.cpp
index 3ef1f18373..e77f9c3cd6 100644
--- a/libs/thread/test/test_6130.cpp
+++ b/libs/thread/test/test_6130.cpp
@@ -2,21 +2,37 @@
#include <assert.h>
#include <iostream>
#include <stdlib.h>
+#if defined(BOOST_THREAD_PLATFORM_PTHREAD)
#include <unistd.h>
+#endif
boost::mutex mtx;
boost::condition_variable cv;
+using namespace boost::posix_time;
+using namespace boost::gregorian;
int main()
{
- for (int i=0; i<3; ++i) {
- const time_t wait_time = ::time(0)+1;
+#if defined(BOOST_THREAD_PLATFORM_PTHREAD)
- boost::mutex::scoped_lock lk(mtx);
- const bool res = cv.timed_wait(lk, boost::posix_time::from_time_t(wait_time));
- const time_t end_time = ::time(0);
- assert(end_time >= wait_time);
- std::cerr << end_time - wait_time << " OK\n";
- }
- return 0;
+ for (int i=0; i<3; ++i)
+ {
+ const time_t now_time = ::time(0);
+ const time_t wait_time = now_time+1;
+ time_t end_time;
+ assert(now_time < wait_time);
+
+ boost::mutex::scoped_lock lk(mtx);
+ //const bool res =
+ (void)cv.timed_wait(lk, from_time_t(wait_time));
+ end_time = ::time(0);
+ std::cerr << "now_time =" << now_time << " \n";
+ std::cerr << "end_time =" << end_time << " \n";
+ std::cerr << "wait_time=" << wait_time << " \n";
+ std::cerr << end_time - wait_time << " \n";
+ assert(end_time >= wait_time);
+ std::cerr << " OK\n";
+ }
+#endif
+ return 0;
}
diff --git a/libs/thread/test/test_6170.cpp b/libs/thread/test/test_6170.cpp
index 6f2f28fd65..4c019074e6 100644
--- a/libs/thread/test/test_6170.cpp
+++ b/libs/thread/test/test_6170.cpp
@@ -11,16 +11,16 @@ typedef upgrade_to_unique_lock<shared_mutex> auto_upgrade_unique_lock;
void testUpgrade(void)
{
- shared_mutex mtx;
- auto_upgrade_lock lock(mtx);
- // Do some read-only stuff
+ shared_mutex mtx;
+ auto_upgrade_lock lock(mtx);
+ // Do some read-only stuff
- auto_upgrade_unique_lock writeLock(lock);
- // Do some write-only stuff with the upgraded lock
+ auto_upgrade_unique_lock writeLock(lock);
+ // Do some write-only stuff with the upgraded lock
}
int main()
{
testUpgrade();
return 0;
-} \ No newline at end of file
+}
diff --git a/libs/thread/test/test_6174.cpp b/libs/thread/test/test_6174.cpp
index b3c14ecacf..cd7ed4e764 100644
--- a/libs/thread/test/test_6174.cpp
+++ b/libs/thread/test/test_6174.cpp
@@ -1,3 +1,8 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
#include <boost/thread.hpp>
@@ -5,26 +10,32 @@
#ifndef BOOST_NO_RVALUE_REFERENCES
struct MovableButNonCopyable {
-#ifndef BOOST_NO_DEFAULTED_FUNCTIONS
- MovableButNonCopyable() = default;
+#if ! defined BOOST_NO_DELETED_FUNCTIONS
MovableButNonCopyable(MovableButNonCopyable const&) = delete;
MovableButNonCopyable& operator=(MovableButNonCopyable const&) = delete;
- MovableButNonCopyable(MovableButNonCopyable&&) = default;
- MovableButNonCopyable& operator=(MovableButNonCopyable&&) = default;
#else
- MovableButNonCopyable() {};
- MovableButNonCopyable(MovableButNonCopyable&&) {};
- MovableButNonCopyable& operator=(MovableButNonCopyable&&) {
- return *this;
- };
private:
MovableButNonCopyable(MovableButNonCopyable const&);
MovableButNonCopyable& operator=(MovableButNonCopyable const&);
#endif
+public:
+ MovableButNonCopyable() {};
+ MovableButNonCopyable(MovableButNonCopyable&&) {};
+ MovableButNonCopyable& operator=(MovableButNonCopyable&&)
+ {
+ return *this;
+ };
};
+
+MovableButNonCopyable construct()
+{
+ return MovableButNonCopyable();
+}
+
int main()
{
- boost::packaged_task<MovableButNonCopyable>(MovableButNonCopyable());
+ boost::packaged_task<MovableButNonCopyable> pt(construct);
+ pt();
return 0;
}
#else
diff --git a/libs/thread/test/test_barrier.cpp b/libs/thread/test/test_barrier.cpp
index cd350ba2f7..b9d5fdf13c 100644
--- a/libs/thread/test/test_barrier.cpp
+++ b/libs/thread/test/test_barrier.cpp
@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
@@ -51,7 +51,7 @@ void test_barrier()
g.join_all();
throw;
}
-
+
BOOST_CHECK_EQUAL(global_parameter,5);
}
@@ -64,3 +64,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_condition.cpp b/libs/thread/test/test_condition.cpp
index f33b7a2bd7..209c72e09a 100644
--- a/libs/thread/test/test_condition.cpp
+++ b/libs/thread/test/test_condition.cpp
@@ -2,7 +2,7 @@
// William E. Kempf
// Copyright (C) 2007 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
@@ -45,7 +45,7 @@ struct cond_predicate
int _val;
private:
void operator=(cond_predicate&);
-
+
};
void condition_test_waits(condition_test_data* data)
@@ -188,3 +188,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_condition_notify_all.cpp b/libs/thread/test/test_condition_notify_all.cpp
index 83165c999b..aaae066af3 100644
--- a/libs/thread/test/test_condition_notify_all.cpp
+++ b/libs/thread/test/test_condition_notify_all.cpp
@@ -1,6 +1,6 @@
// Copyright (C) 2007 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
@@ -10,7 +10,7 @@
#include <boost/test/unit_test.hpp>
#include <libs/thread/test/util.inl>
-#include "condition_test_common.hpp"
+#include <libs/thread/test/condition_test_common.hpp>
unsigned const number_of_test_threads=5;
@@ -171,7 +171,7 @@ namespace
multiple_wake_cond.wait(lk);
++multiple_wake_count;
}
-
+
}
@@ -189,7 +189,7 @@ void do_test_notify_all_following_notify_one_wakes_all_threads()
multiple_wake_cond.notify_one();
multiple_wake_cond.notify_all();
boost::this_thread::sleep(boost::posix_time::milliseconds(200));
-
+
{
boost::mutex::scoped_lock lk(multiple_wake_mutex);
BOOST_CHECK(multiple_wake_count==3);
@@ -220,3 +220,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_condition_notify_one.cpp b/libs/thread/test/test_condition_notify_one.cpp
index 1e489da60c..fbee012c4c 100644
--- a/libs/thread/test/test_condition_notify_one.cpp
+++ b/libs/thread/test/test_condition_notify_one.cpp
@@ -1,6 +1,6 @@
// Copyright (C) 2007 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
@@ -10,12 +10,12 @@
#include <boost/test/unit_test.hpp>
#include <libs/thread/test/util.inl>
-#include "condition_test_common.hpp"
+#include <libs/thread/test/condition_test_common.hpp>
void do_test_condition_notify_one_wakes_from_wait()
{
wait_for_flag data;
-
+
boost::thread thread(bind(&wait_for_flag::wait_without_predicate, data));
{
@@ -31,7 +31,7 @@ void do_test_condition_notify_one_wakes_from_wait()
void do_test_condition_notify_one_wakes_from_wait_with_predicate()
{
wait_for_flag data;
-
+
boost::thread thread(bind(&wait_for_flag::wait_with_predicate, data));
{
@@ -47,7 +47,7 @@ void do_test_condition_notify_one_wakes_from_wait_with_predicate()
void do_test_condition_notify_one_wakes_from_timed_wait()
{
wait_for_flag data;
-
+
boost::thread thread(bind(&wait_for_flag::timed_wait_without_predicate, data));
{
@@ -63,7 +63,7 @@ void do_test_condition_notify_one_wakes_from_timed_wait()
void do_test_condition_notify_one_wakes_from_timed_wait_with_predicate()
{
wait_for_flag data;
-
+
boost::thread thread(bind(&wait_for_flag::timed_wait_with_predicate, data));
{
@@ -79,7 +79,7 @@ void do_test_condition_notify_one_wakes_from_timed_wait_with_predicate()
void do_test_condition_notify_one_wakes_from_relative_timed_wait_with_predicate()
{
wait_for_flag data;
-
+
boost::thread thread(bind(&wait_for_flag::relative_timed_wait_with_predicate, data));
{
@@ -104,7 +104,7 @@ namespace
multiple_wake_cond.wait(lk);
++multiple_wake_count;
}
-
+
}
@@ -122,7 +122,7 @@ void do_test_multiple_notify_one_calls_wakes_multiple_threads()
multiple_wake_cond.notify_one();
multiple_wake_cond.notify_one();
boost::this_thread::sleep(boost::posix_time::milliseconds(200));
-
+
{
boost::mutex::scoped_lock lk(multiple_wake_mutex);
BOOST_CHECK(multiple_wake_count==3);
@@ -153,3 +153,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_condition_timed_wait_times_out.cpp b/libs/thread/test/test_condition_timed_wait_times_out.cpp
index c731b5b68d..03391410e1 100644
--- a/libs/thread/test/test_condition_timed_wait_times_out.cpp
+++ b/libs/thread/test/test_condition_timed_wait_times_out.cpp
@@ -1,6 +1,6 @@
// Copyright (C) 2007-8 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
@@ -9,7 +9,7 @@
#include <boost/thread/thread.hpp>
#include <boost/test/unit_test.hpp>
-#include "util.inl"
+#include <libs/thread/test/util.inl>
bool fake_predicate()
{
@@ -31,7 +31,7 @@ void do_test_timed_wait_times_out()
boost::system_time const start=boost::get_system_time();
boost::system_time const timeout=start+delay;
- while(cond.timed_wait(lock,timeout));
+ while(cond.timed_wait(lock,timeout)) {}
boost::system_time const end=boost::get_system_time();
BOOST_CHECK((delay-timeout_resolution)<=(end-start));
@@ -79,7 +79,7 @@ void do_test_timed_wait_relative_times_out()
boost::mutex::scoped_lock lock(m);
boost::system_time const start=boost::get_system_time();
- while(cond.timed_wait(lock,delay));
+ while(cond.timed_wait(lock,delay)) {}
boost::system_time const end=boost::get_system_time();
BOOST_CHECK((delay-timeout_resolution)<=(end-start));
@@ -95,7 +95,7 @@ void do_test_cv_any_timed_wait_times_out()
boost::system_time const start=boost::get_system_time();
boost::system_time const timeout=start+delay;
- while(cond.timed_wait(lock,timeout));
+ while(cond.timed_wait(lock,timeout)) {}
boost::system_time const end=boost::get_system_time();
BOOST_CHECK((delay-timeout_resolution)<=(end-start));
@@ -143,7 +143,7 @@ void do_test_cv_any_timed_wait_relative_times_out()
boost::mutex::scoped_lock lock(m);
boost::system_time const start=boost::get_system_time();
- while(cond.timed_wait(lock,delay));
+ while(cond.timed_wait(lock,delay)) {}
boost::system_time const end=boost::get_system_time();
BOOST_CHECK((delay-timeout_resolution)<=(end-start));
@@ -171,3 +171,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_futures.cpp b/libs/thread/test/test_futures.cpp
index 4d89e5a9fa..68a03f5320 100644
--- a/libs/thread/test/test_futures.cpp
+++ b/libs/thread/test/test_futures.cpp
@@ -1,19 +1,23 @@
-// (C) Copyright 2008-10 Anthony Williams
+// (C) Copyright 2008-10 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#include "boost/thread/thread.hpp"
-#include "boost/thread/mutex.hpp"
-#include "boost/thread/condition.hpp"
-#include "boost/thread/future.hpp"
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/future.hpp>
#include <utility>
#include <memory>
#include <string>
+#include <iostream>
#include <boost/test/unit_test.hpp>
+#define LOG \
+ if (false) {} else std::cout << std::endl << __FILE__ << "[" << __LINE__ << "]"
+
#ifndef BOOST_NO_RVALUE_REFERENCES
template<typename T>
typename boost::remove_reference<T>::type&& cast_to_rval(T&& t)
@@ -21,43 +25,35 @@
return static_cast<typename boost::remove_reference<T>::type&&>(t);
}
#else
+#if defined BOOST_THREAD_USES_MOVE
+ template<typename T>
+ boost::rv<T>& cast_to_rval(T& t)
+ {
+ return boost::move(t);
+ }
+#else
template<typename T>
boost::detail::thread_move_t<T> cast_to_rval(T& t)
{
return boost::move(t);
}
#endif
+#endif
struct X
{
-private:
-
- X(X& other);
-
public:
-
int i;
-
+
+ BOOST_THREAD_MOVABLE_ONLY(X)
X():
i(42)
{}
-#ifndef BOOST_NO_RVALUE_REFERENCES
- X(X&& other):
- i(other.i)
- {
- other.i=0;
- }
-#else
- X(boost::detail::thread_move_t<X> other):
- i(other->i)
- {
- other->i=0;
- }
- operator boost::detail::thread_move_t<X>()
+ X(BOOST_THREAD_RV_REF(X) other):
+ i(BOOST_THREAD_RV(other).i)
{
- return boost::detail::thread_move_t<X>(*this);
+ BOOST_THREAD_RV(other).i=0;
}
-#endif
~X()
{}
};
@@ -88,22 +84,39 @@ void set_promise_exception_thread(boost::promise<int>* p)
void test_store_value_from_thread()
{
+ LOG;
+ try {
boost::promise<int> pi2;
- boost::unique_future<int> fi2(pi2.get_future());
+ LOG;
+ boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi2.get_future()));
+ LOG;
boost::thread(set_promise_thread,&pi2);
+ LOG;
int j=fi2.get();
+ LOG;
BOOST_CHECK(j==42);
+ LOG;
BOOST_CHECK(fi2.is_ready());
+ LOG;
BOOST_CHECK(fi2.has_value());
+ LOG;
BOOST_CHECK(!fi2.has_exception());
+ LOG;
BOOST_CHECK(fi2.get_state()==boost::future_state::ready);
+ LOG;
+ }
+ catch (...)
+ {
+ BOOST_CHECK(false&&"Exception thrown");
+ }
}
void test_store_exception()
{
+ LOG;
boost::promise<int> pi3;
- boost::unique_future<int> fi3=pi3.get_future();
+ boost::unique_future<int> fi3(BOOST_THREAD_MAKE_RV_REF(pi3.get_future()));
boost::thread(set_promise_exception_thread,&pi3);
try
{
@@ -114,7 +127,7 @@ void test_store_exception()
{
BOOST_CHECK(true);
}
-
+
BOOST_CHECK(fi3.is_ready());
BOOST_CHECK(!fi3.has_value());
BOOST_CHECK(fi3.has_exception());
@@ -123,6 +136,7 @@ void test_store_exception()
void test_initial_state()
{
+ LOG;
boost::unique_future<int> fi;
BOOST_CHECK(!fi.is_ready());
BOOST_CHECK(!fi.has_value());
@@ -132,6 +146,7 @@ void test_initial_state()
try
{
i=fi.get();
+ (void)i;
BOOST_CHECK(false);
}
catch(boost::future_uninitialized)
@@ -142,9 +157,10 @@ void test_initial_state()
void test_waiting_future()
{
+ LOG;
boost::promise<int> pi;
boost::unique_future<int> fi;
- fi=pi.get_future();
+ fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
int i=0;
BOOST_CHECK(!fi.is_ready());
@@ -156,8 +172,9 @@ void test_waiting_future()
void test_cannot_get_future_twice()
{
+ LOG;
boost::promise<int> pi;
- pi.get_future();
+ BOOST_THREAD_MAKE_RV_REF(pi.get_future());
try
{
@@ -172,12 +189,13 @@ void test_cannot_get_future_twice()
void test_set_value_updates_future_state()
{
+ LOG;
boost::promise<int> pi;
boost::unique_future<int> fi;
- fi=pi.get_future();
+ fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
pi.set_value(42);
-
+
BOOST_CHECK(fi.is_ready());
BOOST_CHECK(fi.has_value());
BOOST_CHECK(!fi.has_exception());
@@ -186,12 +204,13 @@ void test_set_value_updates_future_state()
void test_set_value_can_be_retrieved()
{
+ LOG;
boost::promise<int> pi;
boost::unique_future<int> fi;
- fi=pi.get_future();
+ fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
pi.set_value(42);
-
+
int i=0;
BOOST_CHECK(i=fi.get());
BOOST_CHECK(i==42);
@@ -203,12 +222,13 @@ void test_set_value_can_be_retrieved()
void test_set_value_can_be_moved()
{
+ LOG;
// boost::promise<int> pi;
// boost::unique_future<int> fi;
-// fi=pi.get_future();
+// fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
// pi.set_value(42);
-
+
// int i=0;
// BOOST_CHECK(i=fi.get());
// BOOST_CHECK(i==42);
@@ -220,8 +240,9 @@ void test_set_value_can_be_moved()
void test_future_from_packaged_task_is_waiting()
{
+ LOG;
boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi=pt.get_future();
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
int i=0;
BOOST_CHECK(!fi.is_ready());
BOOST_CHECK(!fi.has_value());
@@ -232,8 +253,9 @@ void test_future_from_packaged_task_is_waiting()
void test_invoking_a_packaged_task_populates_future()
{
+ LOG;
boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi=pt.get_future();
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
pt();
@@ -248,6 +270,7 @@ void test_invoking_a_packaged_task_populates_future()
void test_invoking_a_packaged_task_twice_throws()
{
+ LOG;
boost::packaged_task<int> pt(make_int);
pt();
@@ -265,6 +288,7 @@ void test_invoking_a_packaged_task_twice_throws()
void test_cannot_get_future_twice_from_task()
{
+ LOG;
boost::packaged_task<int> pt(make_int);
pt.get_future();
try
@@ -280,8 +304,9 @@ void test_cannot_get_future_twice_from_task()
void test_task_stores_exception_if_function_throws()
{
+ LOG;
boost::packaged_task<int> pt(throw_runtime_error);
- boost::unique_future<int> fi=pt.get_future();
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
pt();
@@ -302,13 +327,14 @@ void test_task_stores_exception_if_function_throws()
{
BOOST_CHECK(!"Unknown exception thrown");
}
-
+
}
void test_void_promise()
{
+ LOG;
boost::promise<void> p;
- boost::unique_future<void> f=p.get_future();
+ boost::unique_future<void> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
p.set_value();
BOOST_CHECK(f.is_ready());
BOOST_CHECK(f.has_value());
@@ -319,8 +345,9 @@ void test_void_promise()
void test_reference_promise()
{
+ LOG;
boost::promise<int&> p;
- boost::unique_future<int&> f=p.get_future();
+ boost::unique_future<int&> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
int i=42;
p.set_value(i);
BOOST_CHECK(f.is_ready());
@@ -335,8 +362,9 @@ void do_nothing()
void test_task_returning_void()
{
+ LOG;
boost::packaged_task<void> pt(do_nothing);
- boost::unique_future<void> fi=pt.get_future();
+ boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
pt();
@@ -355,8 +383,9 @@ int& return_ref()
void test_task_returning_reference()
{
+ LOG;
boost::packaged_task<int&> pt(return_ref);
- boost::unique_future<int&> fi=pt.get_future();
+ boost::unique_future<int&> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
pt();
@@ -370,6 +399,7 @@ void test_task_returning_reference()
void test_shared_future()
{
+ LOG;
boost::packaged_task<int> pt(make_int);
boost::unique_future<int> fi=pt.get_future();
@@ -389,8 +419,9 @@ void test_shared_future()
void test_copies_of_shared_future_become_ready_together()
{
+ LOG;
boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi=pt.get_future();
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::shared_future<int> sf(::cast_to_rval(fi));
boost::shared_future<int> sf2(sf);
@@ -427,8 +458,9 @@ void test_copies_of_shared_future_become_ready_together()
void test_shared_future_can_be_move_assigned_from_unique_future()
{
+ LOG;
boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi=pt.get_future();
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::shared_future<int> sf;
sf=::cast_to_rval(fi);
@@ -442,8 +474,9 @@ void test_shared_future_can_be_move_assigned_from_unique_future()
void test_shared_future_void()
{
+ LOG;
boost::packaged_task<void> pt(do_nothing);
- boost::unique_future<void> fi=pt.get_future();
+ boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::shared_future<void> sf(::cast_to_rval(fi));
BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
@@ -459,8 +492,9 @@ void test_shared_future_void()
void test_shared_future_ref()
{
+ LOG;
boost::promise<int&> p;
- boost::shared_future<int&> f(p.get_future());
+ boost::shared_future<int&> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
int i=42;
p.set_value(i);
BOOST_CHECK(f.is_ready());
@@ -472,11 +506,12 @@ void test_shared_future_ref()
void test_can_get_a_second_future_from_a_moved_promise()
{
+ LOG;
boost::promise<int> pi;
- boost::unique_future<int> fi=pi.get_future();
-
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
+
boost::promise<int> pi2(::cast_to_rval(pi));
- boost::unique_future<int> fi2=pi.get_future();
+ boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
pi2.set_value(3);
BOOST_CHECK(fi.is_ready());
@@ -489,11 +524,12 @@ void test_can_get_a_second_future_from_a_moved_promise()
void test_can_get_a_second_future_from_a_moved_void_promise()
{
+ LOG;
boost::promise<void> pi;
- boost::unique_future<void> fi=pi.get_future();
-
+ boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
+
boost::promise<void> pi2(::cast_to_rval(pi));
- boost::unique_future<void> fi2=pi.get_future();
+ boost::unique_future<void> fi2(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
pi2.set_value();
BOOST_CHECK(fi.is_ready());
@@ -504,8 +540,9 @@ void test_can_get_a_second_future_from_a_moved_void_promise()
void test_unique_future_for_move_only_udt()
{
+ LOG;
boost::promise<X> pt;
- boost::unique_future<X> fi=pt.get_future();
+ boost::unique_future<X> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
pt.set_value(X());
X res(fi.get());
@@ -514,27 +551,28 @@ void test_unique_future_for_move_only_udt()
void test_unique_future_for_string()
{
+ LOG;
boost::promise<std::string> pt;
- boost::unique_future<std::string> fi=pt.get_future();
+ boost::unique_future<std::string> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
pt.set_value(std::string("hello"));
std::string res(fi.get());
BOOST_CHECK(res=="hello");
boost::promise<std::string> pt2;
- fi=pt2.get_future();
+ fi=BOOST_THREAD_MAKE_RV_REF(pt2.get_future());
std::string const s="goodbye";
-
+
pt2.set_value(s);
res=fi.get();
BOOST_CHECK(res=="goodbye");
boost::promise<std::string> pt3;
- fi=pt3.get_future();
+ fi=BOOST_THREAD_MAKE_RV_REF(pt3.get_future());
std::string s2="foo";
-
+
pt3.set_value(s2);
res=fi.get();
BOOST_CHECK(res=="foo");
@@ -564,9 +602,10 @@ void do_nothing_callback(boost::promise<int>& /*pi*/)
void test_wait_callback()
{
+ LOG;
callback_called=0;
boost::promise<int> pi;
- boost::unique_future<int> fi=pi.get_future();
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
pi.set_wait_callback(wait_callback);
fi.wait();
BOOST_CHECK(callback_called);
@@ -578,9 +617,10 @@ void test_wait_callback()
void test_wait_callback_with_timed_wait()
{
+ LOG;
callback_called=0;
boost::promise<int> pi;
- boost::unique_future<int> fi=pi.get_future();
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
pi.set_wait_callback(do_nothing_callback);
bool success=fi.timed_wait(boost::posix_time::milliseconds(10));
BOOST_CHECK(callback_called);
@@ -601,6 +641,7 @@ void test_wait_callback_with_timed_wait()
void wait_callback_for_task(boost::packaged_task<int>& pt)
{
+ LOG;
boost::lock_guard<boost::mutex> lk(callback_mutex);
++callback_called;
try
@@ -615,9 +656,10 @@ void wait_callback_for_task(boost::packaged_task<int>& pt)
void test_wait_callback_for_packaged_task()
{
+ LOG;
callback_called=0;
boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi=pt.get_future();
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
pt.set_wait_callback(wait_callback_for_task);
fi.wait();
BOOST_CHECK(callback_called);
@@ -629,12 +671,13 @@ void test_wait_callback_for_packaged_task()
void test_packaged_task_can_be_moved()
{
+ LOG;
boost::packaged_task<int> pt(make_int);
- boost::unique_future<int> fi=pt.get_future();
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
BOOST_CHECK(!fi.is_ready());
-
+
boost::packaged_task<int> pt2(::cast_to_rval(pt));
BOOST_CHECK(!fi.is_ready());
@@ -650,17 +693,18 @@ void test_packaged_task_can_be_moved()
BOOST_CHECK(!fi.is_ready());
pt2();
-
+
BOOST_CHECK(fi.is_ready());
}
void test_destroying_a_promise_stores_broken_promise()
{
+ LOG;
boost::unique_future<int> f;
-
+
{
boost::promise<int> p;
- f=p.get_future();
+ f=BOOST_THREAD_MAKE_RV_REF(p.get_future());
}
BOOST_CHECK(f.is_ready());
BOOST_CHECK(f.has_exception());
@@ -675,11 +719,12 @@ void test_destroying_a_promise_stores_broken_promise()
void test_destroying_a_packaged_task_stores_broken_promise()
{
+ LOG;
boost::unique_future<int> f;
-
+
{
boost::packaged_task<int> p(make_int);
- f=p.get_future();
+ f=BOOST_THREAD_MAKE_RV_REF(p.get_future());
}
BOOST_CHECK(f.is_ready());
BOOST_CHECK(f.has_exception());
@@ -700,15 +745,16 @@ int make_int_slowly()
void test_wait_for_either_of_two_futures_1()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
-
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+
boost::thread(::cast_to_rval(pt));
-
+
unsigned const future=boost::wait_for_any(f1,f2);
-
+
BOOST_CHECK(future==0);
BOOST_CHECK(f1.is_ready());
BOOST_CHECK(!f2.is_ready());
@@ -717,15 +763,16 @@ void test_wait_for_either_of_two_futures_1()
void test_wait_for_either_of_two_futures_2()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
-
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+
boost::thread(::cast_to_rval(pt2));
-
+
unsigned const future=boost::wait_for_any(f1,f2);
-
+
BOOST_CHECK(future==1);
BOOST_CHECK(!f1.is_ready());
BOOST_CHECK(f2.is_ready());
@@ -734,17 +781,18 @@ void test_wait_for_either_of_two_futures_2()
void test_wait_for_either_of_three_futures_1()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(pt3.get_future());
-
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+
boost::thread(::cast_to_rval(pt));
-
+
unsigned const future=boost::wait_for_any(f1,f2,f3);
-
+
BOOST_CHECK(future==0);
BOOST_CHECK(f1.is_ready());
BOOST_CHECK(!f2.is_ready());
@@ -754,17 +802,18 @@ void test_wait_for_either_of_three_futures_1()
void test_wait_for_either_of_three_futures_2()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(pt3.get_future());
-
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+
boost::thread(::cast_to_rval(pt2));
-
+
unsigned const future=boost::wait_for_any(f1,f2,f3);
-
+
BOOST_CHECK(future==1);
BOOST_CHECK(!f1.is_ready());
BOOST_CHECK(f2.is_ready());
@@ -774,17 +823,18 @@ void test_wait_for_either_of_three_futures_2()
void test_wait_for_either_of_three_futures_3()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(pt3.get_future());
-
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+
boost::thread(::cast_to_rval(pt3));
-
+
unsigned const future=boost::wait_for_any(f1,f2,f3);
-
+
BOOST_CHECK(future==2);
BOOST_CHECK(!f1.is_ready());
BOOST_CHECK(!f2.is_ready());
@@ -794,19 +844,20 @@ void test_wait_for_either_of_three_futures_3()
void test_wait_for_either_of_four_futures_1()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(pt3.get_future());
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(pt4.get_future());
-
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+
boost::thread(::cast_to_rval(pt));
-
+
unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
-
+
BOOST_CHECK(future==0);
BOOST_CHECK(f1.is_ready());
BOOST_CHECK(!f2.is_ready());
@@ -817,19 +868,20 @@ void test_wait_for_either_of_four_futures_1()
void test_wait_for_either_of_four_futures_2()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(pt3.get_future());
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(pt4.get_future());
-
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+
boost::thread(::cast_to_rval(pt2));
-
+
unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
-
+
BOOST_CHECK(future==1);
BOOST_CHECK(!f1.is_ready());
BOOST_CHECK(f2.is_ready());
@@ -840,19 +892,20 @@ void test_wait_for_either_of_four_futures_2()
void test_wait_for_either_of_four_futures_3()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(pt3.get_future());
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(pt4.get_future());
-
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+
boost::thread(::cast_to_rval(pt3));
-
+
unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
-
+
BOOST_CHECK(future==2);
BOOST_CHECK(!f1.is_ready());
BOOST_CHECK(!f2.is_ready());
@@ -863,19 +916,20 @@ void test_wait_for_either_of_four_futures_3()
void test_wait_for_either_of_four_futures_4()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(pt3.get_future());
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(pt4.get_future());
-
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+
boost::thread(::cast_to_rval(pt4));
-
+
unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
-
+
BOOST_CHECK(future==3);
BOOST_CHECK(!f1.is_ready());
BOOST_CHECK(!f2.is_ready());
@@ -886,21 +940,22 @@ void test_wait_for_either_of_four_futures_4()
void test_wait_for_either_of_five_futures_1()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(pt3.get_future());
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(pt4.get_future());
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
boost::packaged_task<int> pt5(make_int_slowly);
- boost::unique_future<int> f5(pt5.get_future());
-
+ boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
+
boost::thread(::cast_to_rval(pt));
-
+
unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
-
+
BOOST_CHECK(future==0);
BOOST_CHECK(f1.is_ready());
BOOST_CHECK(!f2.is_ready());
@@ -912,21 +967,22 @@ void test_wait_for_either_of_five_futures_1()
void test_wait_for_either_of_five_futures_2()
{
- boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(pt3.get_future());
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(pt4.get_future());
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
boost::packaged_task<int> pt5(make_int_slowly);
- boost::unique_future<int> f5(pt5.get_future());
-
+ boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
+
boost::thread(::cast_to_rval(pt2));
-
+
unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
-
+
BOOST_CHECK(future==1);
BOOST_CHECK(!f1.is_ready());
BOOST_CHECK(f2.is_ready());
@@ -937,21 +993,22 @@ void test_wait_for_either_of_five_futures_2()
}
void test_wait_for_either_of_five_futures_3()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(pt3.get_future());
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(pt4.get_future());
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
boost::packaged_task<int> pt5(make_int_slowly);
- boost::unique_future<int> f5(pt5.get_future());
-
+ boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
+
boost::thread(::cast_to_rval(pt3));
-
+
unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
-
+
BOOST_CHECK(future==2);
BOOST_CHECK(!f1.is_ready());
BOOST_CHECK(!f2.is_ready());
@@ -962,21 +1019,22 @@ void test_wait_for_either_of_five_futures_3()
}
void test_wait_for_either_of_five_futures_4()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(pt3.get_future());
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(pt4.get_future());
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
boost::packaged_task<int> pt5(make_int_slowly);
- boost::unique_future<int> f5(pt5.get_future());
-
+ boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
+
boost::thread(::cast_to_rval(pt4));
-
+
unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
-
+
BOOST_CHECK(future==3);
BOOST_CHECK(!f1.is_ready());
BOOST_CHECK(!f2.is_ready());
@@ -987,21 +1045,22 @@ void test_wait_for_either_of_five_futures_4()
}
void test_wait_for_either_of_five_futures_5()
{
+ LOG;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> f1(pt.get_future());
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> f2(pt2.get_future());
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
boost::packaged_task<int> pt3(make_int_slowly);
- boost::unique_future<int> f3(pt3.get_future());
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
boost::packaged_task<int> pt4(make_int_slowly);
- boost::unique_future<int> f4(pt4.get_future());
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
boost::packaged_task<int> pt5(make_int_slowly);
- boost::unique_future<int> f5(pt5.get_future());
-
+ boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
+
boost::thread(::cast_to_rval(pt5));
-
+
unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
-
+
BOOST_CHECK(future==4);
BOOST_CHECK(!f1.is_ready());
BOOST_CHECK(!f2.is_ready());
@@ -1013,15 +1072,16 @@ void test_wait_for_either_of_five_futures_5()
void test_wait_for_either_invokes_callbacks()
{
+ LOG;
callback_called=0;
boost::packaged_task<int> pt(make_int_slowly);
- boost::unique_future<int> fi=pt.get_future();
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
boost::packaged_task<int> pt2(make_int_slowly);
- boost::unique_future<int> fi2=pt2.get_future();
+ boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
pt.set_wait_callback(wait_callback_for_task);
boost::thread(::cast_to_rval(pt));
-
+
boost::wait_for_any(fi,fi2);
BOOST_CHECK(callback_called==1);
BOOST_CHECK(fi.get()==42);
@@ -1029,6 +1089,7 @@ void test_wait_for_either_invokes_callbacks()
void test_wait_for_any_from_range()
{
+ LOG;
unsigned const count=10;
for(unsigned i=0;i<count;++i)
{
@@ -1037,14 +1098,14 @@ void test_wait_for_any_from_range()
for(unsigned j=0;j<count;++j)
{
tasks[j]=boost::packaged_task<int>(make_int_slowly);
- futures[j]=tasks[j].get_future();
+ futures[j]=BOOST_THREAD_MAKE_RV_REF(tasks[j].get_future());
}
boost::thread(::cast_to_rval(tasks[i]));
-
+
BOOST_CHECK(boost::wait_for_any(futures,futures)==futures);
-
+
boost::unique_future<int>* const future=boost::wait_for_any(futures,futures+count);
-
+
BOOST_CHECK(future==(futures+i));
for(unsigned j=0;j<count;++j)
{
@@ -1063,17 +1124,18 @@ void test_wait_for_any_from_range()
void test_wait_for_all_from_range()
{
+ LOG;
unsigned const count=10;
boost::unique_future<int> futures[count];
for(unsigned j=0;j<count;++j)
{
boost::packaged_task<int> task(make_int_slowly);
- futures[j]=task.get_future();
+ futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
boost::thread(::cast_to_rval(task));
}
-
+
boost::wait_for_all(futures,futures+count);
-
+
for(unsigned j=0;j<count;++j)
{
BOOST_CHECK(futures[j].is_ready());
@@ -1082,17 +1144,18 @@ void test_wait_for_all_from_range()
void test_wait_for_all_two_futures()
{
+ LOG;
unsigned const count=2;
boost::unique_future<int> futures[count];
for(unsigned j=0;j<count;++j)
{
boost::packaged_task<int> task(make_int_slowly);
- futures[j]=task.get_future();
+ futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
boost::thread(::cast_to_rval(task));
}
-
+
boost::wait_for_all(futures[0],futures[1]);
-
+
for(unsigned j=0;j<count;++j)
{
BOOST_CHECK(futures[j].is_ready());
@@ -1101,17 +1164,18 @@ void test_wait_for_all_two_futures()
void test_wait_for_all_three_futures()
{
+ LOG;
unsigned const count=3;
boost::unique_future<int> futures[count];
for(unsigned j=0;j<count;++j)
{
boost::packaged_task<int> task(make_int_slowly);
- futures[j]=task.get_future();
+ futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
boost::thread(::cast_to_rval(task));
}
-
+
boost::wait_for_all(futures[0],futures[1],futures[2]);
-
+
for(unsigned j=0;j<count;++j)
{
BOOST_CHECK(futures[j].is_ready());
@@ -1120,17 +1184,18 @@ void test_wait_for_all_three_futures()
void test_wait_for_all_four_futures()
{
+ LOG;
unsigned const count=4;
boost::unique_future<int> futures[count];
for(unsigned j=0;j<count;++j)
{
boost::packaged_task<int> task(make_int_slowly);
- futures[j]=task.get_future();
+ futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
boost::thread(::cast_to_rval(task));
}
-
+
boost::wait_for_all(futures[0],futures[1],futures[2],futures[3]);
-
+
for(unsigned j=0;j<count;++j)
{
BOOST_CHECK(futures[j].is_ready());
@@ -1139,17 +1204,18 @@ void test_wait_for_all_four_futures()
void test_wait_for_all_five_futures()
{
+ LOG;
unsigned const count=5;
boost::unique_future<int> futures[count];
for(unsigned j=0;j<count;++j)
{
boost::packaged_task<int> task(make_int_slowly);
- futures[j]=task.get_future();
+ futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
boost::thread(::cast_to_rval(task));
}
-
+
boost::wait_for_all(futures[0],futures[1],futures[2],futures[3],futures[4]);
-
+
for(unsigned j=0;j<count;++j)
{
BOOST_CHECK(futures[j].is_ready());
@@ -1218,3 +1284,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_generic_locks.cpp b/libs/thread/test/test_generic_locks.cpp
index 8e66fad459..f175979aeb 100644
--- a/libs/thread/test/test_generic_locks.cpp
+++ b/libs/thread/test/test_generic_locks.cpp
@@ -18,9 +18,9 @@ void test_lock_two_uncontended()
BOOST_CHECK(!l1.owns_lock());
BOOST_CHECK(!l2.owns_lock());
-
+
boost::lock(l1,l2);
-
+
BOOST_CHECK(l1.owns_lock());
BOOST_CHECK(l2.owns_lock());
}
@@ -30,11 +30,11 @@ struct wait_data
boost::mutex m;
bool flag;
boost::condition_variable cond;
-
+
wait_data():
flag(false)
{}
-
+
void wait()
{
boost::mutex::scoped_lock l(m);
@@ -48,7 +48,7 @@ struct wait_data
bool timed_wait(Duration d)
{
boost::system_time const target=boost::get_system_time()+d;
-
+
boost::mutex::scoped_lock l(m);
while(!flag)
{
@@ -59,7 +59,7 @@ struct wait_data
}
return true;
}
-
+
void signal()
{
boost::mutex::scoped_lock l(m);
@@ -67,7 +67,7 @@ struct wait_data
cond.notify_all();
}
};
-
+
void lock_mutexes_slowly(boost::mutex* m1,boost::mutex* m2,wait_data* locked,wait_data* quit)
{
@@ -90,7 +90,7 @@ void test_lock_two_other_thread_locks_in_order()
boost::mutex m1,m2;
wait_data locked;
wait_data release;
-
+
boost::thread t(lock_mutexes_slowly,&m1,&m2,&locked,&release);
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
@@ -98,7 +98,7 @@ void test_lock_two_other_thread_locks_in_order()
BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(1)));
release.signal();
-
+
BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(1)));
t.join();
@@ -109,7 +109,7 @@ void test_lock_two_other_thread_locks_in_opposite_order()
boost::mutex m1,m2;
wait_data locked;
wait_data release;
-
+
boost::thread t(lock_mutexes_slowly,&m1,&m2,&locked,&release);
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
@@ -117,7 +117,7 @@ void test_lock_two_other_thread_locks_in_opposite_order()
BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(1)));
release.signal();
-
+
BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(1)));
t.join();
@@ -138,9 +138,9 @@ void test_lock_five_uncontended()
BOOST_CHECK(!l3.owns_lock());
BOOST_CHECK(!l4.owns_lock());
BOOST_CHECK(!l5.owns_lock());
-
+
boost::lock(l1,l2,l3,l4,l5);
-
+
BOOST_CHECK(l1.owns_lock());
BOOST_CHECK(l2.owns_lock());
BOOST_CHECK(l3.owns_lock());
@@ -179,7 +179,7 @@ void test_lock_five_other_thread_locks_in_order()
boost::mutex m1,m2,m3,m4,m5;
wait_data locked;
wait_data release;
-
+
boost::thread t(lock_five_mutexes_slowly,&m1,&m2,&m3,&m4,&m5,&locked,&release);
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
@@ -187,7 +187,7 @@ void test_lock_five_other_thread_locks_in_order()
BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(3)));
release.signal();
-
+
BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(3)));
t.join();
@@ -198,7 +198,7 @@ void test_lock_five_other_thread_locks_in_different_order()
boost::mutex m1,m2,m3,m4,m5;
wait_data locked;
wait_data release;
-
+
boost::thread t(lock_five_mutexes_slowly,&m1,&m2,&m3,&m4,&m5,&locked,&release);
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
@@ -206,7 +206,7 @@ void test_lock_five_other_thread_locks_in_different_order()
BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(3)));
release.signal();
-
+
BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(3)));
t.join();
@@ -225,11 +225,11 @@ void lock_n(boost::mutex* mutexes,unsigned count)
void test_lock_ten_other_thread_locks_in_different_order()
{
unsigned const num_mutexes=10;
-
+
boost::mutex mutexes[num_mutexes];
wait_data locked;
wait_data release;
-
+
boost::thread t(lock_five_mutexes_slowly,&mutexes[6],&mutexes[3],&mutexes[8],&mutexes[0],&mutexes[2],&locked,&release);
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
@@ -246,16 +246,16 @@ void test_lock_ten_other_thread_locks_in_different_order()
struct dummy_mutex
{
bool is_locked;
-
+
dummy_mutex():
is_locked(false)
{}
-
+
void lock()
{
is_locked=true;
}
-
+
bool try_lock()
{
if(is_locked)
@@ -265,7 +265,7 @@ struct dummy_mutex
is_locked=true;
return true;
}
-
+
void unlock()
{
is_locked=false;
@@ -289,7 +289,7 @@ void test_lock_five_in_range()
dummy_mutex mutexes[num_mutexes];
boost::lock(mutexes,mutexes+num_mutexes);
-
+
for(unsigned i=0;i<num_mutexes;++i)
{
BOOST_CHECK(mutexes[i].is_locked);
@@ -306,7 +306,7 @@ public:
explicit dummy_iterator(dummy_mutex* p_):
p(p_)
{}
-
+
bool operator==(dummy_iterator const& other) const
{
return p==other.p;
@@ -321,7 +321,7 @@ public:
{
return p<other.p;
}
-
+
dummy_mutex& operator*() const
{
return *p;
@@ -331,22 +331,22 @@ public:
{
return p;
}
-
+
dummy_iterator operator++(int)
{
dummy_iterator temp(*this);
++p;
return temp;
}
-
+
dummy_iterator& operator++()
{
++p;
return *this;
}
-
+
};
-
+
void test_lock_five_in_range_custom_iterator()
{
@@ -354,7 +354,7 @@ void test_lock_five_in_range_custom_iterator()
dummy_mutex mutexes[num_mutexes];
boost::lock(dummy_iterator(mutexes),dummy_iterator(mutexes+num_mutexes));
-
+
for(unsigned i=0;i<num_mutexes;++i)
{
BOOST_CHECK(mutexes[i].is_locked);
@@ -372,7 +372,7 @@ void test_lock_ten_in_range_inherited_mutex()
dummy_mutex2 mutexes[num_mutexes];
boost::lock(mutexes,mutexes+num_mutexes);
-
+
for(unsigned i=0;i<num_mutexes;++i)
{
BOOST_CHECK(mutexes[i].is_locked);
@@ -384,7 +384,7 @@ void test_try_lock_two_uncontended()
dummy_mutex m1,m2;
int const res=boost::try_lock(m1,m2);
-
+
BOOST_CHECK(res==-1);
BOOST_CHECK(m1.is_locked);
BOOST_CHECK(m2.is_locked);
@@ -398,7 +398,7 @@ void test_try_lock_two_first_locked()
l2(m2,boost::defer_lock);
int const res=boost::try_lock(l1,l2);
-
+
BOOST_CHECK(res==0);
BOOST_CHECK(m1.is_locked);
BOOST_CHECK(!m2.is_locked);
@@ -414,7 +414,7 @@ void test_try_lock_two_second_locked()
l2(m2,boost::defer_lock);
int const res=boost::try_lock(l1,l2);
-
+
BOOST_CHECK(res==1);
BOOST_CHECK(!m1.is_locked);
BOOST_CHECK(m2.is_locked);
@@ -425,7 +425,7 @@ void test_try_lock_two_second_locked()
void test_try_lock_three()
{
int const num_mutexes=3;
-
+
for(int i=-1;i<num_mutexes;++i)
{
dummy_mutex mutexes[num_mutexes];
@@ -439,7 +439,7 @@ void test_try_lock_three()
l3(mutexes[2],boost::defer_lock);
int const res=boost::try_lock(l1,l2,l3);
-
+
BOOST_CHECK(res==i);
for(int j=0;j<num_mutexes;++j)
{
@@ -470,7 +470,7 @@ void test_try_lock_three()
void test_try_lock_four()
{
int const num_mutexes=4;
-
+
for(int i=-1;i<num_mutexes;++i)
{
dummy_mutex mutexes[num_mutexes];
@@ -485,7 +485,7 @@ void test_try_lock_four()
l4(mutexes[3],boost::defer_lock);
int const res=boost::try_lock(l1,l2,l3,l4);
-
+
BOOST_CHECK(res==i);
for(int j=0;j<num_mutexes;++j)
{
@@ -518,7 +518,7 @@ void test_try_lock_four()
void test_try_lock_five()
{
int const num_mutexes=5;
-
+
for(int i=-1;i<num_mutexes;++i)
{
dummy_mutex mutexes[num_mutexes];
@@ -534,7 +534,7 @@ void test_try_lock_five()
l5(mutexes[4],boost::defer_lock);
int const res=boost::try_lock(l1,l2,l3,l4,l5);
-
+
BOOST_CHECK(res==i);
for(int j=0;j<num_mutexes;++j)
{
@@ -592,3 +592,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_hardware_concurrency.cpp b/libs/thread/test/test_hardware_concurrency.cpp
index 39f2fd6ad2..78ab846895 100644
--- a/libs/thread/test/test_hardware_concurrency.cpp
+++ b/libs/thread/test/test_hardware_concurrency.cpp
@@ -1,6 +1,6 @@
// Copyright (C) 2007 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread.hpp>
#include <boost/test/unit_test.hpp>
@@ -19,3 +19,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
test->add(BOOST_TEST_CASE(test_hardware_concurrency_is_non_zero));
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_lock_concept.cpp b/libs/thread/test/test_lock_concept.cpp
index bd0a22ad89..cc9d518c14 100644
--- a/libs/thread/test/test_lock_concept.cpp
+++ b/libs/thread/test/test_lock_concept.cpp
@@ -18,7 +18,7 @@ struct test_initially_locked
{
Mutex m;
Lock lock(m);
-
+
BOOST_CHECK(lock);
BOOST_CHECK(lock.owns_lock());
}
@@ -32,7 +32,7 @@ struct test_initially_unlocked_if_other_thread_has_lock
bool done;
bool locked;
boost::condition_variable done_cond;
-
+
test_initially_unlocked_if_other_thread_has_lock():
done(false),locked(false)
{}
@@ -51,7 +51,7 @@ struct test_initially_unlocked_if_other_thread_has_lock
{
return done;
}
-
+
void operator()()
{
@@ -69,7 +69,7 @@ struct test_initially_unlocked_if_other_thread_has_lock
boost::bind(&this_type::is_done,this)));
BOOST_CHECK(!locked);
}
-
+
lock.unlock();
t.join();
}
@@ -90,7 +90,7 @@ struct test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock
bool done;
bool locked;
boost::condition_variable done_cond;
-
+
test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock():
done(false),locked(false)
{}
@@ -109,7 +109,7 @@ struct test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock
{
return done;
}
-
+
void operator()()
{
@@ -127,7 +127,7 @@ struct test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock
boost::bind(&this_type::is_done,this)));
BOOST_CHECK(!locked);
}
-
+
lock.unlock();
t.join();
}
@@ -148,7 +148,7 @@ struct test_initially_locked_if_other_thread_has_shared_lock
bool done;
bool locked;
boost::condition_variable done_cond;
-
+
test_initially_locked_if_other_thread_has_shared_lock():
done(false),locked(false)
{}
@@ -167,7 +167,7 @@ struct test_initially_locked_if_other_thread_has_shared_lock
{
return done;
}
-
+
void operator()()
{
@@ -185,7 +185,7 @@ struct test_initially_locked_if_other_thread_has_shared_lock
boost::bind(&this_type::is_done,this)));
BOOST_CHECK(locked);
}
-
+
lock.unlock();
t.join();
}
@@ -205,7 +205,7 @@ struct test_initially_unlocked_with_defer_lock_parameter
{
Mutex m;
Lock lock(m,boost::defer_lock);
-
+
BOOST_CHECK(!lock);
BOOST_CHECK(!lock.owns_lock());
}
@@ -219,7 +219,7 @@ struct test_initially_locked_with_adopt_lock_parameter
Mutex m;
m.lock();
Lock lock(m,boost::adopt_lock);
-
+
BOOST_CHECK(lock);
BOOST_CHECK(lock.owns_lock());
}
@@ -273,7 +273,7 @@ struct test_unlocked_after_try_lock_if_other_thread_has_lock
bool done;
bool locked;
boost::condition_variable done_cond;
-
+
test_unlocked_after_try_lock_if_other_thread_has_lock():
done(false),locked(false)
{}
@@ -292,7 +292,7 @@ struct test_unlocked_after_try_lock_if_other_thread_has_lock
{
return done;
}
-
+
void operator()()
{
@@ -310,7 +310,7 @@ struct test_unlocked_after_try_lock_if_other_thread_has_lock
boost::bind(&this_type::is_done,this)));
BOOST_CHECK(!locked);
}
-
+
lock.unlock();
t.join();
}
@@ -330,7 +330,7 @@ struct test_throws_if_lock_called_when_already_locked
{
Mutex m;
Lock lock(m);
-
+
BOOST_CHECK_THROW( lock.lock(), boost::lock_error );
}
};
@@ -342,7 +342,7 @@ struct test_throws_if_try_lock_called_when_already_locked
{
Mutex m;
Lock lock(m);
-
+
BOOST_CHECK_THROW( lock.try_lock(), boost::lock_error );
}
};
@@ -355,7 +355,7 @@ struct test_throws_if_unlock_called_when_already_unlocked
Mutex m;
Lock lock(m);
lock.unlock();
-
+
BOOST_CHECK_THROW( lock.unlock(), boost::lock_error );
}
};
@@ -367,7 +367,7 @@ struct test_default_constructed_has_no_mutex_and_unlocked
Lock l;
BOOST_CHECK(!l.mutex());
BOOST_CHECK(!l.owns_lock());
- };
+ }
};
@@ -387,18 +387,21 @@ struct test_locks_can_be_swapped
BOOST_CHECK_EQUAL(l2.mutex(),&m2);
l1.swap(l2);
-
+
BOOST_CHECK_EQUAL(l1.mutex(),&m2);
BOOST_CHECK_EQUAL(l2.mutex(),&m1);
-
+
swap(l1,l2);
BOOST_CHECK_EQUAL(l1.mutex(),&m1);
BOOST_CHECK_EQUAL(l2.mutex(),&m2);
+#if 0
l1.swap(Lock(m3));
BOOST_CHECK_EQUAL(l1.mutex(),&m3);
+#endif
+
}
};
@@ -437,7 +440,7 @@ BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_unique_lock_is_scoped_lock,Mutex)
BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_try_lock_concept,Mutex)
{
typedef typename Mutex::scoped_try_lock Lock;
-
+
test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
test_initially_locked<Mutex,Lock>()();
test_initially_unlocked_if_other_thread_has_lock<Mutex,Lock>()();
@@ -470,25 +473,25 @@ struct dummy_shared_mutex
timed_locked_relative(false),
timed_locked_absolute(false)
{}
-
+
void lock()
{
locked=true;
}
-
+
void lock_shared()
{
shared_locked=true;
}
-
+
void unlock()
{}
-
+
void unlock_shared()
{
shared_unlocked=true;
}
-
+
bool timed_lock_shared(boost::system_time)
{
shared_timed_locked_absolute=true;
@@ -511,7 +514,7 @@ struct dummy_shared_mutex
timed_locked_relative=true;
return false;
}
-
+
};
@@ -519,7 +522,7 @@ void test_shared_lock()
{
typedef boost::shared_mutex Mutex;
typedef boost::shared_lock<Mutex> Lock;
-
+
test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
test_initially_locked<Mutex,Lock>()();
test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock<Mutex,Lock>()();
@@ -552,7 +555,7 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_lock;
-
+
test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_lock_concept,mutex_types_with_scoped_lock));
typedef boost::mpl::vector<boost::try_mutex,boost::timed_mutex,
@@ -562,9 +565,22 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex,boost::shared_mutex> all_mutex_types;
-
+
test->add(BOOST_TEST_CASE_TEMPLATE(test_unique_lock_is_scoped_lock,all_mutex_types));
test->add(BOOST_TEST_CASE(&test_shared_lock));
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_ml.cpp b/libs/thread/test/test_ml.cpp
new file mode 100755
index 0000000000..08707c233b
--- /dev/null
+++ b/libs/thread/test/test_ml.cpp
@@ -0,0 +1,196 @@
+#include <boost/config.hpp>
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/utility/result_of.hpp>
+#include <functional>
+
+struct async_func {
+ virtual ~async_func() { }
+ virtual void run() =0;
+ };
+
+template <typename Ret>
+class async_func_pt : public async_func {
+ boost::packaged_task<Ret> f;
+public:
+ void run() {
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+f(); }
+ async_func_pt (boost::packaged_task<Ret>&& f) : f(boost::move(f)) {}
+ ~async_func_pt() { }
+ boost::unique_future<Ret> get_future() { return f.get_future(); }
+ };
+
+void async_core (async_func* p) {
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ p->run();
+}
+
+
+
+
+template <typename F>
+boost::unique_future<typename boost::result_of< F() >::type>
+async (F&& f)
+ {
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ typedef typename boost::result_of< F() >::type RetType;
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ async_func_pt<RetType>* p= new async_func_pt<RetType> (boost::packaged_task<RetType>(boost::forward<F>(f)));
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ boost::unique_future<RetType> future_result= p->get_future();
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ async_core (p);
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ return boost::move(future_result);
+ }
+
+template <typename F, typename A1>
+boost::unique_future<typename boost::result_of< F(A1) >::type>
+async (F&& f, A1&& a1)
+ {
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+// This should be all it needs. But get a funny error deep inside Boost.
+// problem overloading with && ?
+ return async (boost::bind(f,a1));
+ }
+
+
+int calculate_the_answer_to_life_the_universe_and_everything()
+{
+ return 42;
+}
+
+
+size_t foo (const std::string& s)
+ {
+ return s.size();
+ }
+
+
+
+void test1()
+{
+// this one works
+ // most fundimental form:
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ boost::unique_future<int> fi= async (&calculate_the_answer_to_life_the_universe_and_everything);
+ int i= fi.get();
+ BOOST_TEST (i== 42);
+
+
+// This one chokes at compile time
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ boost::unique_future<size_t> fut_1= async (&foo, "Life");
+
+ BOOST_TEST (fut_1.get()== 4);
+}
+
+int main()
+{
+ test1();
+ return boost::report_errors();
+
+}
+
+#else
+int main()
+{
+ return 0;
+}
+
+#endif
+/*
+ *
+ "/Users/viboes/clang/llvmCore-3.0-rc1.install/bin/clang++"
+ -o "../../../bin.v2/libs/thread/test/test_ml.test/clang-darwin-3.0x/debug/threading-multi/test_ml"
+ "../../../bin.v2/libs/thread/test/test_ml.test/clang-darwin-3.0x/debug/threading-multi/test_ml.o"
+ "../../../bin.v2/libs/test/build/clang-darwin-3.0x/debug/link-static/threading-multi/libboost_unit_test_framework.a"
+ "../../../bin.v2/libs/thread/build/clang-darwin-3.0x/debug/threading-multi/libboost_thread.dylib"
+ "../../../bin.v2/libs/chrono/build/clang-darwin-3.0x/debug/threading-multi/libboost_chrono.dylib"
+ "../../../bin.v2/libs/system/build/clang-darwin-3.0x/debug/threading-multi/libboost_system.dylib" -g
+*/
+
+
+/*
+ *
+ * #include <boost/test/unit_test.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/utility/result_of.hpp>
+#include <functional>
+
+struct async_func {
+ virtual ~async_func() { }
+ virtual void run() =0;
+ };
+
+template <typename Ret>
+class async_func_pt : public async_func {
+ boost::packaged_task<Ret> f;
+public:
+ void run() override { f(); }
+ async_func_pt (boost::packaged_task<Ret>&& f) : f(std::move(f)) {}
+ ~async_func_pt() { }
+ boost::unique_future<Ret> get_future() { return f.get_future(); }
+ };
+
+void async_core (async_func* p);
+
+
+
+
+template <typename F>
+boost::unique_future<typename boost::result_of< F() >::type>
+async (F&& f)
+ {
+ typedef typename boost::result_of< F() >::type RetType;
+ async_func_pt<RetType>* p= new async_func_pt<RetType> (boost::packaged_task<RetType>(f));
+ boost::unique_future<RetType> future_result= p->get_future();
+ async_core (p);
+ return std::move(future_result);
+ }
+
+template <typename F, typename A1>
+boost::unique_future<typename boost::result_of< F(A1) >::type>
+async (F&& f, A1&& a1)
+ {
+// This should be all it needs. But get a funny error deep inside Boost.
+// problem overloading with && ?
+ return async (std::tr1::bind(f,a1));
+ }
+
+BOOST_AUTO_TEST_SUITE(thread_pool_tests)
+
+int calculate_the_answer_to_life_the_universe_and_everything()
+{
+ return 42;
+}
+
+
+size_t foo (const std::string& s)
+ {
+ return s.size();
+ }
+
+
+
+BOOST_AUTO_TEST_CASE( async_test )
+{
+// this one works
+ // most fundimental form:
+ boost::unique_future<int> fi= async (&calculate_the_answer_to_life_the_universe_and_everything);
+ int i= fi.get();
+ BOOST_CHECK_EQUAL (i, 42);
+
+
+// This one chokes at compile time
+ boost::unique_future<size_t> fut_1= async (&foo, "Life");
+
+ BOOST_CHECK_EQUAL (fut_1.get(), 4);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+ */
diff --git a/libs/thread/test/test_move_function.cpp b/libs/thread/test/test_move_function.cpp
index fa139e8863..8d9cd9333b 100644
--- a/libs/thread/test/test_move_function.cpp
+++ b/libs/thread/test/test_move_function.cpp
@@ -47,7 +47,8 @@ void test_thread_move_from_rvalue_on_construction()
void test_thread_move_from_rvalue_using_explicit_move()
{
- boost::thread x(boost::move(start_thread()));
+ //boost::thread x(boost::move(start_thread()));
+ boost::thread x=start_thread();
BOOST_CHECK(x.get_id()!=boost::thread::id());
x.join();
}
@@ -108,15 +109,10 @@ namespace user_test_ns
};
}
-#ifdef BOOST_NO_RVALUE_REFERENCES
namespace boost
{
- template <>
- struct has_move_emulation_enabled_aux<user_test_ns::nc>
- : BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
- {};
+ BOOST_THREAD_DCL_MOVABLE(user_test_ns::nc)
}
-#endif
void test_move_for_user_defined_type_unaffected()
{
@@ -143,3 +139,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
test->add(BOOST_TEST_CASE(test_move_for_user_defined_type_unaffected));
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_mutex.cpp b/libs/thread/test/test_mutex.cpp
index 0350898e8b..68a982d947 100644
--- a/libs/thread/test/test_mutex.cpp
+++ b/libs/thread/test/test_mutex.cpp
@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
@@ -101,13 +101,13 @@ template<typename Mutex>
struct test_lock_times_out_if_other_thread_has_lock
{
typedef boost::unique_lock<Mutex> Lock;
-
+
Mutex m;
boost::mutex done_mutex;
bool done;
bool locked;
boost::condition_variable done_cond;
-
+
test_lock_times_out_if_other_thread_has_lock():
done(false),locked(false)
{}
@@ -139,14 +139,14 @@ struct test_lock_times_out_if_other_thread_has_lock
}
typedef test_lock_times_out_if_other_thread_has_lock<Mutex> this_type;
-
+
void do_test(void (this_type::*test_func)())
{
Lock lock(m);
locked=false;
done=false;
-
+
boost::thread t(test_func,this);
try
@@ -157,7 +157,7 @@ struct test_lock_times_out_if_other_thread_has_lock
boost::bind(&this_type::is_done,this)));
BOOST_CHECK(!locked);
}
-
+
lock.unlock();
t.join();
}
@@ -168,7 +168,7 @@ struct test_lock_times_out_if_other_thread_has_lock
throw;
}
}
-
+
void operator()()
{
@@ -191,7 +191,7 @@ struct test_timedlock
void operator()()
{
test_lock_times_out_if_other_thread_has_lock<mutex_type>()();
-
+
mutex_type mutex;
boost::condition condition;
@@ -243,7 +243,7 @@ struct test_timedlock
BOOST_CHECK(lock ? true : false);
lock.unlock();
BOOST_CHECK(!lock);
-
+
}
};
@@ -345,3 +345,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_once.cpp b/libs/thread/test/test_once.cpp
index 340bef7e3c..8c75dcd7ca 100644
--- a/libs/thread/test/test_once.cpp
+++ b/libs/thread/test/test_once.cpp
@@ -8,6 +8,9 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/once.hpp>
+#define LOG \
+ if (false) {} else std::cout << std::endl << __FILE__ << "[" << __LINE__ << "]"
+
boost::once_flag flag=BOOST_ONCE_INIT;
int var_to_init=0;
boost::mutex m;
@@ -39,6 +42,8 @@ void call_once_thread()
void test_call_once()
{
+ LOG;
+
unsigned const num_threads=20;
boost::thread_group group;
@@ -68,7 +73,7 @@ struct increment_value
explicit increment_value(int* value_):
value(value_)
{}
-
+
void operator()() const
{
boost::mutex::scoped_lock lock(m);
@@ -96,6 +101,8 @@ void call_once_with_functor()
void test_call_once_arbitrary_functor()
{
+ LOG;
+
unsigned const num_threads=20;
boost::thread_group group;
@@ -124,7 +131,7 @@ struct throw_before_third_pass
{};
static unsigned pass_counter;
-
+
void operator()() const
{
boost::mutex::scoped_lock lock(m);
@@ -155,6 +162,7 @@ void call_once_with_exception()
void test_call_once_retried_on_exception()
{
+ LOG;
unsigned const num_threads=20;
boost::thread_group group;
@@ -189,3 +197,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_shared_mutex.cpp b/libs/thread/test/test_shared_mutex.cpp
index 6085bd1211..00c64274c5 100644
--- a/libs/thread/test/test_shared_mutex.cpp
+++ b/libs/thread/test/test_shared_mutex.cpp
@@ -6,8 +6,8 @@
#include <boost/test/unit_test.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
-#include "util.inl"
-#include "shared_mutex_locking_thread.hpp"
+#include <libs/thread/test/util.inl>
+#include <libs/thread/test/shared_mutex_locking_thread.hpp>
#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
{ \
@@ -18,7 +18,7 @@
void test_multiple_readers()
{
unsigned const number_of_threads=10;
-
+
boost::thread_group pool;
boost::shared_mutex rw_mutex;
@@ -65,7 +65,7 @@ void test_multiple_readers()
void test_only_one_writer_permitted()
{
unsigned const number_of_threads=10;
-
+
boost::thread_group pool;
boost::shared_mutex rw_mutex;
@@ -76,7 +76,7 @@ void test_only_one_writer_permitted()
boost::condition_variable unblocked_condition;
boost::mutex finish_mutex;
boost::mutex::scoped_lock finish_lock(finish_mutex);
-
+
try
{
for(unsigned i=0;i<number_of_threads;++i)
@@ -116,10 +116,10 @@ void test_reader_blocks_writer()
boost::condition_variable unblocked_condition;
boost::mutex finish_mutex;
boost::mutex::scoped_lock finish_lock(finish_mutex);
-
+
try
{
-
+
pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
finish_mutex,simultaneous_running_count,max_simultaneous_running));
{
@@ -177,7 +177,7 @@ void test_unlocking_writer_unblocks_all_readers()
CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,0U);
write_lock.unlock();
-
+
{
boost::mutex::scoped_lock lk(unblocked_count_mutex);
while(unblocked_count<reader_count)
@@ -283,3 +283,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_shared_mutex_part_2.cpp b/libs/thread/test/test_shared_mutex_part_2.cpp
index eb9c05ee21..ee8b401558 100644
--- a/libs/thread/test/test_shared_mutex_part_2.cpp
+++ b/libs/thread/test/test_shared_mutex_part_2.cpp
@@ -6,8 +6,8 @@
#include <boost/test/unit_test.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
-#include "util.inl"
-#include "shared_mutex_locking_thread.hpp"
+#include <libs/thread/test/util.inl>
+#include <libs/thread/test/shared_mutex_locking_thread.hpp>
#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
{ \
@@ -21,9 +21,9 @@ class simple_upgrade_thread
boost::mutex& finish_mutex;
boost::mutex& unblocked_mutex;
unsigned& unblocked_count;
-
+
void operator=(simple_upgrade_thread&);
-
+
public:
simple_upgrade_thread(boost::shared_mutex& rwm_,
boost::mutex& finish_mutex_,
@@ -32,16 +32,16 @@ public:
rwm(rwm_),finish_mutex(finish_mutex_),
unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
{}
-
+
void operator()()
{
boost::upgrade_lock<boost::shared_mutex> lk(rwm);
-
+
{
boost::mutex::scoped_lock ulk(unblocked_mutex);
++unblocked_count;
}
-
+
boost::mutex::scoped_lock flk(finish_mutex);
}
};
@@ -50,7 +50,7 @@ public:
void test_only_one_upgrade_lock_permitted()
{
unsigned const number_of_threads=10;
-
+
boost::thread_group pool;
boost::shared_mutex rw_mutex;
@@ -61,7 +61,7 @@ void test_only_one_upgrade_lock_permitted()
boost::condition_variable unblocked_condition;
boost::mutex finish_mutex;
boost::mutex::scoped_lock finish_lock(finish_mutex);
-
+
try
{
for(unsigned i=0;i<number_of_threads;++i)
@@ -297,3 +297,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_shared_mutex_timed_locks.cpp b/libs/thread/test/test_shared_mutex_timed_locks.cpp
index 2e39cc062a..f341e0a086 100644
--- a/libs/thread/test/test_shared_mutex_timed_locks.cpp
+++ b/libs/thread/test/test_shared_mutex_timed_locks.cpp
@@ -6,8 +6,8 @@
#include <boost/test/unit_test.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
-#include "util.inl"
-#include "shared_mutex_locking_thread.hpp"
+#include <libs/thread/test/util.inl>
+#include <libs/thread/test/shared_mutex_locking_thread.hpp>
#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
{ \
@@ -237,7 +237,7 @@ void test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held()
{
rw_mutex.unlock();
}
-
+
boost::posix_time::milliseconds const wait_duration(500);
timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
BOOST_CHECK(timed_lock_succeeded);
@@ -266,3 +266,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_shared_mutex_timed_locks_chrono.cpp b/libs/thread/test/test_shared_mutex_timed_locks_chrono.cpp
new file mode 100644
index 0000000000..847cd0be95
--- /dev/null
+++ b/libs/thread/test/test_shared_mutex_timed_locks_chrono.cpp
@@ -0,0 +1,288 @@
+// (C) Copyright 2006-7 Anthony Williams
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <libs/thread/test/util.inl>
+#include <libs/thread/test/shared_mutex_locking_thread.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
+ { \
+ boost::mutex::scoped_lock lock(mutex_name); \
+ BOOST_CHECK_EQUAL(value,expected_value); \
+ }
+
+
+void test_timed_lock_shared_times_out_if_write_lock_held()
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::mutex::scoped_lock finish_lock(finish_mutex);
+ boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ boost::chrono::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.try_lock_shared_until(timeout);
+ BOOST_CHECK((timeout-timeout_resolution)<boost::chrono::steady_clock::now());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
+ timed_lock_succeeded=rw_mutex.try_lock_shared_for(wait_duration);
+ BOOST_CHECK((timeout2-timeout_resolution)<boost::chrono::steady_clock::now());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ finish_lock.unlock();
+ writer.join();
+}
+
+void test_timed_lock_shared_succeeds_if_no_lock_held()
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ boost::chrono::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.try_lock_shared_until(timeout);
+ BOOST_CHECK(boost::chrono::steady_clock::now()<timeout);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
+ timed_lock_succeeded=rw_mutex.try_lock_shared_for(wait_duration);
+ BOOST_CHECK(boost::chrono::steady_clock::now()<timeout2);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+}
+
+void test_timed_lock_shared_succeeds_if_read_lock_held()
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::mutex::scoped_lock finish_lock(finish_mutex);
+ boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ boost::chrono::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.try_lock_shared_until(timeout);
+ BOOST_CHECK(boost::chrono::steady_clock::now()<timeout);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
+ timed_lock_succeeded=rw_mutex.try_lock_shared_for(wait_duration);
+ BOOST_CHECK(boost::chrono::steady_clock::now()<timeout2);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ finish_lock.unlock();
+ reader.join();
+}
+
+void test_timed_lock_times_out_if_write_lock_held()
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::mutex::scoped_lock finish_lock(finish_mutex);
+ boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ boost::chrono::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.try_lock_until(timeout);
+ BOOST_CHECK((timeout-timeout_resolution)<boost::chrono::steady_clock::now());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
+ timed_lock_succeeded=rw_mutex.try_lock_for(wait_duration);
+ BOOST_CHECK((timeout2-timeout_resolution)<boost::chrono::steady_clock::now());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ finish_lock.unlock();
+ writer.join();
+}
+
+void test_timed_lock_succeeds_if_no_lock_held()
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ boost::chrono::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.try_lock_until(timeout);
+ BOOST_CHECK(boost::chrono::steady_clock::now()<timeout);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
+ timed_lock_succeeded=rw_mutex.try_lock_for(wait_duration);
+ BOOST_CHECK(boost::chrono::steady_clock::now()<timeout2);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+}
+
+void test_timed_lock_times_out_if_read_lock_held()
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::mutex::scoped_lock finish_lock(finish_mutex);
+ boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ boost::chrono::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.try_lock_until(timeout);
+ BOOST_CHECK((timeout-timeout_resolution)<boost::chrono::steady_clock::now());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
+ timed_lock_succeeded=rw_mutex.try_lock_for(wait_duration);
+ BOOST_CHECK((timeout2-timeout_resolution)<boost::chrono::steady_clock::now());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ finish_lock.unlock();
+ reader.join();
+}
+
+void test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held()
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::mutex::scoped_lock finish_lock(finish_mutex);
+ boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ bool timed_lock_succeeded=rw_mutex.try_lock_until(timeout);
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ timed_lock_succeeded=rw_mutex.try_lock_shared_for(wait_duration);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ finish_lock.unlock();
+ reader.join();
+}
+
+
+boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
+{
+ boost::unit_test::test_suite* test =
+ BOOST_TEST_SUITE("Boost.Threads: shared_mutex test suite");
+
+ test->add(BOOST_TEST_CASE(&test_timed_lock_shared_times_out_if_write_lock_held));
+ test->add(BOOST_TEST_CASE(&test_timed_lock_shared_succeeds_if_no_lock_held));
+ test->add(BOOST_TEST_CASE(&test_timed_lock_shared_succeeds_if_read_lock_held));
+ test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_if_write_lock_held));
+ test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_if_read_lock_held));
+ test->add(BOOST_TEST_CASE(&test_timed_lock_succeeds_if_no_lock_held));
+ test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held));
+
+ return test;
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_thread.cpp b/libs/thread/test/test_thread.cpp
index fe6ffa36fa..5944a21e69 100644
--- a/libs/thread/test/test_thread.cpp
+++ b/libs/thread/test/test_thread.cpp
@@ -2,7 +2,7 @@
// William E. Kempf
// Copyright (C) 2008 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
@@ -28,7 +28,7 @@ void simple_thread()
void comparison_thread(boost::thread::id parent)
{
boost::thread::id const my_id=boost::this_thread::get_id();
-
+
BOOST_CHECK(my_id != parent);
boost::thread::id const my_id2=boost::this_thread::get_id();
BOOST_CHECK(my_id == my_id2);
@@ -44,7 +44,7 @@ void test_sleep()
// Ensure it's in a range instead of checking actual equality due to time
// lapse
- BOOST_CHECK(in_range(xt, 2));
+ BOOST_CHECK(boost::threads::test::in_range(xt, 2));
}
void do_test_creation()
@@ -125,11 +125,11 @@ struct non_copyable_functor:
boost::noncopyable
{
unsigned value;
-
+
non_copyable_functor():
value(0)
{}
-
+
void operator()()
{
value=999;
@@ -139,7 +139,7 @@ struct non_copyable_functor:
void do_test_creation_through_reference_wrapper()
{
non_copyable_functor f;
-
+
boost::thread thrd(boost::ref(f));
thrd.join();
BOOST_CHECK_EQUAL(f.value, 999u);
@@ -155,11 +155,11 @@ struct long_running_thread
boost::condition_variable cond;
boost::mutex mut;
bool done;
-
+
long_running_thread():
done(false)
{}
-
+
void operator()()
{
boost::mutex::scoped_lock lk(mut);
@@ -177,7 +177,7 @@ void do_test_timed_join()
BOOST_CHECK(thrd.joinable());
boost::system_time xt=delay(3);
bool const joined=thrd.timed_join(xt);
- BOOST_CHECK(in_range(boost::get_xtime(xt), 2));
+ BOOST_CHECK(boost::threads::test::in_range(boost::get_xtime(xt), 2));
BOOST_CHECK(!joined);
BOOST_CHECK(thrd.joinable());
{
@@ -185,7 +185,7 @@ void do_test_timed_join()
f.done=true;
f.cond.notify_one();
}
-
+
xt=delay(3);
bool const joined2=thrd.timed_join(xt);
boost::system_time const now=boost::get_system_time();
@@ -209,7 +209,7 @@ void test_swap()
t.swap(t2);
BOOST_CHECK(t.get_id()==id2);
BOOST_CHECK(t2.get_id()==id1);
-
+
swap(t,t2);
BOOST_CHECK(t.get_id()==id1);
BOOST_CHECK(t2.get_id()==id2);
@@ -232,3 +232,17 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)boost::unit_test::first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+
+}
diff --git a/libs/thread/test/test_thread_exit.cpp b/libs/thread/test/test_thread_exit.cpp
index a706cb3306..c940b856e8 100644
--- a/libs/thread/test/test_thread_exit.cpp
+++ b/libs/thread/test/test_thread_exit.cpp
@@ -1,13 +1,13 @@
-// (C) Copyright 2009 Anthony Williams
+// (C) Copyright 2009 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#include "boost/thread/thread.hpp"
-#include "boost/thread/mutex.hpp"
-#include "boost/thread/condition.hpp"
-#include "boost/thread/future.hpp"
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/future.hpp>
#include <utility>
#include <memory>
#include <string>
@@ -71,3 +71,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)boost::unit_test::first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_thread_id.cpp b/libs/thread/test/test_thread_id.cpp
index a20805d8c4..0cf71a9dc6 100644
--- a/libs/thread/test/test_thread_id.cpp
+++ b/libs/thread/test/test_thread_id.cpp
@@ -1,6 +1,6 @@
// Copyright (C) 2007 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread.hpp>
#include <boost/test/unit_test.hpp>
@@ -61,7 +61,7 @@ void test_thread_ids_have_a_total_order()
BOOST_CHECK((t3.get_id()<t.get_id()) == (t.get_id()>=t3.get_id()));
BOOST_CHECK((t2.get_id()<t3.get_id()) == (t3.get_id()>=t2.get_id()));
BOOST_CHECK((t3.get_id()<t2.get_id()) == (t2.get_id()>=t3.get_id()));
-
+
BOOST_CHECK((t.get_id()<=t2.get_id()) == (t2.get_id()>t.get_id()));
BOOST_CHECK((t2.get_id()<=t.get_id()) == (t.get_id()>t2.get_id()));
BOOST_CHECK((t.get_id()<=t3.get_id()) == (t3.get_id()>t.get_id()));
@@ -111,7 +111,7 @@ void test_thread_ids_have_a_total_order()
BOOST_CHECK(!(default_id > t.get_id()));
BOOST_CHECK(!(default_id > t2.get_id()));
BOOST_CHECK(!(default_id > t3.get_id()));
-
+
BOOST_CHECK(!(default_id >= t.get_id()));
BOOST_CHECK(!(default_id >= t2.get_id()));
BOOST_CHECK(!(default_id >= t3.get_id()));
@@ -120,7 +120,7 @@ void test_thread_ids_have_a_total_order()
t2.join();
t3.join();
}
-
+
void get_thread_id(boost::thread::id* id)
{
*id=boost::this_thread::get_id();
@@ -147,3 +147,16 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
test->add(BOOST_TEST_CASE(test_thread_id_of_running_thread_returned_by_this_thread_get_id));
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)boost::unit_test::first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+}
diff --git a/libs/thread/test/test_thread_launching.cpp b/libs/thread/test/test_thread_launching.cpp
index 714f33bf6a..ee309e42ed 100644
--- a/libs/thread/test/test_thread_launching.cpp
+++ b/libs/thread/test/test_thread_launching.cpp
@@ -1,6 +1,6 @@
// Copyright (C) 2007-8 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread.hpp>
#include <boost/test/unit_test.hpp>
@@ -40,7 +40,7 @@ void test_thread_function_one_argument()
struct callable_no_args
{
static bool called;
-
+
void operator()() const
{
called=true;
@@ -61,7 +61,7 @@ struct callable_noncopyable_no_args:
boost::noncopyable
{
static bool called;
-
+
void operator()() const
{
called=true;
@@ -73,7 +73,7 @@ bool callable_noncopyable_no_args::called=false;
void test_thread_callable_object_ref_no_arguments()
{
callable_noncopyable_no_args func;
-
+
boost::thread callable(boost::ref(func));
callable.join();
BOOST_CHECK(callable_noncopyable_no_args::called);
@@ -83,7 +83,7 @@ struct callable_one_arg
{
static bool called;
static int called_arg;
-
+
void operator()(int arg) const
{
called=true;
@@ -112,7 +112,7 @@ struct callable_multiple_arg
static std::string called_three_arg1;
static std::vector<int> called_three_arg2;
static int called_three_arg3;
-
+
void operator()(int arg1,double arg2) const
{
called_two=true;
@@ -145,8 +145,10 @@ void test_thread_callable_object_multiple_arguments()
}
callable_multiple_arg func;
-
- boost::thread callable3(func,"hello",x,1.2);
+ // Avoid
+ // boost/bind/bind.hpp(392) : warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data
+
+ boost::thread callable3(func,"hello",x,1);
callable3.join();
BOOST_CHECK(callable_multiple_arg::called_three);
BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg1,"hello");
@@ -155,11 +157,11 @@ void test_thread_callable_object_multiple_arguments()
{
BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg2.at(j),x[j]);
}
-
+
BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg3,1);
double const dbl=1.234;
-
+
boost::thread callable2(func,19,dbl);
callable2.join();
BOOST_CHECK(callable_multiple_arg::called_two);
@@ -176,7 +178,7 @@ struct X
function_called(false),
arg_value(0)
{}
-
+
void f0()
{
@@ -193,7 +195,7 @@ struct X
void test_thread_member_function_no_arguments()
{
X x;
-
+
boost::thread function(&X::f0,&x);
function.join();
BOOST_CHECK(x.function_called);
@@ -224,3 +226,17 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
test->add(BOOST_TEST_CASE(test_thread_member_function_one_argument));
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)boost::unit_test::first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+
+}
diff --git a/libs/thread/test/test_thread_move.cpp b/libs/thread/test/test_thread_move.cpp
index f644e1ebd8..37c9c9d61f 100644
--- a/libs/thread/test/test_thread_move.cpp
+++ b/libs/thread/test/test_thread_move.cpp
@@ -1,6 +1,6 @@
// Copyright (C) 2007-9 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread.hpp>
#include <boost/test/unit_test.hpp>
@@ -54,3 +54,17 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
test->add(BOOST_TEST_CASE(test_move_assign));
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)boost::unit_test::first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+
+}
diff --git a/libs/thread/test/test_thread_move_return.cpp b/libs/thread/test/test_thread_move_return.cpp
index 51f0b3faee..5799fbadb7 100644
--- a/libs/thread/test/test_thread_move_return.cpp
+++ b/libs/thread/test/test_thread_move_return.cpp
@@ -1,7 +1,10 @@
// Copyright (C) 2009 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_USES_MOVE
+
#include <boost/thread/thread.hpp>
#include <boost/test/unit_test.hpp>
@@ -33,3 +36,17 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
test->add(BOOST_TEST_CASE(test_move_from_function_move_return));
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)boost::unit_test::first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+
+}
diff --git a/libs/thread/test/test_thread_return_local.cpp b/libs/thread/test/test_thread_return_local.cpp
index be2aec5137..76cf7cd3e7 100644
--- a/libs/thread/test/test_thread_return_local.cpp
+++ b/libs/thread/test/test_thread_return_local.cpp
@@ -1,7 +1,10 @@
// Copyright (C) 2009 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_USES_MOVE
+
#include <boost/thread/thread.hpp>
#include <boost/test/unit_test.hpp>
@@ -13,7 +16,7 @@ void do_nothing(boost::thread::id* my_id)
boost::thread make_thread_return_local(boost::thread::id* the_id)
{
boost::thread t(do_nothing,the_id);
- return t;
+ return boost::move(t);
}
void test_move_from_function_return_local()
@@ -33,3 +36,17 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
test->add(BOOST_TEST_CASE(test_move_from_function_return_local));
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)boost::unit_test::first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+
+}
diff --git a/libs/thread/test/test_tss.cpp b/libs/thread/test/test_tss.cpp
index 894875fe6c..45a0cbd823 100644
--- a/libs/thread/test/test_tss.cpp
+++ b/libs/thread/test/test_tss.cpp
@@ -2,7 +2,7 @@
// William E. Kempf
// Copyright (C) 2007 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
@@ -19,7 +19,7 @@
#if defined(BOOST_HAS_WINTHREADS)
#define WIN32_LEAN_AND_MEAN
- #include <windows.h>
+ #include <windows.h>
#endif
boost::mutex check_mutex;
@@ -76,7 +76,7 @@ void test_tss_thread()
{
native_thread_t const res=CreateThread(
0, //security attributes (0 = not inheritable)
- 0, //stack size (0 = default)
+ 0, //stack size (0 = default)
&test_tss_thread_native, //function to execute
0, //parameter to pass to function
0, //creation flags (0 = run immediately)
@@ -99,7 +99,7 @@ void test_tss_thread()
extern "C"
{
- void* test_tss_thread_native(void* lpParameter)
+ void* test_tss_thread_native(void* )
{
test_tss_thread();
return 0;
@@ -109,7 +109,7 @@ extern "C"
native_thread_t create_native_thread()
{
native_thread_t thread_handle;
-
+
int const res = pthread_create(&thread_handle, 0, &test_tss_thread_native, 0);
BOOST_CHECK(!res);
return thread_handle;
@@ -261,12 +261,12 @@ void do_test_tss_does_no_cleanup_after_release()
struct dummy_class_tracks_deletions
{
static unsigned deletions;
-
+
~dummy_class_tracks_deletions()
{
++deletions;
}
-
+
};
unsigned dummy_class_tracks_deletions::deletions=0;
@@ -357,3 +357,17 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)boost::unit_test::first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+
+}
diff --git a/libs/thread/test/test_xtime.cpp b/libs/thread/test/test_xtime.cpp
index 0dff620094..2ba3013c37 100644
--- a/libs/thread/test/test_xtime.cpp
+++ b/libs/thread/test/test_xtime.cpp
@@ -2,7 +2,7 @@
// William E. Kempf
// Copyright (C) 2008 Anthony Williams
//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
@@ -17,8 +17,8 @@ void test_xtime_cmp()
{
boost::xtime xt1, xt2, cur;
BOOST_CHECK_EQUAL(
- boost::xtime_get(&cur, boost::TIME_UTC),
- static_cast<int>(boost::TIME_UTC));
+ boost::xtime_get(&cur, boost::TIME_UTC_),
+ static_cast<int>(boost::TIME_UTC_));
xt1 = xt2 = cur;
xt1.nsec -= 1;
@@ -42,14 +42,14 @@ void test_xtime_get()
boost::xtime orig, cur, old;
BOOST_CHECK_EQUAL(
boost::xtime_get(&orig,
- boost::TIME_UTC), static_cast<int>(boost::TIME_UTC));
+ boost::TIME_UTC_), static_cast<int>(boost::TIME_UTC_));
old = orig;
for (int x=0; x < 100; ++x)
{
BOOST_CHECK_EQUAL(
- boost::xtime_get(&cur, boost::TIME_UTC),
- static_cast<int>(boost::TIME_UTC));
+ boost::xtime_get(&cur, boost::TIME_UTC_),
+ static_cast<int>(boost::TIME_UTC_));
BOOST_CHECK(boost::xtime_cmp(cur, orig) >= 0);
BOOST_CHECK(boost::xtime_cmp(cur, old) >= 0);
old = cur;
@@ -85,7 +85,7 @@ void test_xtime_condvar_backwards_compatibility()
boost::condition_variable cond;
boost::condition_variable_any cond_any;
boost::mutex m;
-
+
boost::mutex::scoped_lock lk(m);
cond.timed_wait(lk,boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10)));
cond.timed_wait(lk,boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10)),predicate);
@@ -107,3 +107,17 @@ boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
return test;
}
+
+void remove_unused_warning()
+{
+
+ //../../../boost/test/results_collector.hpp:40:13: warning: unused function 'first_failed_assertion' [-Wunused-function]
+ //(void)boost::unit_test::first_failed_assertion;
+
+ //../../../boost/test/tools/floating_point_comparison.hpp:304:25: warning: unused variable 'check_is_close' [-Wunused-variable]
+ //../../../boost/test/tools/floating_point_comparison.hpp:326:25: warning: unused variable 'check_is_small' [-Wunused-variable]
+ (void)boost::test_tools::check_is_close;
+ (void)boost::test_tools::check_is_small;
+
+
+}
diff --git a/libs/thread/test/threads/container/thread_ptr_list_pass.cpp b/libs/thread/test/threads/container/thread_ptr_list_pass.cpp
new file mode 100644
index 0000000000..3bf58110fb
--- /dev/null
+++ b/libs/thread/test/threads/container/thread_ptr_list_pass.cpp
@@ -0,0 +1,101 @@
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_USES_MOVE
+
+#include <boost/config.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/container/list.hpp>
+//#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
+#include <boost/smart_ptr.hpp>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int count = 0;
+boost::mutex mutex;
+
+namespace {
+
+
+template <typename TC>
+void join_all(TC & tc)
+{
+ for (typename TC::iterator it = tc.begin(); it != tc.end(); ++it)
+ {
+ (*it)->join();
+ }
+}
+
+
+void increment_count()
+{
+ boost::mutex::scoped_lock lock(mutex);
+ std::cout << "count = " << ++count << std::endl;
+}
+
+template <class T>
+struct default_delete
+{
+ typedef T* pointer;
+
+ BOOST_CONSTEXPR default_delete() BOOST_NOEXCEPT {} //= default;
+ template <class U>
+ default_delete(const default_delete<U>&) BOOST_NOEXCEPT
+ {}
+ void operator()(T* ptr) const
+ {
+ delete ptr;
+ }
+};
+
+}
+int main()
+{
+ {
+ typedef boost::shared_ptr<boost::thread > thread_ptr;
+ //typedef boost::interprocess::shared_ptr<boost::thread, std::allocator<boost::thread>, default_delete<boost::thread> > thread_ptr;
+ typedef boost::container::list<thread_ptr > thread_ptr_list;
+ thread_ptr_list threads;
+ for (int i = 0; i < 10; ++i)
+ {
+ //threads.push_back(BOOST_THREAD_MAKE_RV_REF(thread_ptr(new boost::thread(&increment_count))));
+ threads.push_back(thread_ptr(new boost::thread(&increment_count)));
+ }
+ BOOST_TEST(threads.size()==10);
+ //join_all(threads);
+ for (thread_ptr_list::iterator it = threads.begin(); it != threads.end(); ++it)
+ {
+ (*it)->join();
+ }
+ }
+ count = 0;
+ {
+ typedef boost::shared_ptr<boost::thread > thread_ptr;
+ //typedef boost::interprocess::shared_ptr<boost::thread, std::allocator<boost::thread>, default_delete<boost::thread> > thread_ptr;
+ typedef boost::container::list<thread_ptr > thread_ptr_list;
+ thread_ptr_list threads;
+ for (int i = 0; i < 10; ++i)
+ {
+ //threads.push_back(BOOST_THREAD_MAKE_RV_REF(thread_ptr(new boost::thread(&increment_count))));
+ threads.push_back(thread_ptr(new boost::thread(&increment_count)));
+ }
+ BOOST_TEST(threads.size()==10);
+ thread_ptr sth(new boost::thread(&increment_count));
+ threads.push_back(sth);
+ BOOST_TEST(threads.size()==11);
+ threads.remove(sth);
+ BOOST_TEST(threads.size()==10);
+ sth->join();
+ //join_all(threads);
+ for (thread_ptr_list::iterator it = threads.begin(); it != threads.end(); ++it)
+ {
+ (*it)->join();
+ }
+ }
+
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/threads/container/thread_vector_pass.cpp b/libs/thread/test/threads/container/thread_vector_pass.cpp
new file mode 100644
index 0000000000..121b8ec6f0
--- /dev/null
+++ b/libs/thread/test/threads/container/thread_vector_pass.cpp
@@ -0,0 +1,88 @@
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_USES_MOVE
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/container/vector.hpp>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+int count = 0;
+boost::mutex mutex;
+
+namespace
+{
+template <typename TC>
+void join_all(TC & tc)
+{
+ for (typename TC::iterator it = tc.begin(); it != tc.end(); ++it)
+ {
+ it->join();
+ }
+}
+
+template <typename TC>
+void interrupt_all(TC & tc)
+{
+ for (typename TC::iterator it = tc.begin(); it != tc.end(); ++it)
+ {
+ it->interrupt();
+ }
+}
+}
+
+void increment_count()
+{
+ boost::mutex::scoped_lock lock(mutex);
+ std::cout << "count = " << ++count << std::endl;
+}
+
+int main()
+{
+ typedef boost::container::vector<boost::thread> thread_vector;
+ {
+ thread_vector threads;
+ threads.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ {
+ boost::thread th(&increment_count);
+ threads.push_back(boost::move(th));
+ }
+ join_all(threads);
+ }
+ count = 0;
+ {
+ thread_vector threads;
+ threads.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ {
+ threads.push_back(BOOST_THREAD_MAKE_RV_REF(boost::thread(&increment_count)));
+ }
+ join_all(threads);
+ }
+ count = 0;
+ {
+ thread_vector threads;
+ threads.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ {
+ threads.emplace_back(&increment_count);
+ }
+ join_all(threads);
+ }
+ count = 0;
+ {
+ thread_vector threads;
+ threads.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ {
+ threads.emplace_back(&increment_count);
+ }
+ interrupt_all(threads);
+ }
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/threads/this_thread/get_id/get_id_pass.cpp b/libs/thread/test/threads/this_thread/get_id/get_id_pass.cpp
new file mode 100644
index 0000000000..8fb82b4a7d
--- /dev/null
+++ b/libs/thread/test/threads/this_thread/get_id/get_id_pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// thread::id this_thread::get_id();
+
+#include <boost/thread/thread.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::thread::id id = boost::this_thread::get_id();
+ BOOST_TEST(id != boost::thread::id());
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/threads/this_thread/sleep_for/sleep_for_pass.cpp b/libs/thread/test/threads/this_thread/sleep_for/sleep_for_pass.cpp
new file mode 100644
index 0000000000..ce325dcccc
--- /dev/null
+++ b/libs/thread/test/threads/this_thread/sleep_for/sleep_for_pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// thread::id this_thread::get_id();
+
+#include <boost/thread/thread.hpp>
+#include <cstdlib>
+#include <algorithm>
+
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+int main()
+{
+ typedef boost::chrono::system_clock Clock;
+ typedef Clock::time_point time_point;
+ typedef Clock::duration duration;
+ boost::chrono::milliseconds ms(500);
+ time_point t0 = Clock::now();
+ boost::this_thread::sleep_for(ms);
+ time_point t1 = Clock::now();
+ boost::chrono::nanoseconds ns = (t1 - t0) - ms;
+ boost::chrono::nanoseconds err = ms / 100;
+ // The time slept is within 1% of 500ms
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST((std::max)(ns.count(), -ns.count()) < (err+boost::chrono::milliseconds(1000)).count());
+ //BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+boost::chrono::milliseconds(1000)).count());
+ return boost::report_errors();
+
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/libs/thread/test/threads/this_thread/sleep_until/sleep_until_pass.cpp b/libs/thread/test/threads/this_thread/sleep_until/sleep_until_pass.cpp
new file mode 100644
index 0000000000..4adcd3c957
--- /dev/null
+++ b/libs/thread/test/threads/this_thread/sleep_until/sleep_until_pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// thread::id this_thread::get_id();
+
+#include <boost/thread/thread.hpp>
+#include <cstdlib>
+#include <algorithm>
+
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+int main()
+{
+ typedef boost::chrono::system_clock Clock;
+ typedef Clock::time_point time_point;
+ typedef Clock::duration duration;
+ boost::chrono::milliseconds ms(500);
+ time_point t0 = Clock::now();
+ boost::this_thread::sleep_until(t0 + ms);
+ time_point t1 = Clock::now();
+ boost::chrono::nanoseconds ns = (t1 - t0) - ms;
+ boost::chrono::nanoseconds err = ms / 100;
+ // The time slept is within 1% of 500ms
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST((std::max)(ns.count(), -ns.count()) < (err+boost::chrono::milliseconds(1000)).count());
+ //BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+boost::chrono::milliseconds(1000)).count());
+ return boost::report_errors();
+
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/libs/thread/test/threads/thread/assign/copy_fail.cpp b/libs/thread/test/threads/thread/assign/copy_fail.cpp
new file mode 100644
index 0000000000..23a15b7cc2
--- /dev/null
+++ b/libs/thread/test/threads/thread/assign/copy_fail.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// thread& operator=(thread&& t);
+
+#include <boost/thread/thread.hpp>
+#include <new>
+#include <cstdlib>
+#include <boost/detail/lightweight_test.hpp>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ boost::thread t1;
+ t1 = t0;
+ }
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+
+}
diff --git a/libs/thread/test/threads/thread/assign/move_pass.cpp b/libs/thread/test/threads/thread/assign/move_pass.cpp
new file mode 100644
index 0000000000..2163c54397
--- /dev/null
+++ b/libs/thread/test/threads/thread/assign/move_pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// thread& operator=(thread&& t);
+
+#define BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
+
+#include <boost/thread/thread.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+
+ void operator()(int i, double j)
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ BOOST_TEST(i == 5);
+ BOOST_TEST(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+void f1()
+{
+ std::exit(boost::report_errors());
+}
+
+int main()
+{
+ std::set_terminate(f1);
+ {
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(!G::op_run);
+ boost::thread t0(G(), 5, 5.5);
+ boost::thread::id id = t0.get_id();
+ boost::thread t1;
+ t1 = boost::move(t0);
+ BOOST_TEST(t1.get_id() == id);
+ BOOST_TEST(t0.get_id() == boost::thread::id());
+ t1.join();
+ BOOST_TEST(G::op_run);
+ }
+// BOOST_TEST(G::n_alive == 0);
+// {
+// boost::thread t0(G(), 5, 5.5);
+// boost::thread::id id = t0.get_id();
+// boost::thread t1;
+// t0 = boost::move(t1);
+// BOOST_TEST(false);
+// }
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/threads/thread/constr/FArgs_pass.cpp b/libs/thread/test/threads/thread/constr/FArgs_pass.cpp
new file mode 100644
index 0000000000..6a573fe3ea
--- /dev/null
+++ b/libs/thread/test/threads/thread/constr/FArgs_pass.cpp
@@ -0,0 +1,143 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class F, class ...Args> thread(F f, Args... args);
+
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+unsigned throw_one = 0xFFFF;
+
+#if defined _GLIBCXX_THROW
+void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
+#elif defined BOOST_MSVC
+void* operator new(std::size_t s)
+#else
+void* operator new(std::size_t s) throw (std::bad_alloc)
+#endif
+{
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ if (throw_one == 0) throw std::bad_alloc();
+ --throw_one;
+ return std::malloc(s);
+}
+
+#if defined BOOST_MSVC
+void operator delete(void* p)
+#else
+void operator delete(void* p) throw ()
+#endif
+{
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ std::free(p);
+}
+
+bool f_run = false;
+
+void f(int i, double j)
+{
+ BOOST_TEST(i == 5);
+ BOOST_TEST(j == 5.5);
+ f_run = true;
+}
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()(int i, double j)
+ {
+ BOOST_TEST(alive_ == 1);
+ BOOST_TEST(n_alive >= 1);
+ BOOST_TEST(i == 5);
+ BOOST_TEST(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+
+int main()
+{
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ boost::thread t(f, 5, 5.5);
+ t.join();
+ BOOST_TEST(f_run == true);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ }
+#ifndef BOOST_MSVC
+ f_run = false;
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ try
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ throw_one = 0;
+ boost::thread t(f, 5, 5.5);
+ BOOST_TEST(false);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ }
+ catch (...)
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ throw_one = 0xFFFF;
+ BOOST_TEST(!f_run);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ }
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ }
+#endif
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ BOOST_TEST(G::n_alive == 0);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ BOOST_TEST(!G::op_run);
+ boost::thread t(G(), 5, 5.5);
+ t.join();
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(G::op_run);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ }
+
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/threads/thread/constr/F_pass.cpp b/libs/thread/test/threads/thread/constr/F_pass.cpp
new file mode 100644
index 0000000000..03208a0d62
--- /dev/null
+++ b/libs/thread/test/threads/thread/constr/F_pass.cpp
@@ -0,0 +1,148 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class F, class ...Args> thread(F f, Args... args);
+
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+unsigned throw_one = 0xFFFF;
+
+#if defined _GLIBCXX_THROW
+void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
+#elif defined BOOST_MSVC
+void* operator new(std::size_t s)
+#else
+void* operator new(std::size_t s) throw (std::bad_alloc)
+#endif
+{
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ if (throw_one == 0) throw std::bad_alloc();
+ --throw_one;
+ return std::malloc(s);
+}
+
+#if defined BOOST_MSVC
+void operator delete(void* p)
+#else
+void operator delete(void* p) throw ()
+#endif
+{
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ std::free(p);
+}
+
+bool f_run = false;
+
+void f()
+{
+ f_run = true;
+}
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ BOOST_TEST(n_alive >= 1);
+ op_run = true;
+ }
+
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+
+int main()
+{
+ {
+ boost::thread t(f);
+ t.join();
+ BOOST_TEST(f_run == true);
+ }
+ f_run = false;
+#ifndef BOOST_MSVC
+ {
+ try
+ {
+ throw_one = 0;
+ boost::thread t(f);
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ throw_one = 0xFFFF;
+ BOOST_TEST(!f_run);
+ }
+ }
+#endif
+ {
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(!G::op_run);
+ boost::thread t( (G()));
+ t.join();
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(G::op_run);
+ }
+#ifndef BOOST_MSVC
+ G::op_run = false;
+ {
+ try
+ {
+ throw_one = 0;
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(!G::op_run);
+ boost::thread t( (G()));
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ throw_one = 0xFFFF;
+ BOOST_TEST(G::n_alive == 0);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ BOOST_TEST(!G::op_run);
+ }
+ }
+#endif
+
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp b/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp
new file mode 100644
index 0000000000..fdd5be1c12
--- /dev/null
+++ b/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class F, class ...Args> thread(F&& f, Args&&... args);
+
+#include <boost/thread/thread.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+class MoveOnly
+{
+ BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
+ MoveOnly()
+ {
+ }
+ MoveOnly(BOOST_THREAD_RV_REF(MoveOnly))
+ {}
+
+ void operator()(BOOST_THREAD_RV_REF(MoveOnly))
+ {
+ }
+};
+
+int main()
+{
+ {
+ boost::thread t = boost::thread( BOOST_THREAD_MAKE_RV_REF(MoveOnly()), BOOST_THREAD_MAKE_RV_REF(MoveOnly()) );
+ t.join();
+ }
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/threads/thread/constr/Frvalue_pass.cpp b/libs/thread/test/threads/thread/constr/Frvalue_pass.cpp
new file mode 100644
index 0000000000..4d89a76356
--- /dev/null
+++ b/libs/thread/test/threads/thread/constr/Frvalue_pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class F, class ...Args> thread(F&& f, Args&&... args);
+
+#define BOOST_THREAD_USES_MOVE
+
+#include <boost/thread/thread.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+class MoveOnly
+{
+public:
+ BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
+ MoveOnly()
+ {
+ }
+ MoveOnly(BOOST_THREAD_RV_REF(MoveOnly))
+ {}
+
+ void operator()()
+ {
+ }
+};
+
+MoveOnly MakeMoveOnly() {
+ return BOOST_THREAD_MAKE_RV_REF(MoveOnly());
+}
+
+int main()
+{
+ {
+ boost::thread t(( BOOST_THREAD_MAKE_RV_REF(MakeMoveOnly()) ));
+ t.join();
+ }
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/threads/thread/constr/copy_fail.cpp b/libs/thread/test/threads/thread/constr/copy_fail.cpp
new file mode 100644
index 0000000000..0b04b8c813
--- /dev/null
+++ b/libs/thread/test/threads/thread/constr/copy_fail.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// thread(const thread&) = delete;
+
+#include <boost/thread/thread.hpp>
+#include <new>
+#include <cstdlib>
+#include <boost/detail/lightweight_test.hpp>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+
+ void operator()(int i, double j)
+ {
+ BOOST_TEST(alive_ == 1);
+ BOOST_TEST(n_alive == 1);
+ BOOST_TEST(i == 5);
+ BOOST_TEST(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(!G::op_run);
+ boost::thread t0(G(), 5, 5.5);
+ boost::thread::id id = t0.get_id();
+ boost::thread t1( (t0));
+ BOOST_TEST(t1.get_id() == id);
+ BOOST_TEST(t0.get_id() == boost::thread::id());
+ t1.join();
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(G::op_run);
+ }
+}
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
+
+ (void)boost::system::posix_category;
+ (void)boost::system::errno_ecat;
+ (void)boost::system::native_ecat;
+
+}
diff --git a/libs/thread/test/threads/thread/constr/default_pass.cpp b/libs/thread/test/threads/thread/constr/default_pass.cpp
new file mode 100644
index 0000000000..9270e89c04
--- /dev/null
+++ b/libs/thread/test/threads/thread/constr/default_pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// thread();
+
+#include <boost/thread/thread.hpp>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::thread t;
+ BOOST_TEST(t.get_id() == boost::thread::id());
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/threads/thread/constr/move_pass.cpp b/libs/thread/test/threads/thread/constr/move_pass.cpp
new file mode 100644
index 0000000000..b97b49656d
--- /dev/null
+++ b/libs/thread/test/threads/thread/constr/move_pass.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// thread(thread&& t);
+
+#include <boost/thread/thread.hpp>
+#include <new>
+#include <cstdlib>
+#include <boost/detail/lightweight_test.hpp>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+
+ void operator()(int i, double j)
+ {
+ BOOST_TEST(alive_ == 1);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << n_alive << std::endl;
+ BOOST_TEST(n_alive == 1);
+ BOOST_TEST(i == 5);
+ BOOST_TEST(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+boost::thread make_thread() {
+ return boost::thread(G(), 5, 5.5);
+}
+
+int main()
+{
+ {
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(!G::op_run);
+ boost::thread t0((G()));
+ boost::thread::id id = t0.get_id();
+ boost::thread t1((boost::move(t0)));
+ BOOST_TEST(t1.get_id() == id);
+ BOOST_TEST(t0.get_id() == boost::thread::id());
+ t1.join();
+ BOOST_TEST(G::op_run);
+ }
+ BOOST_TEST(G::n_alive == 0);
+ {
+ boost::thread t1((BOOST_THREAD_MAKE_RV_REF(make_thread())));
+ t1.join();
+ BOOST_TEST(G::op_run);
+ }
+ BOOST_TEST(G::n_alive == 0);
+ return boost::report_errors();
+}
diff --git a/libs/thread/test/threads/thread/destr/dtor_pass.cpp b/libs/thread/test/threads/thread/destr/dtor_pass.cpp
new file mode 100644
index 0000000000..a5c62cf424
--- /dev/null
+++ b/libs/thread/test/threads/thread/destr/dtor_pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// ~thread();
+
+#define BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
+
+#include <boost/thread/thread.hpp>
+#include <new>
+#include <cstdlib>
+#include <boost/detail/lightweight_test.hpp>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+void f1()
+{
+ std::exit(boost::report_errors());
+}
+
+int main()
+{
+ std::set_terminate(f1);
+ {
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(!G::op_run);
+ boost::thread t( (G()));
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(250));
+#endif
+ BOOST_TEST(t.joinable());
+ }
+ BOOST_TEST(false);
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/threads/thread/id/hash_pass.cpp b/libs/thread/test/threads/thread/id/hash_pass.cpp
new file mode 100644
index 0000000000..5202d46be8
--- /dev/null
+++ b/libs/thread/test/threads/thread/id/hash_pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// <functional>
+
+// template <class T>
+// struct hash
+// : public unary_function<T, size_t>
+// {
+// size_t operator()(T val) const;
+// };
+
+
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ boost::thread::id id1;
+ boost::thread::id id2 = boost::this_thread::get_id();
+ typedef boost::hash<boost::thread::id> H;
+ H h;
+ BOOST_TEST(h(id1) != h(id2));
+ }
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/threads/thread/members/detach_pass.cpp b/libs/thread/test/threads/thread/members/detach_pass.cpp
new file mode 100644
index 0000000000..7170416d5b
--- /dev/null
+++ b/libs/thread/test/threads/thread/members/detach_pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// void detach();
+
+#include <boost/thread/thread.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.detach();
+ BOOST_TEST(!t0.joinable());
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(250));
+ BOOST_TEST(G::op_run);
+ BOOST_TEST(G::n_alive == 0);
+#endif
+ }
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/threads/thread/members/get_id_pass.cpp b/libs/thread/test/threads/thread/members/get_id_pass.cpp
new file mode 100644
index 0000000000..02c0e34a12
--- /dev/null
+++ b/libs/thread/test/threads/thread/members/get_id_pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// id get_id() const;
+
+#include <boost/thread/thread.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ //boost::thread::id id0 = t0.get_id();
+ boost::thread t1;
+ boost::thread::id id1 = t1.get_id();
+ BOOST_TEST(t0.get_id() != id1);
+ BOOST_TEST(t1.get_id() == boost::thread::id());
+ t0.join();
+ }
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/threads/thread/members/join_pass.cpp b/libs/thread/test/threads/thread/members/join_pass.cpp
new file mode 100644
index 0000000000..72977be0de
--- /dev/null
+++ b/libs/thread/test/threads/thread/members/join_pass.cpp
@@ -0,0 +1,151 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// void join();
+
+#define BOOST_THREAD_VESRION 3
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << n_alive << std::endl;
+ BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+boost::thread* resource_deadlock_would_occur_th;
+boost::mutex resource_deadlock_would_occur_mtx;
+void resource_deadlock_would_occur_tester()
+{
+ try
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+
+ resource_deadlock_would_occur_th->join();
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ BOOST_TEST(false);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ }
+ catch (boost::system::system_error& e)
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ catch (...)
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ BOOST_TEST(false&&"exception thrown");
+ }
+}
+
+int main()
+{
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.join();
+ BOOST_TEST(!t0.joinable());
+ }
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ boost::thread t0( resource_deadlock_would_occur_tester );
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ resource_deadlock_would_occur_th = &t0;
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ BOOST_TEST(t0.joinable());
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ lk.unlock();
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ t0.join();
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ BOOST_TEST(!t0.joinable());
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << std::endl;
+ }
+
+// {
+// boost::thread t0( (G()));
+// t0.detach();
+// try
+// {
+// t0.join();
+// BOOST_TEST(false);
+// }
+// catch (boost::system::system_error& e)
+// {
+// BOOST_TEST(e.code().value() == boost::system::errc::no_such_process);
+// }
+// }
+// {
+// boost::thread t0( (G()));
+// BOOST_TEST(t0.joinable());
+// t0.join();
+// BOOST_TEST(!t0.joinable());
+// try
+// {
+// t0.join();
+// BOOST_TEST(false);
+// }
+// catch (boost::system::system_error& e)
+// {
+// BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+// }
+//
+// }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/threads/thread/members/joinable_pass.cpp b/libs/thread/test/threads/thread/members/joinable_pass.cpp
new file mode 100644
index 0000000000..60a6db76f6
--- /dev/null
+++ b/libs/thread/test/threads/thread/members/joinable_pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// bool joinable() const;
+
+#include <boost/thread/thread.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.join();
+ BOOST_TEST(!t0.joinable());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/threads/thread/members/native_handle_pass.cpp b/libs/thread/test/threads/thread/members/native_handle_pass.cpp
new file mode 100644
index 0000000000..c35e9a8c2e
--- /dev/null
+++ b/libs/thread/test/threads/thread/members/native_handle_pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// native_handle_type native_handle();
+
+#include <boost/thread/thread.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ // boost::thread::native_handle_type hdl =
+ (void)t0.native_handle();
+ t0.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/threads/thread/members/swap_pass.cpp b/libs/thread/test/threads/thread/members/swap_pass.cpp
new file mode 100644
index 0000000000..6a8d590015
--- /dev/null
+++ b/libs/thread/test/threads/thread/members/swap_pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// native_handle_type native_handle();
+
+#include <boost/thread/thread.hpp>
+#include <cstdlib>
+#include <boost/detail/lightweight_test.hpp>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ std::cout << n_alive << std::endl;
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ boost::thread::id id0 = t0.get_id();
+ boost::thread t1;
+ boost::thread::id id1 = t1.get_id();
+ t0.swap(t1);
+ BOOST_TEST(t0.get_id() == id1);
+ BOOST_TEST(t1.get_id() == id0);
+ t1.join();
+ return boost::report_errors();
+ }
+}
+
diff --git a/libs/thread/test/threads/thread/non_members/swap_pass.cpp b/libs/thread/test/threads/thread/non_members/swap_pass.cpp
new file mode 100644
index 0000000000..dd05d61e5e
--- /dev/null
+++ b/libs/thread/test/threads/thread/non_members/swap_pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// void swap(thread& x, thread& y);
+
+#include <boost/thread/thread.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ ++n_alive;
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ boost::thread::id id0 = t0.get_id();
+ boost::thread t1;
+ boost::thread::id id1 = t1.get_id();
+ swap(t0, t1);
+ BOOST_TEST(t0.get_id() == id1);
+ BOOST_TEST(t1.get_id() == id0);
+ t1.join();
+ }
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/threads/thread/static/hardware_concurrency_pass.cpp b/libs/thread/test/threads/thread/static/hardware_concurrency_pass.cpp
new file mode 100644
index 0000000000..7d1581b520
--- /dev/null
+++ b/libs/thread/test/threads/thread/static/hardware_concurrency_pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// static unsigned hardware_concurrency();
+
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_TEST(boost::thread::hardware_concurrency() > 0);
+ return boost::report_errors();
+}
+
diff --git a/libs/thread/test/util.inl b/libs/thread/test/util.inl
index 5c761d506d..b85fbb08d8 100644
--- a/libs/thread/test/util.inl
+++ b/libs/thread/test/util.inl
@@ -19,6 +19,8 @@
// boostinspect:nounnamed
+
+
namespace
{
inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
@@ -28,8 +30,8 @@ inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
const int NANOSECONDS_PER_MILLISECOND = 1000000;
boost::xtime xt;
- if (boost::TIME_UTC != boost::xtime_get (&xt, boost::TIME_UTC))
- BOOST_ERROR ("boost::xtime_get != boost::TIME_UTC");
+ if (boost::TIME_UTC_ != boost::xtime_get (&xt, boost::TIME_UTC_))
+ BOOST_ERROR ("boost::xtime_get != boost::TIME_UTC_");
nsecs += xt.nsec;
msecs += nsecs / NANOSECONDS_PER_MILLISECOND;
@@ -41,6 +43,13 @@ inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
return xt;
}
+}
+namespace boost
+{
+namespace threads
+{
+namespace test
+{
inline bool in_range(const boost::xtime& xt, int secs=1)
{
boost::xtime min = delay(-secs);
@@ -48,7 +57,13 @@ inline bool in_range(const boost::xtime& xt, int secs=1)
return (boost::xtime_cmp(xt, min) >= 0) &&
(boost::xtime_cmp(xt, max) <= 0);
}
+}
+}
+}
+
+namespace
+{
class execution_monitor
{
public:
@@ -98,7 +113,9 @@ private:
wait_type type;
int secs;
};
-
+}
+namespace thread_detail_anon
+{
template <typename F>
class indirect_adapter
{
@@ -126,18 +143,28 @@ private:
void operator=(indirect_adapter&);
};
+}
+// boostinspect:nounnamed
+namespace
+{
+
template <typename F>
void timed_test(F func, int secs,
execution_monitor::wait_type type=DEFAULT_EXECUTION_MONITOR_TYPE)
{
execution_monitor monitor(type, secs);
- indirect_adapter<F> ifunc(func, monitor);
+ thread_detail_anon::indirect_adapter<F> ifunc(func, monitor);
monitor.start();
boost::thread thrd(ifunc);
BOOST_REQUIRE_MESSAGE(monitor.wait(),
"Timed test didn't complete in time, possible deadlock.");
}
+}
+
+namespace thread_detail_anon
+{
+
template <typename F, typename T>
class thread_binder
{
@@ -151,11 +178,20 @@ private:
T param;
};
+}
+
+// boostinspect:nounnamed
+namespace
+{
template <typename F, typename T>
-thread_binder<F, T> bind(const F& func, const T& param)
+thread_detail_anon::thread_binder<F, T> bind(const F& func, const T& param)
{
- return thread_binder<F, T>(func, param);
+ return thread_detail_anon::thread_binder<F, T>(func, param);
}
+}
+
+namespace thread_detail_anon
+{
template <typename R, typename T>
class thread_member_binder
@@ -172,11 +208,15 @@ private:
T& param;
};
+}
+// boostinspect:nounnamed
+namespace
+{
template <typename R, typename T>
-thread_member_binder<R, T> bind(R (T::*func)(), T& param)
+thread_detail_anon::thread_member_binder<R, T> bind(R (T::*func)(), T& param)
{
- return thread_member_binder<R, T>(func, param);
+ return thread_detail_anon::thread_member_binder<R, T>(func, param);
}
} // namespace
diff --git a/libs/thread/tutorial/helloworld4.cpp b/libs/thread/tutorial/helloworld4.cpp
deleted file mode 100644
index cd43987f58..0000000000
--- a/libs/thread/tutorial/helloworld4.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (C) 2001-2003
-// William E. Kempf
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#include <boost/thread/thread.hpp>
-#include <boost/bind.hpp>
-#include <iostream>
-
-void helloworld(const char* who)
-{
- std::cout << who << "says, \"Hello World.\"" << std::endl;
-}
-
-int main()
-{
- boost::thread thrd(boost::bind(&helloworld, "Bob"));
- thrd.join();
-}