mutex_concepts.qbk 101 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235
  1. [/
  2. (C) Copyright 2007-8 Anthony Williams.
  3. (C) Copyright 2011-12 Vicente J. Botet Escriba.
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt).
  7. ]
  8. [section:mutex_concepts Mutex Concepts]
  9. A mutex object facilitates protection against data races and allows thread-safe synchronization of data between threads. A thread
  10. obtains ownership of a mutex object by calling one of the lock functions and relinquishes ownership by calling the corresponding
  11. unlock function. Mutexes may be either recursive or non-recursive, and may grant simultaneous ownership to one or many
  12. threads. __boost_thread__ supplies recursive and non-recursive mutexes with exclusive ownership semantics, along with a shared
  13. ownership (multiple-reader / single-writer) mutex.
  14. __boost_thread__ supports four basic concepts for lockable objects: __lockable_concept_type__, __timed_lockable_concept_type__,
  15. __shared_lockable_concept_type__ and __upgrade_lockable_concept_type__. Each mutex type implements one or more of these concepts, as
  16. do the various lock types.
  17. [section:basic_lockable `BasicLockable` Concept]
  18. // #include <boost/thread/lockable_concepts.hpp>
  19. namespace boost
  20. {
  21. template<typename L>
  22. class BasicLockable; // EXTENSION
  23. }
  24. The __BasicLockable concept models exclusive ownership.
  25. A type `L` meets the __BasicLockable requirements if the following expressions are well-formed and have the specified semantics (`m` denotes a value of type `L`):
  26. * `m.__lock();`
  27. * `m.__unlock();`
  28. Lock ownership acquired through a call to __lock_ref__ must be released through a call to __unlock_ref__.
  29. [section:lock `m.lock();`]
  30. [variablelist
  31. [[Requires:] [The calling thread doesn't owns the mutex if the mutex is not recursive.]]
  32. [[Effects:] [The current thread blocks until ownership can be obtained for the current thread.]]
  33. [[Synchronization:] [Prior `unlock()` operations on the same object synchronizes with this operation. ]]
  34. [[Postcondition:] [The current thread owns `m`.]]
  35. [[Return type:] [`void`.]]
  36. [[Throws:] [__lock_error__ if an error occurs.]]
  37. [[Error Conditions:] [
  38. [*operation_not_permitted]: if the thread does not have the privilege to perform the operation.
  39. [*resource_deadlock_would_occur]: if the implementation detects that a deadlock would occur.
  40. [*device_or_resource_busy]: if the mutex is already locked and blocking is not possible.
  41. ]]
  42. [[Thread safety:] [If an exception is thrown then a lock shall not have been acquired for the current thread.]]
  43. ]
  44. [endsect]
  45. [section:unlock `m.unlock();`]
  46. [variablelist
  47. [[Requires:] [The current thread owns `m`.]]
  48. [[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership on the same object.]]
  49. [[Effects:] [Releases a lock on `m` by the current thread.]]
  50. [[Return type:] [`void`.]]
  51. [[Throws:] [Nothing.]]
  52. ]
  53. [endsect]
  54. [section:is_basic_lockable `is_basic_lockable` trait -- EXTENSION]
  55. // #include <boost/thread/lockable_traits.hpp>
  56. namespace boost
  57. {
  58. namespace sync
  59. {
  60. template<typename L>
  61. class is_basic_lockable;// EXTENSION
  62. }
  63. }
  64. Some of the algorithms on mutexes use this trait via SFINAE.
  65. This trait is true_type if the parameter L meets the __Lockable requirements.
  66. [warning If BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES is defined you will need to specialize this traits for the models of BasicLockable you could build.]
  67. [endsect]
  68. [endsect]
  69. [section:lockable `Lockable` Concept]
  70. // #include <boost/thread/lockable_concepts.hpp>
  71. namespace boost
  72. {
  73. template<typename L>
  74. class Lockable;
  75. }
  76. A type `L` meets the __Lockable requirements if it meets the __BasicLockable requirements and the following expressions are well-formed and have the specified semantics (`m` denotes a value of type `L`):
  77. * `m.__try_lock()`
  78. Lock ownership acquired through a call to __try_lock_ref__ must be released through a call to __unlock_ref__.
  79. [section:try_lock `m.try_lock()`]
  80. [variablelist
  81. [[Requires:] [The calling thread doesn't owns the mutex if the mutex is not recursive.]]
  82. [[Effects:] [Attempt to obtain ownership for the current thread without blocking.]]
  83. [[Synchronization:] [If `try_lock()` returns true, prior `unlock()` operations on the same object synchronize with this operation.]]
  84. [[Note:] [Since `lock()` does not synchronize with a failed subsequent
  85. `try_lock()`, the visibility rules are weak enough that little would be known about the state after a
  86. failure, even in the absence of spurious failures.]]
  87. [[Return type:] [`bool`.]]
  88. [[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]]
  89. [[Postcondition:] [If the call returns `true`, the current thread owns the `m`.]]
  90. [[Throws:] [Nothing.]]
  91. ]
  92. [endsect]
  93. [section:is_lockable `is_lockable` trait -- EXTENSION]
  94. // #include <boost/thread/lockable_traits.hpp>
  95. namespace boost
  96. {
  97. namespace sync
  98. {
  99. template<typename L>
  100. class is_lockable;// EXTENSION
  101. }
  102. }
  103. Some of the algorithms on mutexes use this trait via SFINAE.
  104. This trait is true_type if the parameter L meets the __Lockable requirements.
  105. [warning If BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES is defined you will need to specialize this traits for the models of Lockable you could build.]
  106. [endsect]
  107. [endsect]
  108. [section:recursive Recursive Lockable Concept]
  109. The user could require that the mutex passed to an algorithm is a recursive one. Whether a lockable is recursive or not can not be checked using template meta-programming. This is the motivation for the following trait.
  110. [section:is_recursive_mutex_sur_parole `is_recursive_mutex_sur_parole` trait -- EXTENSION]
  111. // #include <boost/thread/lockable_traits.hpp>
  112. namespace boost
  113. {
  114. namespace sync
  115. {
  116. template<typename L>
  117. class is_recursive_mutex_sur_parole: false_type; // EXTENSION
  118. template<>
  119. class is_recursive_mutex_sur_parole<recursive_mutex>: true_type; // EXTENSION
  120. template<>
  121. class is_recursive_mutex_sur_parole<timed_recursive_mutex>: true_type; // EXTENSION
  122. }
  123. }
  124. The trait `is_recursive_mutex_sur_parole` is `false_type` by default and is specialized for the provide `recursive_mutex` and `timed_recursive_mutex`.
  125. It should be specialized by the user providing other model of recursive lockable.
  126. [endsect]
  127. [section:is_recursive_basic_lockable `is_recursive_basic_lockable` trait -- EXTENSION]
  128. // #include <boost/thread/lockable_traits.hpp>
  129. namespace boost
  130. {
  131. namespace sync
  132. {
  133. template<typename L>
  134. class is_recursive_basic_lockable;// EXTENSION
  135. }
  136. }
  137. This traits is true_type if is_basic_lockable and is_recursive_mutex_sur_parole.
  138. [endsect]
  139. [section:is_recursive_lockable `is_recursive_lockable` trait -- EXTENSION]
  140. // #include <boost/thread/lockable_traits.hpp>
  141. namespace boost
  142. {
  143. namespace sync
  144. {
  145. template<typename L>
  146. class is_recursive_lockable;// EXTENSION
  147. }
  148. }
  149. This traits is true_type if is_lockable and is_recursive_mutex_sur_parole.
  150. [endsect]
  151. [endsect]
  152. [section:timed_lockable `TimedLockable` Concept]
  153. // #include <boost/thread/lockable_concepts.hpp>
  154. namespace boost
  155. {
  156. template<typename L>
  157. class TimedLockable; // EXTENSION
  158. }
  159. The __timed_lockable_concept__ refines the __lockable_concept__ to add support for
  160. timeouts when trying to acquire the lock.
  161. 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.
  162. [*Variables:]
  163. * `m` denotes a value of type `L`,
  164. * `rel_time` denotes a value of an instantiation of `chrono::duration`, and
  165. * `abs_time` denotes a value of an instantiation of `chrono::time_point`:
  166. [*Expressions:]
  167. * `m.__try_lock_for(rel_time)`
  168. * `m.__try_lock_until(abs_time)`
  169. Lock ownership acquired through a call to __try_lock_for or __try_lock_until must be released through a call to __unlock.
  170. [section:try_lock_until `m.try_lock_until(abs_time)`]
  171. [variablelist
  172. [[Requires:] [The calling thread doesn't owns the mutex if the mutex is not recursive.]]
  173. [[Effects:] [Attempt to obtain ownership for the current thread. Blocks until ownership can be obtained, or the specified time is
  174. reached. If the specified time has already passed, behaves as __try_lock_ref__.]]
  175. [[Synchronization:] [If `try_lock_until()` returns true, prior `unlock()` operations on the same object synchronize with this operation.]]
  176. [[Return type:] [`bool`.]]
  177. [[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]]
  178. [[Postcondition:] [If the call returns `true`, the current thread owns `m`.]]
  179. [[Throws:] [Nothing.]]
  180. ]
  181. [endsect]
  182. [section:try_lock_for `m.try_lock_for(rel_time)`]
  183. [variablelist
  184. [[Requires:] [The calling thread doesn't owns the mutex if the mutex is not recursive.]]
  185. [[Effects:] [As-if `__try_lock_until(chrono::steady_clock::now() + rel_time)`.]]
  186. [[Synchronization:] [If `try_lock_for()` returns true, prior `unlock()` operations on the same object synchronize with this operation.]]
  187. ]
  188. [endsect]
  189. [warning
  190. DEPRECATED since 4.00. The following expressions were required on version 2, but are now deprecated.
  191. Use instead __try_lock_for, __try_lock_until.
  192. ]
  193. [*Variables:]
  194. * `rel_time` denotes a value of an instantiation of an unspecified `DurationType` arithmetic compatible with `boost::system_time`, and
  195. * `abs_time` denotes a value of an instantiation of `boost::system_time`:
  196. [*Expressions:]
  197. * `m.__timed_lock_duration(rel_time)`
  198. * `m.__timed_lock(abs_time)`
  199. Lock ownership acquired through a call to __timed_lock_ref__ must be released through a call to __unlock_ref__.
  200. [section:timed_lock `m.timed_lock(abs_time)`]
  201. [variablelist
  202. [[Effects:] [Attempt to obtain ownership for the current thread. Blocks until ownership can be obtained, or the specified time is
  203. reached. If the specified time has already passed, behaves as __try_lock_ref__.]]
  204. [[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]]
  205. [[Postcondition:] [If the call returns `true`, the current thread owns `m`.]]
  206. [[Throws:] [__lock_error__ if an error occurs.]]
  207. ]
  208. [endsect]
  209. [section:timed_lock_duration `m.timed_lock(rel_time)`]
  210. [variablelist
  211. [[Effects:] [As-if [timed_lock_ref_link
  212. `timed_lock(boost::get_system_time()+rel_time)`].]]
  213. ]
  214. [endsect]
  215. [endsect]
  216. [section:shared_lockable `SharedLockable` Concept -- C++14]
  217. // #include <boost/thread/lockable_concepts.hpp>
  218. namespace boost
  219. {
  220. template<typename L>
  221. class SharedLockable; // C++14
  222. }
  223. The __shared_lockable_concept__ is a refinement of the __timed_lockable_concept__ that
  224. allows for ['shared ownership] as well as ['exclusive ownership]. This is the
  225. standard multiple-reader / single-write model: at most one thread can have
  226. exclusive ownership, and if any thread does have exclusive ownership, no other threads
  227. can have shared or exclusive ownership. Alternatively, many threads may have
  228. shared ownership.
  229. 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.
  230. [*Variables:]
  231. * `m` denotes a value of type `L`,
  232. * `rel_time` denotes a value of an instantiation of `chrono::duration`, and
  233. * `abs_time` denotes a value of an instantiation of `chrono::time_point`:
  234. [*Expressions:]
  235. * `m.__lock_shared();`
  236. * `m.__try_lock_shared()`
  237. * `m.__try_lock_shared_for(rel_time)`
  238. * `m.__try_lock_shared_until(abs_time)`
  239. * `m.__unlock_shared();`
  240. 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__.
  241. [section:lock_shared `m.lock_shared()`]
  242. [variablelist
  243. [[Effects:] [The current thread blocks until shared ownership can be obtained for the current thread.]]
  244. [[Postcondition:] [The current thread has shared ownership of `m`.]]
  245. [[Throws:] [__lock_error__ if an error occurs.]]
  246. ]
  247. [endsect]
  248. [section:try_lock_shared `m.try_lock_shared()`]
  249. [variablelist
  250. [[Effects:] [Attempt to obtain shared ownership for the current thread without blocking.]]
  251. [[Returns:] [`true` if shared ownership was obtained for the current thread, `false` otherwise.]]
  252. [[Postcondition:] [If the call returns `true`, the current thread has shared ownership of `m`.]]
  253. [[Throws:] [__lock_error__ if an error occurs.]]
  254. ]
  255. [endsect]
  256. [section:try_lock_shared_for `m.try_lock_shared_for(rel_time)`]
  257. [variablelist
  258. [[Effects:] [Attempt to obtain shared ownership for the current thread. Blocks until shared ownership can be obtained, or the
  259. specified duration is elapsed. If the specified duration is already elapsed, behaves as __try_lock_shared_ref__.]]
  260. [[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]]
  261. [[Postcondition:] [If the call returns `true`, the current thread has shared
  262. ownership of `m`.]]
  263. [[Throws:] [__lock_error__ if an error occurs.]]
  264. ]
  265. [endsect]
  266. [section:try_lock_shared_until `m.try_lock_shared_until(abs_time))`]
  267. [variablelist
  268. [[Effects:] [Attempt to obtain shared ownership for the current thread. Blocks until shared ownership can be obtained, or the
  269. specified time is reached. If the specified time has already passed, behaves as __try_lock_shared_ref__.]]
  270. [[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]]
  271. [[Postcondition:] [If the call returns `true`, the current thread has shared
  272. ownership of `m`.]]
  273. [[Throws:] [__lock_error__ if an error occurs.]]
  274. ]
  275. [endsect]
  276. [section:unlock_shared `m.unlock_shared()`]
  277. [variablelist
  278. [[Precondition:] [The current thread has shared ownership of `m`.]]
  279. [[Effects:] [Releases shared ownership of `m` by the current thread.]]
  280. [[Postcondition:] [The current thread no longer has shared ownership of `m`.]]
  281. [[Throws:] [Nothing]]
  282. ]
  283. [endsect]
  284. [warning
  285. DEPRECATED since 3.00. The following expressions were required on version 2, but are now deprecated.
  286. Use instead __try_lock_shared_for, __try_lock_shared_until.
  287. ]
  288. [*Variables:]
  289. * `abs_time` denotes a value of an instantiation of `boost::system_time`:
  290. [*Expressions:]
  291. * `m.timed_lock_shared(abs_time);`
  292. Lock ownership acquired through a call to __timed_lock_shared_ref__ must be released through a call to __unlock_shared_ref__.
  293. [section:timed_lock_shared `m.timed_lock_shared(abs_time)`]
  294. [variablelist
  295. [[Effects:] [Attempt to obtain shared ownership for the current thread. Blocks until shared ownership can be obtained, or the
  296. specified time is reached. If the specified time has already passed, behaves as __try_lock_shared_ref__.]]
  297. [[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]]
  298. [[Postcondition:] [If the call returns `true`, the current thread has shared
  299. ownership of `m`.]]
  300. [[Throws:] [__lock_error__ if an error occurs.]]
  301. ]
  302. [endsect]
  303. [endsect]
  304. [section:upgrade_lockable `UpgradeLockable` Concept -- EXTENSION]
  305. // #include <boost/thread/lockable_concepts.hpp>
  306. namespace boost
  307. {
  308. template<typename L>
  309. class UpgradeLockable; // EXTENSION
  310. }
  311. The __upgrade_lockable_concept__ is a refinement of the __shared_lockable_concept__ that allows for ['upgradable ownership] as well
  312. as ['shared ownership] and ['exclusive ownership]. This is an extension to the multiple-reader / single-write model provided by the
  313. __shared_lockable_concept__: a single thread may have ['upgradable ownership] at the same time as others have ['shared
  314. ownership]. The thread with ['upgradable ownership] may at any time attempt to upgrade that ownership to ['exclusive ownership]. If
  315. no other threads have shared ownership, the upgrade is completed immediately, and the thread now has ['exclusive ownership], which
  316. must be relinquished by a call to __unlock_ref__, just as if it had been acquired by a call to __lock_ref__.
  317. If a thread with ['upgradable ownership] tries to upgrade whilst other threads have ['shared ownership], the attempt will fail and
  318. the thread will block until ['exclusive ownership] can be acquired.
  319. Ownership can also be ['downgraded] as well as ['upgraded]: exclusive ownership of an implementation of the
  320. __upgrade_lockable_concept__ can be downgraded to upgradable ownership or shared ownership, and upgradable ownership can be
  321. downgraded to plain shared ownership.
  322. A type `L` meets the __UpgradeLockable requirements if it meets the __SharedLockable
  323. requirements and the following expressions are well-formed and have the specified semantics.
  324. [*Variables:]
  325. * `m` denotes a value of type `L`,
  326. * `rel_time` denotes a value of an instantiation of `chrono::duration`, and
  327. * `abs_time` denotes a value of an instantiation of `chrono::time_point`:
  328. [*Expressions:]
  329. * `m.__lock_upgrade();`
  330. * `m.__unlock_upgrade()`
  331. * `m.__try_lock_upgrade()`
  332. * `m.__try_lock_upgrade_for(rel_time)`
  333. * `m.__try_lock_upgrade_until(abs_time)`
  334. * `m.__unlock_and_lock_shared()`
  335. * `m.__unlock_and_lock_upgrade();`
  336. * `m.__unlock_upgrade_and_lock();`
  337. * `m.__try_unlock_upgrade_and_lock()`
  338. * `m.__try_unlock_upgrade_and_lock_for(rel_time)`
  339. * `m.__try_unlock_upgrade_and_lock_until(abs_time)`
  340. * `m.__unlock_upgrade_and_lock_shared();`
  341. If `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS is defined the following expressions are also required:
  342. * `m.__try_unlock_shared_and_lock();`
  343. * `m.__try_unlock_shared_and_lock_for(rel_time);`
  344. * `m.__try_unlock_shared_and_lock_until(abs_time);`
  345. * `m.__try_unlock_shared_and_lock_upgrade();`
  346. * `m.__try_unlock_shared_and_lock_upgrade_for(rel_time);`
  347. * `m.__try_unlock_shared_and_lock_upgrade_until(abs_time);`
  348. Lock ownership acquired through a call to __lock_upgrade_ref__ must be released through a call to __unlock_upgrade_ref__. If the
  349. ownership type is changed through a call to one of the `unlock_xxx_and_lock_yyy()` functions, ownership must be released through a
  350. call to the unlock function corresponding to the new level of ownership.
  351. [section:lock_upgrade `m.lock_upgrade()`]
  352. [variablelist
  353. [[Precondition:] [The calling thread has no ownership of the mutex. ]]
  354. [[Effects:] [The current thread blocks until upgrade ownership can be obtained for the current thread.]]
  355. [[Postcondition:] [The current thread has upgrade ownership of `m`.]]
  356. [[Synchronization:] [Prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]]
  357. [[Throws:] [__lock_error__ if an error occurs.]]
  358. ]
  359. [endsect]
  360. [section:unlock_upgrade `m.unlock_upgrade()`]
  361. [variablelist
  362. [[Precondition:] [The current thread has upgrade ownership of `m`.]]
  363. [[Effects:] [Releases upgrade ownership of `m` by the current thread.]]
  364. [[Postcondition:] [The current thread no longer has upgrade ownership of `m`.]]
  365. [[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership on the same object.]]
  366. [[Throws:] [Nothing]]
  367. ]
  368. [endsect]
  369. [section:try_lock_upgrade `m.try_lock_upgrade()`]
  370. [variablelist
  371. [[Precondition:] [The calling thread has no ownership of the mutex. ]]
  372. [[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.]]
  373. [[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
  374. [[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
  375. [[Synchronization:] [If `__try_lock_upgrade()` returns true, prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]]
  376. [[Throws:] [Nothing]]
  377. ]
  378. [endsect]
  379. [section:try_lock_upgrade_for `m.try_lock_upgrade_for(rel_time)`]
  380. [variablelist
  381. [[Precondition:] [The calling thread has no ownership of the mutex. ]]
  382. [[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.
  383. Attempts to obtain upgrade lock ownership for the calling thread within the relative timeout specified by `rel_time`.
  384. 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()`).
  385. The function returns within the timeout specified by `rel_time` only if it has obtained upgrade ownership of the mutex object.]]
  386. [[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
  387. [[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
  388. [[Synchronization:] [If `__try_lock_upgrade_for(rel_time)` returns true, prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]]
  389. [[Throws:] [Nothing]]
  390. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  391. ]
  392. [endsect]
  393. [section:try_lock_upgrade_until `m.try_lock_upgrade_until(abs_time)`]
  394. [variablelist
  395. [[Precondition:] [The calling thread has no ownership of the mutex. ]]
  396. [[Effects:] [The function attempts to obtain upgrade ownership of the mutex.
  397. If `abs_time` has already passed, the function attempts to obtain upgrade ownership without blocking (as if by calling `__try_lock_upgrade()`).
  398. The function returns before the absolute timeout specified by `abs_time` only if it has obtained upgrade ownership of the mutex object.]]
  399. [[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
  400. [[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
  401. [[Synchronization:] [If `__try_lock_upgrade_until(abs_time)` returns true, prior `__unlock_upgrade()` operations on the same object synchronize with this operation.]]
  402. [[Throws:] [Nothing]]
  403. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  404. ]
  405. [endsect]
  406. [section:try_unlock_shared_and_lock `m.try_unlock_shared_and_lock()`]
  407. [variablelist
  408. [[Precondition:] [The calling thread must hold a shared lock on the mutex.]]
  409. [[Effects:] [The function attempts to atomically convert the ownership from shared to exclusive for the calling thread without blocking.
  410. For this conversion to be successful, this thread must be the only thread holding any ownership of the lock.
  411. If the conversion is not successful, the shared ownership of m is retained.]]
  412. [[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
  413. [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
  414. [[Synchronization:] [If `__try_unlock_shared_and_lock()` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
  415. [[Throws:] [Nothing]]
  416. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  417. ]
  418. [endsect]
  419. [section:try_unlock_shared_and_lock_for `m.try_unlock_shared_and_lock_for(rel_time)`]
  420. [variablelist
  421. [[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
  422. [[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.
  423. The function attempts to atomically convert the ownership from shared to exclusive for the calling thread within the relative timeout specified by `rel_time`.
  424. 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()`).
  425. The function shall return within the timeout specified by `rel_time` only if it has obtained exclusive ownership of the mutex object.
  426. For this conversion to be successful, this thread must be the only thread holding any ownership of the lock at the moment of conversion.
  427. If the conversion is not successful, the shared ownership of the mutex is retained.]]
  428. [[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
  429. [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
  430. [[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. ]]
  431. [[Throws:] [Nothing]]
  432. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  433. ]
  434. [endsect]
  435. [section:try_unlock_shared_and_lock_until `m.try_unlock_shared_and_lock_until(abs_time)`]
  436. [variablelist
  437. [[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
  438. [[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`.
  439. If `abs_time` has already passed, the function attempts to obtain exclusive ownership without blocking (as if by calling `try_unlock_shared_and_lock()`).
  440. The function shall return before the absolute timeout specified by `abs_time` only if it has obtained exclusive ownership of the mutex object.
  441. For this conversion to be successful, this thread must be the only thread holding any ownership of the lock at the moment of conversion.
  442. If the conversion is not successful, the shared ownership of the mutex is retained.]]
  443. [[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
  444. [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
  445. [[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. ]]
  446. [[Throws:] [Nothing]]
  447. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  448. ]
  449. [endsect]
  450. [section:unlock_and_lock_shared `m.unlock_and_lock_shared()`]
  451. [variablelist
  452. [[Precondition:] [The calling thread shall hold an exclusive lock on `m`.]]
  453. [[Effects:] [Atomically converts the ownership from exclusive to shared for the calling thread.]]
  454. [[Postcondition:] [The current thread has shared ownership of `m`.]]
  455. [[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership of the same object.]]
  456. [[Throws:] [Nothing]]
  457. ]
  458. [endsect]
  459. [section:try_unlock_shared_and_lock_upgrade `m.try_unlock_shared_and_lock_upgrade()`]
  460. [variablelist
  461. [[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
  462. [[Effects:] [The function attempts to atomically convert the ownership from shared to upgrade for the calling thread without blocking.
  463. For this conversion to be successful, there must be no thread holding upgrade ownership of this object.
  464. If the conversion is not successful, the shared ownership of the mutex is retained.]]
  465. [[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
  466. [[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
  467. [[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. ]]
  468. [[Throws:] [Nothing]]
  469. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  470. ]
  471. [endsect]
  472. [section:try_unlock_shared_and_lock_upgrade_for `m.try_unlock_shared_and_lock_upgrade_for(rel_time)`]
  473. [variablelist
  474. [[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
  475. [[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.
  476. The function attempts to atomically convert the ownership from shared to upgrade for the calling thread within the relative timeout specified by `rel_time`.
  477. 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()`).
  478. The function shall return within the timeout specified by `rel_time` only if it has obtained exclusive ownership of the mutex object.
  479. For this conversion to be successful, there must be no thread holding upgrade ownership of this object at the moment of conversion.
  480. If the conversion is not successful, the shared ownership of m is retained.]]
  481. [[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
  482. [[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
  483. [[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. ]]
  484. [[Throws:] [Nothing]]
  485. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  486. ]
  487. [endsect]
  488. [section:try_unlock_shared_and_lock_upgrade_until `m.try_unlock_shared_and_lock_upgrade_until(abs_time)`]
  489. [variablelist
  490. [[Precondition:] [The calling thread shall hold a shared lock on the mutex.]]
  491. [[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`.
  492. 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()`).
  493. The function shall return before the absolute timeout specified by `abs_time` only if it has obtained upgrade ownership of the mutex object.
  494. For this conversion to be successful, there must be no thread holding upgrade ownership of this object at the moment of conversion.
  495. If the conversion is not successful, the shared ownership of the mutex is retained.]]
  496. [[Returns:] [`true` if upgrade ownership was acquired for the current thread, `false` otherwise.]]
  497. [[Postcondition:] [If the call returns `true`, the current thread has upgrade ownership of `m`.]]
  498. [[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. ]]
  499. [[Throws:] [Nothing]]
  500. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  501. ]
  502. [endsect]
  503. [section:unlock_and_lock_upgrade `m.unlock_and_lock_upgrade()`]
  504. [variablelist
  505. [[Precondition:] [The current thread has exclusive ownership of `m`.]]
  506. [[Effects:] [Atomically releases exclusive ownership of `m` by the current thread and acquires upgrade ownership of `m`
  507. without blocking.]]
  508. [[Postcondition:] [The current thread has upgrade ownership of `m`.]]
  509. [[Synchronization:] [This operation synchronizes with subsequent lock operations that obtain ownership of the same object.]]
  510. [[Throws:] [Nothing]]
  511. ]
  512. [endsect]
  513. [section:unlock_upgrade_and_lock `m.unlock_upgrade_and_lock()`]
  514. [variablelist
  515. [[Precondition:] [The current thread has upgrade ownership of `m`.]]
  516. [[Effects:] [Atomically releases upgrade ownership of `m` by the current thread and acquires exclusive ownership of `m`. If
  517. any other threads have shared ownership, blocks until exclusive ownership can be acquired.]]
  518. [[Postcondition:] [The current thread has exclusive ownership of `m`.]]
  519. [[Synchronization:] [This operation synchronizes with prior `__unlock_shared()` and subsequent lock operations that obtain ownership of the same object.]]
  520. [[Throws:] [Nothing]]
  521. ]
  522. [endsect]
  523. [section:try_unlock_upgrade_and_lock `m.try_unlock_upgrade_and_lock()`]
  524. [variablelist
  525. [[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
  526. [[Effects:] [The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread without blocking.
  527. For this conversion to be successful, this thread must be the only thread holding any ownership of the lock.
  528. If the conversion is not successful, the upgrade ownership of m is retained.]]
  529. [[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
  530. [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
  531. [[Synchronization:] [If `__try_unlock_upgrade_and_lock()` returns true, prior `__unlock()` and subsequent lock operations on the same object synchronize with this operation. ]]
  532. [[Throws:] [Nothing]]
  533. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  534. ]
  535. [endsect]
  536. [section:try_unlock_upgrade_and_lock_for `m.try_unlock_upgrade_and_lock_for(rel_time)`]
  537. [variablelist
  538. [[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
  539. [[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.
  540. The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread within the relative timeout specified by `rel_time`.
  541. 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()`).
  542. The function shall return within the timeout specified by `rel_time` only if it has obtained exclusive ownership of the mutex object.
  543. For this conversion to be successful, this thread shall be the only thread holding any ownership of the lock at the moment of conversion.
  544. If the conversion is not successful, the upgrade ownership of m is retained.]]
  545. [[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
  546. [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
  547. [[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. ]]
  548. [[Throws:] [Nothing]]
  549. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  550. ]
  551. [endsect]
  552. [section:try_unlock_upgrade_and_lock_until `m.try_unlock_upgrade_and_lock_until(abs_time)`]
  553. [variablelist
  554. [[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
  555. [[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`.
  556. If `abs_time` has already passed, the function attempts to obtain exclusive ownership without blocking (as if by calling `__try_unlock_upgrade_and_lock()`).
  557. The function shall return before the absolute timeout specified by `abs_time` only if it has obtained exclusive ownership of the mutex object.
  558. For this conversion to be successful, this thread shall be the only thread holding any ownership of the lock at the moment of conversion.
  559. If the conversion is not successful, the upgrade ownership of m is retained.]]
  560. [[Returns:] [`true` if exclusive ownership was acquired for the current thread, `false` otherwise.]]
  561. [[Postcondition:] [If the call returns `true`, the current thread has exclusive ownership of `m`.]]
  562. [[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. ]]
  563. [[Throws:] [Nothing]]
  564. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  565. ]
  566. [endsect]
  567. [section:unlock_upgrade_and_lock_shared `m.unlock_upgrade_and_lock_shared()`]
  568. [variablelist
  569. [[Precondition:] [The current thread has upgrade ownership of `m`.]]
  570. [[Effects:] [Atomically releases upgrade ownership of `m` by the current thread and acquires shared ownership of `m` without
  571. blocking.]]
  572. [[Postcondition:] [The current thread has shared ownership of `m`.]]
  573. [[Synchronization:] [This operation synchronizes with prior `unlock_shared()` and subsequent lock operations that obtain ownership of the same object.]]
  574. [[Throws:] [Nothing]]
  575. ]
  576. [endsect]
  577. [endsect]
  578. [endsect]
  579. [section:lock_option Lock Options]
  580. // #include <boost/thread/locks.hpp>
  581. // #include <boost/thread/locks_options.hpp>
  582. namespace boost
  583. {
  584. struct defer_lock_t {};
  585. struct try_to_lock_t {};
  586. struct adopt_lock_t {};
  587. constexpr defer_lock_t defer_lock;
  588. constexpr try_to_lock_t try_to_lock;
  589. constexpr adopt_lock_t adopt_lock;
  590. [section:lock_tags Lock option tags]
  591. #include <boost/thread/locks.hpp>
  592. #include <boost/thread/locks_options.hpp>
  593. struct defer_lock_t {};
  594. struct try_to_lock_t {};
  595. struct adopt_lock_t {};
  596. const defer_lock_t defer_lock;
  597. const try_to_lock_t try_to_lock;
  598. const adopt_lock_t adopt_lock;
  599. These tags are used in scoped locks constructors to specify a specific behavior.
  600. *`defer_lock_t`: is used to construct the scoped lock without locking it.
  601. *`try_to_lock_t`: is used to construct the scoped lock trying to lock it.
  602. *`adopt_lock_t`: is used to construct the scoped lock without locking it but adopting ownership.
  603. [endsect]
  604. [endsect]
  605. [section:lock_guard Lock Guard]
  606. // #include <boost/thread/locks.hpp>
  607. // #include <boost/thread/lock_guard.hpp>
  608. namespace boost
  609. {
  610. template<typename Lockable>
  611. class lock_guard
  612. #if ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD
  613. template <typename Lockable>
  614. lock_guard<Lockable> make_lock_guard(Lockable& mtx); // EXTENSION
  615. template <typename Lockable>
  616. lock_guard<Lockable> make_lock_guard(Lockable& mtx, adopt_lock_t); // EXTENSION
  617. #endif
  618. }
  619. [section:lock_guard Class template `lock_guard`]
  620. // #include <boost/thread/locks.hpp>
  621. // #include <boost/thread/lock_guard.hpp>
  622. template<typename Lockable>
  623. class lock_guard
  624. {
  625. public:
  626. explicit lock_guard(Lockable& m_);
  627. lock_guard(Lockable& m_,boost::adopt_lock_t);
  628. ~lock_guard();
  629. };
  630. __lock_guard__ is very simple: on construction it
  631. acquires ownership of the implementation of the __lockable_concept__ supplied as
  632. the constructor parameter. On destruction, the ownership is released. This
  633. provides simple RAII-style locking of a __lockable_concept_type__ object, to facilitate exception-safe
  634. locking and unlocking. In addition, the [link
  635. thread.synchronization.lock_guard.lock_guard.constructor_adopt `lock_guard(Lockable &
  636. m,boost::adopt_lock_t)` constructor] allows the __lock_guard__ object to
  637. take ownership of a lock already held by the current thread.
  638. [section:constructor `lock_guard(Lockable & m)`]
  639. [variablelist
  640. [[Effects:] [Stores a reference to `m`. Invokes [lock_ref_link `m.lock()`].]]
  641. [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
  642. ]
  643. [endsect]
  644. [section:constructor_adopt `lock_guard(Lockable & m,boost::adopt_lock_t)`]
  645. [variablelist
  646. [[Precondition:] [The current thread owns a lock on `m` equivalent to one
  647. obtained by a call to [lock_ref_link `m.lock()`].]]
  648. [[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of
  649. `m`.]]
  650. [[Throws:] [Nothing.]]
  651. ]
  652. [endsect]
  653. [section:destructor `~lock_guard()`]
  654. [variablelist
  655. [[Effects:] [Invokes [unlock_ref_link `m.unlock()`] on the __lockable_concept_type__
  656. object passed to the constructor.]]
  657. [[Throws:] [Nothing.]]
  658. ]
  659. [endsect]
  660. [endsect]
  661. [section:make_lock_guard Non Member Function `make_lock_guard`]
  662. template <typename Lockable>
  663. lock_guard<Lockable> make_lock_guard(Lockable& m); // EXTENSION
  664. [variablelist
  665. [[Returns:] [a lock_guard as if initialized with `{m}`.]]
  666. [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
  667. ]
  668. [endsect]
  669. [section:make_lock_guard_adopt Non Member Function `make_lock_guard`]
  670. template <typename Lockable>
  671. lock_guard<Lockable> make_lock_guard(Lockable& m, adopt_lock_t); // EXTENSION
  672. [variablelist
  673. [[Returns:] [a lock_guard as if initialized with `{m, adopt_lock}`.]]
  674. [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
  675. ]
  676. [endsect]
  677. [endsect]
  678. [section:with_lock_guard With Lock Guard]
  679. // #include <boost/thread/with_lock_guard.hpp>
  680. namespace boost
  681. {
  682. template <class Lockable, class Function, class... Args>
  683. auto with_lock_guard(Lockable& m, Function&& func, Args&&... args) -> decltype(func(boost::forward<Args>(args)...));
  684. }
  685. [section:with_lock_guard Non Member Function `with_lock_guard`]
  686. template <class Lockable, class Function, class... Args>
  687. auto with_lock_guard(
  688. Lockable& m,
  689. Function&& func,
  690. Args&&... args
  691. ) -> decltype(func(boost::forward<Args>(args)...));
  692. [variablelist
  693. [[Precondition:] [`m` must be in unlocked state]]
  694. [[Effects:] [call `func` in scope locked by `m`]]
  695. [[Returns:] [Result of `func(args...)` call]]
  696. [[Throws:] [Any exception thrown by the call to `m.lock` and `func(args...)`]]
  697. [[Postcondition:] [`m` is in unlocked state]]
  698. [[Limitations:] [Without c++11 variadic templates support number of arguments is limited to `4`]]
  699. [[] [Without rvalue references support calling class method with `boost::bind` must be const]]
  700. [[] [For correct work with lambda macro `BOOST_RESULT_OF_USE_DECLTYPE` may be needed to define]]
  701. ]
  702. [endsect]
  703. [endsect]
  704. [section:lock_concepts Lock Concepts]
  705. [section:StrictLock StrictLock -- EXTENSION]
  706. // #include <boost/thread/lock_concepts.hpp>
  707. namespace boost
  708. {
  709. template<typename Lock>
  710. class StrictLock;
  711. }
  712. A StrictLock is a lock that ensures that the associated mutex is locked during the lifetime of the lock.
  713. A type `L` meets the StrictLock requirements if the following expressions are well-formed and have the specified semantics
  714. * `L::mutex_type`
  715. * `is_strict_lock<L>`
  716. * `cl.owns_lock(m);`
  717. and BasicLockable<L::mutex_type>
  718. where
  719. * `cl` denotes a value of type `L const&`,
  720. * `m` denotes a value of type `L::mutex_type const*`,
  721. [section: mutex_type `L::mutex_type`]
  722. The type L::mutex_type denotes the mutex that is locked by this lock.
  723. [endsect] [/ mutex_type]
  724. [section:is_strict_lock_sur_parole `is_strict_lock_sur_parole<L>`]
  725. As the semantic "ensures that the associated mutex is locked during the lifetime of the lock. " can not be described by syntactic requirements a `is_strict_lock_sur_parole` trait must be specialized by the user defining the lock so that the following assertion is true:
  726. is_strict_lock_sur_parole<L>::value == true
  727. [endsect] [/ is_strict_lock_sur_parole]
  728. [section:owns_lock `cl.owns_lock(m);`]
  729. [variablelist
  730. [[Return Type:] [`bool`]]
  731. [[Returns:] [Whether the strict lock is locking the mutex `m`]]
  732. [[Throws:] [Nothing.]]
  733. ]
  734. [endsect] [/ owns_lock]
  735. [section Models]
  736. The following classes are models of `StrictLock`:
  737. * strict_lock: ensured by construction,
  738. * nested_strict_lock: "sur parole" as the user could use adopt_lock_t on unique_lock constructor overload without having locked the mutex,
  739. * __lock_guard__: "sur parole" as the user could use adopt_lock_t constructor overload without having locked the mutex.
  740. [endsect] [/ Models]
  741. [endsect] [/ Strict Lock]
  742. [endsect] [/ Lock Concepts]
  743. [section:locks Lock Types]
  744. // #include <boost/thread/locks.hpp>
  745. // #include <boost/thread/lock_types.hpp>
  746. namespace boost
  747. {
  748. template<typename Lockable>
  749. class unique_lock;
  750. template<typename Mutex>
  751. void swap(unique_lock <Mutex>& lhs, unique_lock <Mutex>& rhs);
  752. template<typename Lockable>
  753. class shared_lock; // C++14
  754. template<typename Mutex>
  755. void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs); // C++14
  756. template<typename Lockable>
  757. class upgrade_lock; // EXTENSION
  758. template<typename Mutex>
  759. void swap(upgrade_lock <Mutex>& lhs, upgrade_lock <Mutex>& rhs); // EXTENSION
  760. template <class Mutex>
  761. class upgrade_to_unique_lock; // EXTENSION
  762. }
  763. [section:unique_lock Class template `unique_lock`]
  764. // #include <boost/thread/locks.hpp>
  765. // #include <boost/thread/lock_types.hpp>
  766. template<typename Lockable>
  767. class unique_lock
  768. {
  769. public:
  770. typedef Lockable mutex_type;
  771. unique_lock() noexcept;
  772. explicit unique_lock(Lockable& m_);
  773. unique_lock(Lockable& m_,adopt_lock_t);
  774. unique_lock(Lockable& m_,defer_lock_t) noexcept;
  775. unique_lock(Lockable& m_,try_to_lock_t);
  776. #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
  777. unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t); // C++14
  778. template <class Clock, class Duration>
  779. unique_lock(shared_lock<mutex_type>&& sl,
  780. const chrono::time_point<Clock, Duration>& abs_time); // C++14
  781. template <class Rep, class Period>
  782. unique_lock(shared_lock<mutex_type>&& sl,
  783. const chrono::duration<Rep, Period>& rel_time); // C++14
  784. #endif
  785. template <class Clock, class Duration>
  786. unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t);
  787. template <class Rep, class Period>
  788. unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d);
  789. ~unique_lock();
  790. unique_lock(unique_lock const&) = delete;
  791. unique_lock& operator=(unique_lock const&) = delete;
  792. unique_lock(unique_lock<Lockable>&& other) noexcept;
  793. explicit unique_lock(upgrade_lock<Lockable>&& other) noexcept; // EXTENSION
  794. unique_lock& operator=(unique_lock<Lockable>&& other) noexcept;
  795. void swap(unique_lock& other) noexcept;
  796. Lockable* release() noexcept;
  797. void lock();
  798. bool try_lock();
  799. template <class Rep, class Period>
  800. bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
  801. template <class Clock, class Duration>
  802. bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
  803. void unlock();
  804. explicit operator bool() const noexcept;
  805. bool owns_lock() const noexcept;
  806. mutex_type* mutex() const noexcept;
  807. #if defined BOOST_THREAD_USE_DATE_TIME || defined BOOST_THREAD_DONT_USE_CHRONO
  808. unique_lock(Lockable& m_,system_time const& target_time);
  809. template<typename TimeDuration>
  810. bool timed_lock(TimeDuration const& relative_time);
  811. bool timed_lock(::boost::system_time const& absolute_time);
  812. #endif
  813. };
  814. __unique_lock__ is more complex than __lock_guard__: not only does it provide for RAII-style locking, it also allows for deferring
  815. acquiring the lock until the __lock_ref__ member function is called explicitly, or trying to acquire the lock in a non-blocking
  816. fashion, or with a timeout. Consequently, __unlock_ref__ is only called in the destructor if the lock object has locked the
  817. __lockable_concept_type__ object, or otherwise adopted a lock on the __lockable_concept_type__ object.
  818. Specializations of __unique_lock__ model the __TimedLockable concept if the supplied `Lockable` type itself models
  819. __TimedLockable concept (e.g. `boost::unique_lock<boost::timed_mutex>`), or the __Lockable concept if the supplied `Lockable` type itself models
  820. __Lockable concept (e.g. `boost::unique_lock<boost::mutex>`), or the __BasicLockable concept if the supplied `Lockable` type itself models
  821. __BasicLockable concept.
  822. An instance of __unique_lock__ is said to ['own] the lock state of a __lockable_concept_type__ `m` if __mutex_func_ref__ returns a
  823. pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] the lock state of a __lockable_concept_type__ object
  824. is destroyed, then the destructor will invoke [unlock_ref_link `mutex()->unlock()`].
  825. The member functions of __unique_lock__ are not thread-safe. In particular, __unique_lock__ is intended to model the ownership of a
  826. __lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock state
  827. (including the destructor) must be called by the same thread that acquired ownership of the lock state.
  828. [section:defaultconstructor `unique_lock()`]
  829. [variablelist
  830. [[Effects:] [Creates a lock object with no associated mutex.]]
  831. [[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `NULL`.]]
  832. [[Throws:] [Nothing.]]
  833. ]
  834. [endsect]
  835. [section:constructor `unique_lock(Lockable & m)`]
  836. [variablelist
  837. [[Effects:] [Stores a reference to `m`. Invokes [lock_ref_link `m.lock()`].]]
  838. [[Postcondition:] [__owns_lock_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
  839. [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
  840. ]
  841. [endsect]
  842. [section:constructor_adopt `unique_lock(Lockable & m,boost::adopt_lock_t)`]
  843. [variablelist
  844. [[Precondition:] [The current thread owns an exclusive lock on `m`.]]
  845. [[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of `m`.]]
  846. [[Postcondition:] [__owns_lock_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
  847. [[Throws:] [Nothing.]]
  848. ]
  849. [endsect]
  850. [section:constructor_defer `unique_lock(Lockable & m,boost::defer_lock_t)`]
  851. [variablelist
  852. [[Effects:] [Stores a reference to `m`.]]
  853. [[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `&m`.]]
  854. [[Throws:] [Nothing.]]
  855. ]
  856. [endsect]
  857. [section:constructor_try `unique_lock(Lockable & m,boost::try_to_lock_t)`]
  858. [variablelist
  859. [[Effects:] [Stores a reference to `m`. Invokes [try_lock_ref_link
  860. `m.try_lock()`], and takes ownership of the lock state if the call returns
  861. `true`.]]
  862. [[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_ref__
  863. returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
  864. returns `false`.]]
  865. [[Throws:] [Nothing.]]
  866. ]
  867. [endsect]
  868. [section:constructor_sh_try `unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t)`]
  869. [variablelist
  870. [[Requires:] [The supplied `Mutex` type must implement `__try_unlock_shared_and_lock()`.]]
  871. [[Effects:] [Constructs an object of type __unique_lock. Let `pm` be the pointer to the mutex and `owns` the ownership state. Initializes `pm` with nullptr and `owns` with false.
  872. If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.release()`.
  873. 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`.]]
  874. [[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()->try_unlock_shared_and_lock()` returns `false`, `sl` is not modified.]]
  875. [[Throws:] [Nothing.]]
  876. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  877. ]
  878. [endsect]
  879. [section:constructor_sh_until `unique_lock(shared_lock<mutex_type>&&, const chrono::time_point<Clock, Duration>&)`]
  880. template <class Clock, class Duration>
  881. unique_lock(shared_lock<mutex_type>&& sl,
  882. const chrono::time_point<Clock, Duration>& abs_time);
  883. [variablelist
  884. [[Requires:] [The supplied `Mutex` type shall implement `__try_unlock_shared_and_lock_until(abs_time)`.]]
  885. [[Effects:] [Constructs an object of type `__unique_lock`, initializing `pm` with `nullptr` and `owns` with `false`.
  886. If `sl.__owns_lock_shared_ref__()` returns `false`, sets `pm` to the return value of `sl.release()`.
  887. Else `sl.__owns_lock_shared_ref__()` 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`.]]
  888. [[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()-> __try_unlock_shared_and_lock_until(abs_time)` returns `false`, `sl` is not modified.]]
  889. [[Throws:] [Nothing.]]
  890. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  891. ]
  892. [endsect]
  893. [section:constructor_sh_for `unique_lock(shared_lock<mutex_type>&&, const chrono::duration<Rep, Period>&)`]
  894. template <class Rep, class Period>
  895. unique_lock(shared_lock<mutex_type>&& sl,
  896. const chrono::duration<Rep, Period>& rel_time)
  897. [variablelist
  898. [[Requires:] [The supplied `Mutex` type shall implement `__try_unlock_shared_and_lock_for(rel_time)`.]]
  899. [[Effects:] [Constructs an object of type `__unique_lock`, initializing `pm` with `nullptr` and `owns` with `false`.
  900. If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.release()`.
  901. 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`.]]
  902. [[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()-> __try_unlock_shared_and_lock_for(rel_time)` returns `false`, `sl` is not modified.]]
  903. [[Postcondition:] [.]]
  904. [[Throws:] [Nothing.]]
  905. [[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
  906. ]
  907. [endsect]
  908. [section:constructor_abs_time `unique_lock(Lockable & m,boost::system_time const& abs_time)`]
  909. [variablelist
  910. [[Effects:] [Stores a reference to `m`. Invokes [timed_lock_ref_link
  911. `m.timed_lock(abs_time)`], and takes ownership of the lock state if the call
  912. returns `true`.]]
  913. [[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __timed_lock_ref__
  914. returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
  915. returns `false`.]]
  916. [[Throws:] [Any exceptions thrown by the call to [timed_lock_ref_link `m.timed_lock(abs_time)`].]]
  917. ]
  918. [endsect]
  919. [section:constructor_time_point `template <class Clock, class Duration> unique_lock(Lockable & m,const chrono::time_point<Clock, Duration>& abs_time)`]
  920. [variablelist
  921. [[Effects:] [Stores a reference to `m`. Invokes
  922. `m.__try_lock_until(abs_time)`, and takes ownership of the lock state if the call
  923. returns `true`.]]
  924. [[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_until
  925. returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
  926. returns `false`.]]
  927. [[Throws:] [Any exceptions thrown by the call to `m.__try_lock_until(abs_time)`.]]
  928. ]
  929. [endsect]
  930. [section:constructor_duration `template <class Rep, class Period> unique_lock(Lockable & m,const chrono::duration<Rep, Period>& abs_time)`]
  931. [variablelist
  932. [[Effects:] [Stores a reference to `m`. Invokes
  933. `m.__try_lock_for(rel_time)`, and takes ownership of the lock state if the call
  934. returns `true`.]]
  935. [[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_for
  936. returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
  937. returns `false`.]]
  938. [[Throws:] [Any exceptions thrown by the call to `m.__try_lock_for(rel_time)`.]]
  939. ]
  940. [endsect]
  941. [section:destructor `~unique_lock()`]
  942. [variablelist
  943. [[Effects:] [Invokes __mutex_func_ref__`->`[unlock_ref_link `unlock()`] if
  944. __owns_lock_ref__ returns `true`.]]
  945. [[Throws:] [Nothing.]]
  946. ]
  947. [endsect]
  948. [section:owns_lock `bool owns_lock() const`]
  949. [variablelist
  950. [[Returns:] [`true` if the `*this` owns the lock on the __lockable_concept_type__
  951. object associated with `*this`.]]
  952. [[Throws:] [Nothing.]]
  953. ]
  954. [endsect]
  955. [section:mutex `Lockable* mutex() const noexcept`]
  956. [variablelist
  957. [[Returns:] [A pointer to the __lockable_concept_type__ object associated with
  958. `*this`, or `NULL` if there is no such object.]]
  959. [[Throws:] [Nothing.]]
  960. ]
  961. [endsect]
  962. [section:explicit_bool_conversion `explicit operator bool() const`]
  963. [variablelist
  964. [[Returns:] [`__owns_lock_ref__()`.]]
  965. [[Throws:] [Nothing.]]
  966. ]
  967. [endsect]
  968. [section:release `Lockable* release()`]
  969. [variablelist
  970. [[Effects:] [The association between `*this` and the __lockable_concept_type__ object is removed, without affecting the lock state
  971. of the __lockable_concept_type__ object. If __owns_lock_ref__ would have returned `true`, it is the responsibility of the calling
  972. code to ensure that the __lockable_concept_type__ is correctly unlocked.]]
  973. [[Returns:] [A pointer to the __lockable_concept_type__ object associated with `*this` at the point of the call, or `NULL` if there
  974. is no such object.]]
  975. [[Throws:] [Nothing.]]
  976. [[Postcondition:] [`*this` is no longer associated with any __lockable_concept_type__ object. __mutex_func_ref__ returns `NULL` and
  977. __owns_lock_ref__ returns `false`.]]
  978. ]
  979. [endsect]
  980. [endsect]
  981. [section:shared_lock Class template `shared_lock` - C++14]
  982. // #include <boost/thread/locks.hpp>
  983. // #include <boost/thread/lock_types.hpp>
  984. template<typename Lockable>
  985. class shared_lock
  986. {
  987. public:
  988. typedef Lockable mutex_type;
  989. // Shared locking
  990. shared_lock();
  991. explicit shared_lock(Lockable& m_);
  992. shared_lock(Lockable& m_,adopt_lock_t);
  993. shared_lock(Lockable& m_,defer_lock_t);
  994. shared_lock(Lockable& m_,try_to_lock_t);
  995. template <class Clock, class Duration>
  996. shared_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t);
  997. template <class Rep, class Period>
  998. shared_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d);
  999. ~shared_lock();
  1000. shared_lock(shared_lock const&) = delete;
  1001. shared_lock& operator=(shared_lock const&) = delete;
  1002. shared_lock(shared_lock<Lockable> && other);
  1003. shared_lock& operator=(shared_lock<Lockable> && other);
  1004. void lock();
  1005. bool try_lock();
  1006. template <class Rep, class Period>
  1007. bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
  1008. template <class Clock, class Duration>
  1009. bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
  1010. void unlock();
  1011. // Conversion from upgrade locking
  1012. explicit shared_lock(upgrade_lock<Lockable> && other); // EXTENSION
  1013. // Conversion from exclusive locking
  1014. explicit shared_lock(unique_lock<Lockable> && other);
  1015. // Setters
  1016. void swap(shared_lock& other);
  1017. mutex_type* release() noexcept;
  1018. // Getters
  1019. explicit operator bool() const;
  1020. bool owns_lock() const;
  1021. mutex_type mutex() const;
  1022. #if defined BOOST_THREAD_USE_DATE_TIME || defined BOOST_THREAD_DONT_USE_CHRONO
  1023. shared_lock(Lockable& m_,system_time const& target_time);
  1024. bool timed_lock(boost::system_time const& target_time);
  1025. #endif
  1026. };
  1027. Like __unique_lock__, __shared_lock__ models the __lockable_concept__, but rather than acquiring unique ownership of the supplied
  1028. __lockable_concept_type__ object, locking an instance of __shared_lock__ acquires shared ownership.
  1029. Like __unique_lock__, not only does it provide for RAII-style locking, it also allows for deferring acquiring the lock until the
  1030. __lock_ref__ member function is called explicitly, or trying to acquire the lock in a non-blocking fashion, or with a
  1031. timeout. Consequently, __unlock_ref__ is only called in the destructor if the lock object has locked the __lockable_concept_type__
  1032. object, or otherwise adopted a lock on the __lockable_concept_type__ object.
  1033. An instance of __shared_lock__ is said to ['own] the lock state of a __lockable_concept_type__ `m` if __mutex_func_ref__ returns a
  1034. pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] the lock state of a __lockable_concept_type__ object
  1035. is destroyed, then the destructor will invoke [unlock_shared_ref_link `mutex()->unlock_shared()`].
  1036. The member functions of __shared_lock__ are not thread-safe. In particular, __shared_lock__ is intended to model the shared
  1037. ownership of a __lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock
  1038. state (including the destructor) must be called by the same thread that acquired ownership of the lock state.
  1039. [section:defaultconstructor `shared_lock()`]
  1040. [variablelist
  1041. [[Effects:] [Creates a lock object with no associated mutex.]]
  1042. [[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `NULL`.]]
  1043. [[Throws:] [Nothing.]]
  1044. ]
  1045. [endsect]
  1046. [section:constructor `shared_lock(Lockable & m)`]
  1047. [variablelist
  1048. [[Effects:] [Stores a reference to `m`. Invokes [lock_shared_ref_link `m.lock_shared()`].]]
  1049. [[Postcondition:] [__owns_lock_shared_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
  1050. [[Throws:] [Any exception thrown by the call to [lock_shared_ref_link `m.lock_shared()`].]]
  1051. ]
  1052. [endsect]
  1053. [section:constructor_adopt `shared_lock(Lockable & m,boost::adopt_lock_t)`]
  1054. [variablelist
  1055. [[Precondition:] [The current thread owns an exclusive lock on `m`.]]
  1056. [[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of `m`.]]
  1057. [[Postcondition:] [__owns_lock_shared_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
  1058. [[Throws:] [Nothing.]]
  1059. ]
  1060. [endsect]
  1061. [section:constructor_defer `shared_lock(Lockable & m,boost::defer_lock_t)`]
  1062. [variablelist
  1063. [[Effects:] [Stores a reference to `m`.]]
  1064. [[Postcondition:] [__owns_lock_shared_ref__ returns `false`. __mutex_func_ref__ returns `&m`.]]
  1065. [[Throws:] [Nothing.]]
  1066. ]
  1067. [endsect]
  1068. [section:constructor_try `shared_lock(Lockable & m,boost::try_to_lock_t)`]
  1069. [variablelist
  1070. [[Effects:] [Stores a reference to `m`. Invokes [try_lock_shared_ref_link
  1071. `m.try_lock_shared()`], and takes ownership of the lock state if the call returns
  1072. `true`.]]
  1073. [[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_shared_ref__
  1074. returned `true`, then __owns_lock_shared_ref__ returns `true`, otherwise __owns_lock_shared_ref__
  1075. returns `false`.]]
  1076. [[Throws:] [Nothing.]]
  1077. ]
  1078. [endsect]
  1079. [section:constructor_abs_time `shared_lock(Lockable & m,boost::system_time const& abs_time)`]
  1080. [variablelist
  1081. [[Effects:] [Stores a reference to `m`. Invokes [timed_lock_shared_ref_link
  1082. `m.timed_lock(abs_time)`], and takes ownership of the lock state if the call
  1083. returns `true`.]]
  1084. [[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __timed_lock_shared_ref__
  1085. returned `true`, then __owns_lock_shared_ref__ returns `true`, otherwise __owns_lock_shared_ref__
  1086. returns `false`.]]
  1087. [[Throws:] [Any exceptions thrown by the call to [timed_lock_shared_ref_link `m.timed_lock(abs_time)`].]]
  1088. ]
  1089. [endsect]
  1090. [section:destructor `~shared_lock()`]
  1091. [variablelist
  1092. [[Effects:] [Invokes __mutex_func_ref__`->`[unlock_shared_ref_link `unlock_shared()`] if
  1093. __owns_lock_shared_ref__ returns `true`.]]
  1094. [[Throws:] [Nothing.]]
  1095. ]
  1096. [endsect]
  1097. [section:owns_lock `bool owns_lock() const`]
  1098. [variablelist
  1099. [[Returns:] [`true` if the `*this` owns the lock on the __lockable_concept_type__
  1100. object associated with `*this`.]]
  1101. [[Throws:] [Nothing.]]
  1102. ]
  1103. [endsect]
  1104. [section:mutex `Lockable* mutex() const`]
  1105. [variablelist
  1106. [[Returns:] [A pointer to the __lockable_concept_type__ object associated with
  1107. `*this`, or `NULL` if there is no such object.]]
  1108. [[Throws:] [Nothing.]]
  1109. ]
  1110. [endsect]
  1111. [section:explicit_operator_bool `explicit operator bool() const`]
  1112. [variablelist
  1113. [[Returns:] [__owns_lock_shared_ref__.]]
  1114. [[Throws:] [Nothing.]]
  1115. ]
  1116. [endsect]
  1117. [section:release `Lockable* release()`]
  1118. [variablelist
  1119. [[Effects:] [The association between `*this` and the __lockable_concept_type__ object is removed, without affecting the lock state
  1120. of the __lockable_concept_type__ object. If __owns_lock_shared_ref__ would have returned `true`, it is the responsibility of the calling
  1121. code to ensure that the __lockable_concept_type__ is correctly unlocked.]]
  1122. [[Returns:] [A pointer to the __lockable_concept_type__ object associated with `*this` at the point of the call, or `NULL` if there
  1123. is no such object.]]
  1124. [[Throws:] [Nothing.]]
  1125. [[Postcondition:] [`*this` is no longer associated with any __lockable_concept_type__ object. __mutex_func_ref__ returns `NULL` and
  1126. __owns_lock_shared_ref__ returns `false`.]]
  1127. ]
  1128. [endsect]
  1129. [endsect]
  1130. [section:upgrade_lock Class template `upgrade_lock` - EXTENSION]
  1131. // #include <boost/thread/locks.hpp>
  1132. // #include <boost/thread/lock_types.hpp>
  1133. template<typename Lockable>
  1134. class upgrade_lock
  1135. {
  1136. public:
  1137. typedef Lockable mutex_type;
  1138. // Upgrade locking
  1139. upgrade_lock();
  1140. explicit upgrade_lock(mutex_type& m_);
  1141. upgrade_lock(mutex_type& m, defer_lock_t) noexcept;
  1142. upgrade_lock(mutex_type& m, try_to_lock_t);
  1143. upgrade_lock(mutex_type& m, adopt_lock_t);
  1144. template <class Clock, class Duration>
  1145. upgrade_lock(mutex_type& m,
  1146. const chrono::time_point<Clock, Duration>& abs_time);
  1147. template <class Rep, class Period>
  1148. upgrade_lock(mutex_type& m,
  1149. const chrono::duration<Rep, Period>& rel_time);
  1150. ~upgrade_lock();
  1151. upgrade_lock(const upgrade_lock& other) = delete;
  1152. upgrade_lock& operator=(const upgrade_lock<Lockable> & other) = delete;
  1153. upgrade_lock(upgrade_lock<Lockable> && other);
  1154. upgrade_lock& operator=(upgrade_lock<Lockable> && other);
  1155. void lock();
  1156. bool try_lock();
  1157. template <class Rep, class Period>
  1158. bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
  1159. template <class Clock, class Duration>
  1160. bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
  1161. void unlock();
  1162. #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
  1163. // Conversion from shared locking
  1164. upgrade_lock(shared_lock<mutex_type>&& sl, try_to_lock_t);
  1165. template <class Clock, class Duration>
  1166. upgrade_lock(shared_lock<mutex_type>&& sl,
  1167. const chrono::time_point<Clock, Duration>& abs_time);
  1168. template <class Rep, class Period>
  1169. upgrade_lock(shared_lock<mutex_type>&& sl,
  1170. const chrono::duration<Rep, Period>& rel_time);
  1171. #endif
  1172. // Conversion from exclusive locking
  1173. explicit upgrade_lock(unique_lock<Lockable> && other);
  1174. // Setters
  1175. void swap(upgrade_lock& other);
  1176. mutex_type* release() noexcept;
  1177. // Getters
  1178. explicit operator bool() const;
  1179. bool owns_lock() const;
  1180. mutex_type mutex() const;
  1181. };
  1182. Like __unique_lock__, __upgrade_lock__ models the __lockable_concept__, but rather than acquiring unique ownership of the supplied
  1183. __lockable_concept_type__ object, locking an instance of __upgrade_lock__ acquires upgrade ownership.
  1184. Like __unique_lock__, not only does it provide for RAII-style locking, it also allows for deferring acquiring the lock until the
  1185. __lock_ref__ member function is called explicitly, or trying to acquire the lock in a non-blocking fashion, or with a
  1186. timeout. Consequently, __unlock_ref__ is only called in the destructor if the lock object has locked the __lockable_concept_type__
  1187. object, or otherwise adopted a lock on the __lockable_concept_type__ object.
  1188. An instance of __upgrade_lock__ is said to ['own] the lock state of a __lockable_concept_type__ `m` if __mutex_func_ref__ returns a
  1189. pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] the lock state of a __lockable_concept_type__ object
  1190. is destroyed, then the destructor will invoke [unlock_upgrade_ref_link `mutex()->unlock_upgrade()`].
  1191. The member functions of __upgrade_lock__ are not thread-safe. In particular, __upgrade_lock__ is intended to model the upgrade
  1192. ownership of a __upgrade_lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock
  1193. state (including the destructor) must be called by the same thread that acquired ownership of the lock state.
  1194. [endsect]
  1195. [section:upgrade_to_unique_lock Class template `upgrade_to_unique_lock` -- EXTENSION]
  1196. // #include <boost/thread/locks.hpp>
  1197. // #include <boost/thread/lock_types.hpp>
  1198. template <class Lockable>
  1199. class upgrade_to_unique_lock
  1200. {
  1201. public:
  1202. typedef Lockable mutex_type;
  1203. explicit upgrade_to_unique_lock(upgrade_lock<Lockable>& m_);
  1204. ~upgrade_to_unique_lock();
  1205. upgrade_to_unique_lock(upgrade_to_unique_lock const& other) = delete;
  1206. upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Lockable> const& other) = delete;
  1207. upgrade_to_unique_lock(upgrade_to_unique_lock<Lockable> && other);
  1208. upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Lockable> && other);
  1209. void swap(upgrade_to_unique_lock& other);
  1210. explicit operator bool() const;
  1211. bool owns_lock() const;
  1212. mutex_type* mutex() const;
  1213. };
  1214. __upgrade_to_unique_lock__ allows for a temporary upgrade of an __upgrade_lock__ to exclusive ownership. When constructed with a
  1215. reference to an instance of __upgrade_lock__, if that instance has upgrade ownership on some __lockable_concept_type__ object, that
  1216. ownership is upgraded to exclusive ownership. When the __upgrade_to_unique_lock__ instance is destroyed, the ownership of the
  1217. __lockable_concept_type__ is downgraded back to ['upgrade ownership].
  1218. [endsect]
  1219. [section:scoped_try_lock Mutex-specific class `scoped_try_lock` -- DEPRECATED]
  1220. class MutexType::scoped_try_lock
  1221. {
  1222. private:
  1223. MutexType::scoped_try_lock(MutexType::scoped_try_lock<MutexType>& other);
  1224. MutexType::scoped_try_lock& operator=(MutexType::scoped_try_lock<MutexType>& other);
  1225. public:
  1226. MutexType::scoped_try_lock();
  1227. explicit MutexType::scoped_try_lock(MutexType& m);
  1228. MutexType::scoped_try_lock(MutexType& m_,adopt_lock_t);
  1229. MutexType::scoped_try_lock(MutexType& m_,defer_lock_t);
  1230. MutexType::scoped_try_lock(MutexType& m_,try_to_lock_t);
  1231. MutexType::scoped_try_lock(MutexType::scoped_try_lock<MutexType>&& other);
  1232. MutexType::scoped_try_lock& operator=(MutexType::scoped_try_lock<MutexType>&& other);
  1233. void swap(MutexType::scoped_try_lock&& other);
  1234. void lock();
  1235. bool try_lock();
  1236. void unlock();
  1237. MutexType* mutex() const;
  1238. MutexType* release();
  1239. explicit operator bool() const;
  1240. bool owns_lock() const;
  1241. };
  1242. The member typedef `scoped_try_lock` is provided for each distinct
  1243. `MutexType` as a typedef to a class with the preceding definition. The
  1244. semantics of each constructor and member function are identical to
  1245. those of [unique_lock_link `boost::unique_lock<MutexType>`] for the same `MutexType`, except
  1246. that the constructor that takes a single reference to a mutex will
  1247. call [try_lock_ref_link `m.try_lock()`] rather than `m.lock()`.
  1248. [endsect]
  1249. [endsect]
  1250. [/
  1251. [section:other_mutex Other Mutex Types]
  1252. [section: reverse_mutex Class template `reverse_mutex`]
  1253. //#include <boost/thread/reverse_mutex.hpp>
  1254. namespace boost
  1255. {
  1256. template<typename BasicLockable>
  1257. class reverse_mutex
  1258. {
  1259. public:
  1260. typedef BasicLockable mutex_type;
  1261. reverse_mutex(reverse_mutex const&) = delete;
  1262. reverse_mutex& operator=(reverse_mutex const&) = delete;
  1263. explicit reverse_mutex(mutex_type& m_);
  1264. ~reverse_mutex();
  1265. void lock();
  1266. void unlock();
  1267. };
  1268. }
  1269. __reverse_mutex reverse the operations of a __BasicLockable, that unlocks the lockable when `lock()` is called and locks it when `unlock()` is called.
  1270. [endsect]
  1271. [endsect]
  1272. ]
  1273. [section:other_locks Other Lock Types - EXTENSION]
  1274. [section:strict_locks Strict Locks]
  1275. // #include <boost/thread/locks.hpp>
  1276. // #include <boost/thread/strict_lock.hpp>
  1277. namespace boost
  1278. {
  1279. template<typename Lockable>
  1280. class strict_lock;
  1281. template <typename Lock>
  1282. class nested_strict_lock;
  1283. template <typename Lockable>
  1284. struct is_strict_lock_sur_parole<strict_lock<Lockable> >;
  1285. template <typename Lock>
  1286. struct is_strict_lock_sur_parole<nested_strict_lock<Lock> >;
  1287. #if ! defined BOOST_THREAD_NO_MAKE_STRICT_LOCK
  1288. template <typename Lockable>
  1289. strict_lock<Lockable> make_strict_lock(Lockable& mtx);
  1290. #endif
  1291. #if ! defined BOOST_THREAD_NO_MAKE_NESTED_STRICT_LOCK
  1292. template <typename Lock>
  1293. nested_strict_lock<Lock> make_nested_strict_lock(Lock& lk);
  1294. #endif
  1295. }
  1296. [section:strict_lock Class template `strict_lock`]
  1297. // #include <boost/thread/locks.hpp>
  1298. // #include <boost/thread/strict_lock.hpp>
  1299. template<typename BasicLockable>
  1300. class strict_lock
  1301. {
  1302. public:
  1303. typedef BasicLockable mutex_type;
  1304. strict_lock(strict_lock const& m_) = delete;
  1305. strict_lock& operator=(strict_lock const& m_) = delete;
  1306. explicit strict_lock(mutex_type& m_);
  1307. ~strict_lock();
  1308. bool owns_lock(mutex_type const* l) const noexcept;
  1309. };
  1310. __strict_lock is a model of __StrictLock.
  1311. __strict_lock is the simplest __StrictLock: on construction it acquires ownership of the implementation of the __BasicLockable concept supplied as the constructor parameter. On destruction, the ownership is released. This provides simple RAII-style locking of a __BasicLockable object, to facilitate exception-safe locking and unlocking.
  1312. [heading See also __lock_guard__]
  1313. [section:constructor `strict_lock(Lockable & m)`]
  1314. [variablelist
  1315. [[Effects:] [Stores a reference to `m`. Invokes [lock_ref_link `m.lock()`].]]
  1316. [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
  1317. ]
  1318. [endsect]
  1319. [section:destructor `~strict_lock()`]
  1320. [variablelist
  1321. [[Effects:] [Invokes [unlock_ref_link `m.unlock()`] on the __lockable_concept_type__
  1322. object passed to the constructor.]]
  1323. [[Throws:] [Nothing.]]
  1324. ]
  1325. [endsect]
  1326. [endsect]
  1327. [section:nested_strict_lock Class template `nested_strict_lock`]
  1328. // #include <boost/thread/locks.hpp>
  1329. // #include <boost/thread/strict_lock.hpp>
  1330. template<typename Lock>
  1331. class nested_strict_lock
  1332. {
  1333. public:
  1334. typedef BasicLockable mutex_type;
  1335. nested_strict_lock(nested_strict_lock const& m_) = delete;
  1336. nested_strict_lock& operator=(nested_strict_lock const& m_) = delete;
  1337. explicit nested_strict_lock(Lock& lk),
  1338. ~nested_strict_lock() noexcept;
  1339. bool owns_lock(mutex_type const* l) const noexcept;
  1340. };
  1341. __nested_strict_lock is a model of __StrictLock.
  1342. A nested strict lock is a scoped lock guard ensuring a mutex is locked on its
  1343. scope, by taking ownership of a nesting lock, locking the mutex on construction if not already locked
  1344. and restoring the ownership to the nesting lock on destruction.
  1345. [heading See also __strict_lock, __unique_lock]
  1346. [section:constructor `nested_strict_lock(Lock & lk)`]
  1347. [variablelist
  1348. [[Requires:] [`lk.mutex() != null_ptr`.]]
  1349. [[Effects:] [Stores the reference to the lock parameter `lk` and takes ownership on it.
  1350. If the lock doesn't owns the mutex lock it.
  1351. ]]
  1352. [[Postcondition:] [`owns_lock(lk.mutex())`.]]
  1353. [[Throws:] [
  1354. - lock_error when BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is defined and lk.mutex() == null_ptr
  1355. - Any exception that @c lk.lock() can throw.
  1356. ]]
  1357. ]
  1358. [endsect]
  1359. [section:destructor `~nested_strict_lock() noexcept`]
  1360. [variablelist
  1361. [[Effects:] [Restores ownership to the nesting lock.]]
  1362. ]
  1363. [endsect]
  1364. [section:owns_lock `bool owns_lock(mutex_type const* l) const noexcept`]
  1365. [variablelist
  1366. [[Return:] [Whether if this lock is locking that mutex.]]
  1367. ]
  1368. [endsect]
  1369. [endsect]
  1370. [section:make_strict_lock Non Member Function `make_strict_lock`]
  1371. template <typename Lockable>
  1372. strict_lock<Lockable> make_strict_lock(Lockable& m); // EXTENSION
  1373. [variablelist
  1374. [[Returns:] [a strict_lock as if initialized with `{m}`.]]
  1375. [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
  1376. ]
  1377. [endsect]
  1378. [section:make_nested_strict_lock Non Member Function `make_nested_strict_lock`]
  1379. template <typename Lock>
  1380. nested_strict_lock<Lock> make_nested_strict_lock(Lock& lk); // EXTENSION
  1381. [variablelist
  1382. [[Returns:] [a nested_strict_lock as if initialized with `{lk}`.]]
  1383. [[Throws:] [Any exception thrown by the call to [lock_ref_link `lk.lock()`].]]
  1384. ]
  1385. [endsect]
  1386. [endsect]
  1387. [section:lock_ptrs Locking pointers]
  1388. // #include <boost/thread/synchroniezd_value.hpp>
  1389. // #include <boost/thread/strict_lock_ptr.hpp>
  1390. namespace boost
  1391. {
  1392. template<typename T, typename Lockable = mutex>
  1393. class strict_lock_ptr;
  1394. template<typename T, typename Lockable = mutex>
  1395. class const_strict_lock_ptr;
  1396. }
  1397. [/
  1398. template<typename T, typename Lockable = mutex>
  1399. class unique_lock_ptr;
  1400. template<typename T, typename Lockable = mutex>
  1401. class const_unique_lock_ptr;
  1402. ]
  1403. [section:const_strict_lock_ptr Class template `const_strict_lock_ptr `]
  1404. // #include <boost/thread/synchroniezd_value.hpp>
  1405. // #include <boost/thread/strict_lock_ptr.hpp>
  1406. template <typename T, typename Lockable = mutex>
  1407. class const_strict_lock_ptr
  1408. {
  1409. public:
  1410. typedef T value_type;
  1411. typedef Lockable mutex_type;
  1412. const_strict_lock_ptr(const_strict_lock_ptr const& m_) = delete;
  1413. const_strict_lock_ptr& operator=(const_strict_lock_ptr const& m_) = delete;
  1414. const_strict_lock_ptr(T const& val, Lockable & mtx);
  1415. const_strict_lock_ptr(T const& val, Lockable & mtx, adopt_lock_t tag);
  1416. ~const_strict_lock_ptr();
  1417. const T* operator->() const;
  1418. const T& operator*() const;
  1419. };
  1420. [section:constructor `const_strict_lock_ptr(T const&,Lockable&)`]
  1421. const_strict_lock_ptr(T const& val, Lockable & m);
  1422. [variablelist
  1423. [[Effects:] [Invokes [lock_ref_link `m.lock()`], stores a reference to it and to the value type `val`.]]
  1424. [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
  1425. ]
  1426. [endsect]
  1427. [section:constructor_adopt `const_strict_lock_ptr(T const&,Lockable&,adopt_lock_t)`]
  1428. const_strict_lock_ptr(T const& val, Lockable & m, adopt_lock_t tag);
  1429. [variablelist
  1430. [[Effects:] [Stores a reference to it and to the value type `val`.]]
  1431. [[Throws:] [Nothing.]]
  1432. ]
  1433. [endsect]
  1434. [section:destructor `~const_strict_lock_ptr()`]
  1435. ~const_strict_lock_ptr();
  1436. [variablelist
  1437. [[Effects:] [Invokes [unlock_ref_link `m.unlock()`] on the __lockable_concept_type__
  1438. object passed to the constructor.]]
  1439. [[Throws:] [Nothing.]]
  1440. ]
  1441. [endsect]
  1442. [section:indir `operator->() const`]
  1443. const T* operator->() const;
  1444. [variablelist
  1445. [[Return:] [return a constant pointer to the protected value.]]
  1446. [[Throws:] [Nothing.]]
  1447. ]
  1448. [endsect]
  1449. [section:deref `operator*() const`]
  1450. const T& operator*() const;
  1451. [variablelist
  1452. [[Return:] [return a constant reference to the protected value.]]
  1453. [[Throws:] [Nothing.]]
  1454. ]
  1455. [endsect]
  1456. [endsect] [/ const_strict_lock_ptr ]
  1457. [section:strict_lock_ptr Class template `strict_lock_ptr`]
  1458. // #include <boost/thread/synchroniezd_value.hpp>
  1459. // #include <boost/thread/strict_lock_ptr.hpp>
  1460. template <typename T, typename Lockable = mutex>
  1461. class strict_lock_ptr : public const_strict_lock_ptr<T,Lockable>
  1462. {
  1463. public:
  1464. strict_lock_ptr(strict_lock_ptr const& m_) = delete;
  1465. strict_lock_ptr& operator=(strict_lock_ptr const& m_) = delete;
  1466. strict_lock_ptr(T & val, Lockable & mtx);
  1467. strict_lock_ptr(T & val, Lockable & mtx, adopt_lock_t tag);
  1468. ~strict_lock_ptr();
  1469. T* operator->();
  1470. T& operator*();
  1471. };
  1472. [section:constructor `strict_lock_ptr(T const&,Lockable&)`]
  1473. strict_lock_ptr(T const& val, Lockable & m);
  1474. [variablelist
  1475. [[Effects:] [Invokes [lock_ref_link `m.lock()`], stores a reference to it and to the value type `val`.]]
  1476. [[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
  1477. ]
  1478. [endsect]
  1479. [section:constructor_adopt `strict_lock_ptr(T const&,Lockable&,adopt_lock_t)`]
  1480. strict_lock_ptr(T const& val, Lockable & m, adopt_lock_t tag);
  1481. [variablelist
  1482. [[Effects:] [Stores a reference to it and to the value type `val`.]]
  1483. [[Throws:] [Nothing.]]
  1484. ]
  1485. [endsect]
  1486. [section:destructor `~strict_lock_ptr()`]
  1487. ~ strict_lock_ptr();
  1488. [variablelist
  1489. [[Effects:] [Invokes [unlock_ref_link `m.unlock()`] on the __lockable_concept_type__
  1490. object passed to the constructor.]]
  1491. [[Throws:] [Nothing.]]
  1492. ]
  1493. [endsect]
  1494. [section:indir `operator->()`]
  1495. T* operator->();
  1496. [variablelist
  1497. [[Return:] [return a pointer to the protected value.]]
  1498. [[Throws:] [Nothing.]]
  1499. ]
  1500. [endsect]
  1501. [section:deref `operator*()`]
  1502. T& operator*();
  1503. [variablelist
  1504. [[Return:] [return a reference to the protected value.]]
  1505. [[Throws:] [Nothing.]]
  1506. ]
  1507. [endsect]
  1508. [endsect] [/ strict_lock_ptr ]
  1509. [endsect] [/ lock_ptrs ]
  1510. [section Externally Locked]
  1511. // #include <boost/thread/externally_locked.hpp>
  1512. template <class T, typename MutexType = boost::mutex>
  1513. class externally_locked;
  1514. template <class T, typename MutexType>
  1515. class externally_locked<T&, MutexType>;
  1516. template <typename T, typename MutexType>
  1517. void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs);
  1518. [section:externally_locked Template Class `externally_locked`]
  1519. // #include <boost/thread/externally_locked.hpp>
  1520. template <class T, typename MutexType>
  1521. class externally_locked
  1522. {
  1523. //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
  1524. BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
  1525. public:
  1526. typedef MutexType mutex_type;
  1527. externally_locked(mutex_type& mtx, const T& obj);
  1528. externally_locked(mutex_type& mtx,T&& obj);
  1529. explicit externally_locked(mutex_type& mtx);
  1530. externally_locked(externally_locked const& rhs);
  1531. externally_locked(externally_locked&& rhs);
  1532. externally_locked& operator=(externally_locked const& rhs);
  1533. externally_locked& operator=(externally_locked&& rhs);
  1534. // observers
  1535. T& get(strict_lock<mutex_type>& lk);
  1536. const T& get(strict_lock<mutex_type>& lk) const;
  1537. template <class Lock>
  1538. T& get(nested_strict_lock<Lock>& lk);
  1539. template <class Lock>
  1540. const T& get(nested_strict_lock<Lock>& lk) const;
  1541. template <class Lock>
  1542. T& get(Lock& lk);
  1543. template <class Lock>
  1544. T const& get(Lock& lk) const;
  1545. mutex_type* mutex() const noexcept;
  1546. // modifiers
  1547. void lock();
  1548. void unlock();
  1549. bool try_lock();
  1550. void swap(externally_locked&);
  1551. };
  1552. `externally_locked` is a model of __Lockable, it cloaks an object of type `T`, and actually provides full
  1553. access to that object through the get and set member functions, provided you
  1554. pass a reference to a strict lock object.
  1555. Only the specificities respect to __Lockable are described here.
  1556. [///////////////////////////////]
  1557. [section:constructor1 `externally_locked(mutex_type&, const T&)`]
  1558. externally_locked(mutex_type& mtx, const T& obj);
  1559. [variablelist
  1560. [[Requires:] [T is a model of CopyConstructible.]]
  1561. [[Effects:] [Constructs an externally locked object copying the cloaked type.]]
  1562. [[Throws:] [Any exception thrown by the call to `T(obj)`.]]
  1563. ]
  1564. [endsect]
  1565. [///////////////////////////////]
  1566. [section:constructor2 `externally_locked(mutex_type&, T&&)`]
  1567. externally_locked(mutex_type& mtx,T&& obj);
  1568. [variablelist
  1569. [[Requires:] [T is a model of Movable.]]
  1570. [[Effects:] [Constructs an externally locked object by moving the cloaked type.]]
  1571. [[Throws:] [Any exception thrown by the call to `T(obj)`.]]
  1572. ]
  1573. [endsect]
  1574. [///////////////////////////////]
  1575. [section:constructor3 `externally_locked(mutex_type&)`]
  1576. externally_locked(mutex_type& mtx);
  1577. [variablelist
  1578. [[Requires:] [T is a model of DefaultConstructible.]]
  1579. [[Effects:] [Constructs an externally locked object by default constructing the cloaked type.]]
  1580. [[Throws:] [Any exception thrown by the call to `T()`.]]
  1581. ]
  1582. [endsect]
  1583. [///////////////////////////////]
  1584. [section:constructor4 `externally_locked(externally_locked&&)`]
  1585. externally_locked(externally_locked&& rhs);
  1586. [variablelist
  1587. [[Requires:] [T is a model of Movable.]]
  1588. [[Effects:] [Move constructs an externally locked object by moving the cloaked type and copying the mutex reference ]]
  1589. [[Throws:] [Any exception thrown by the call to `T(T&&)`.]]
  1590. ]
  1591. [endsect]
  1592. [///////////////////////////////]
  1593. [section:constructor5 `externally_locked(externally_locked&)`]
  1594. externally_locked(externally_locked& rhs);
  1595. [variablelist
  1596. [[Requires:] [T is a model of Copyable.]]
  1597. [[Effects:] [Copy constructs an externally locked object by copying the cloaked type and copying the mutex reference ]]
  1598. [[Throws:] [Any exception thrown by the call to `T(T&)`.]]
  1599. ]
  1600. [endsect]
  1601. [///////////////////////////////]
  1602. [section:assign4 `externally_locked(externally_locked&&)`]
  1603. externally_locked& operator=(externally_locked&& rhs);
  1604. [variablelist
  1605. [[Requires:] [T is a model of Movable.]]
  1606. [[Effects:] [Move assigns an externally locked object by moving the cloaked type and copying the mutex reference ]]
  1607. [[Throws:] [Any exception thrown by the call to `T::operator=(T&&)`.]]
  1608. ]
  1609. [endsect]
  1610. [///////////////////////////////]
  1611. [section:assign5 `externally_locked(externally_locked&)`]
  1612. externally_locked& operator=(externally_locked const& rhs);
  1613. [variablelist
  1614. [[Requires:] [T is a model of Copyable.]]
  1615. [[Effects:] [Copy assigns an externally locked object by copying the cloaked type and copying the mutex reference ]]
  1616. [[Throws:] [Any exception thrown by the call to `T::operator=(T&)`.]]
  1617. ]
  1618. [endsect]
  1619. [///////////////////////////////]
  1620. [section:get1 `get(strict_lock<mutex_type>&)`]
  1621. T& get(strict_lock<mutex_type>& lk);
  1622. const T& get(strict_lock<mutex_type>& lk) const;
  1623. [variablelist
  1624. [[Requires:] [The `lk` parameter must be locking the associated mutex.]]
  1625. [[Returns:] [A reference to the cloaked object ]]
  1626. [[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
  1627. ]
  1628. [endsect]
  1629. [///////////////////////////////]
  1630. [section:get2 `get(nested_strict_lock<Lock>&)`]
  1631. template <class Lock>
  1632. T& get(nested_strict_lock<Lock>& lk);
  1633. template <class Lock>
  1634. const T& get(nested_strict_lock<Lock>& lk) const;
  1635. [variablelist
  1636. [[Requires:] [`is_same<mutex_type, typename Lock::mutex_type>` and the `lk` parameter must be locking the associated mutex.]]
  1637. [[Returns:] [A reference to the cloaked object ]]
  1638. [[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
  1639. ]
  1640. [endsect]
  1641. [///////////////////////////////]
  1642. [section:get3 `get(Lock&)`]
  1643. template <class Lock>
  1644. T& get(Lock& lk);
  1645. template <class Lock>
  1646. T const& get(Lock& lk) const;
  1647. [variablelist
  1648. [[Requires:] [`Lock` is a model of __StrictLock, `is_same<mutex_type, typename Lock::mutex_type>` and the `lk` parameter must be locking the associated mutex.]]
  1649. [[Returns:] [A reference to the cloaked object ]]
  1650. [[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
  1651. ]
  1652. [endsect]
  1653. [endsect]
  1654. [section:externally_locked_ref Template Class `externally_locked<T&>`]
  1655. // #include <boost/thread/externally_locked.hpp>
  1656. template <class T, typename MutexType>
  1657. class externally_locked<T&, MutexType>
  1658. {
  1659. //BOOST_CONCEPT_ASSERT(( CopyConstructible<T> ));
  1660. BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
  1661. public:
  1662. typedef MutexType mutex_type;
  1663. externally_locked(mutex_type& mtx, T& obj);
  1664. explicit externally_locked(mutex_type& mtx);
  1665. externally_locked(externally_locked const& rhs) noexcept;
  1666. externally_locked(externally_locked&& rhs) noexcept;
  1667. externally_locked& operator=(externally_locked const& rhs) noexcept;
  1668. externally_locked& operator=(externally_locked&& rhs) noexcept;
  1669. // observers
  1670. T& get(strict_lock<mutex_type>& lk);
  1671. const T& get(strict_lock<mutex_type>& lk) const;
  1672. template <class Lock>
  1673. T& get(nested_strict_lock<Lock>& lk);
  1674. template <class Lock>
  1675. const T& get(nested_strict_lock<Lock>& lk) const;
  1676. template <class Lock>
  1677. T& get(Lock& lk);
  1678. template <class Lock>
  1679. T const& get(Lock& lk) const;
  1680. mutex_type* mutex() const noexcept;
  1681. // modifiers
  1682. void lock();
  1683. void unlock();
  1684. bool try_lock();
  1685. void swap(externally_locked&) noexcept;
  1686. };
  1687. `externally_locked` is a model of __Lockable, it cloaks an object of type `T`, and actually provides full
  1688. access to that object through the get and set member functions, provided you
  1689. pass a reference to a strict lock object.
  1690. Only the specificities respect to __Lockable are described here.
  1691. [///////////////////////////////]
  1692. [section:constructor1 `externally_locked<T&>(mutex_type&, T&)`]
  1693. externally_locked<T&>(mutex_type& mtx, T& obj) noexcept;
  1694. [variablelist
  1695. [[Effects:] [Constructs an externally locked object copying the cloaked reference.]]
  1696. ]
  1697. [endsect]
  1698. [///////////////////////////////]
  1699. [section:constructor4 `externally_locked<T&>(externally_locked&&)`]
  1700. externally_locked(externally_locked&& rhs) noexcept;
  1701. [variablelist
  1702. [[Effects:] [Moves an externally locked object by moving the cloaked type and copying the mutex reference ]]
  1703. ]
  1704. [endsect]
  1705. [///////////////////////////////]
  1706. [section:assign4 `externally_locked(externally_locked&&)`]
  1707. externally_locked& operator=(externally_locked&& rhs);
  1708. [variablelist
  1709. [[Effects:] [Move assigns an externally locked object by copying the cloaked reference and copying the mutex reference ]]
  1710. ]
  1711. [endsect]
  1712. [///////////////////////////////]
  1713. [section:assign5 `externally_locked(externally_locked&)`]
  1714. externally_locked& operator=(externally_locked const& rhs);
  1715. [variablelist
  1716. [[Requires:] [T is a model of Copyable.]]
  1717. [[Effects:] [Copy assigns an externally locked object by copying the cloaked reference and copying the mutex reference ]]
  1718. [[Throws:] [Any exception thrown by the call to `T::operator=(T&)`.]]
  1719. ]
  1720. [endsect]
  1721. [///////////////////////////////]
  1722. [section:get1 `get(strict_lock<mutex_type>&)`]
  1723. T& get(strict_lock<mutex_type>& lk);
  1724. const T& get(strict_lock<mutex_type>& lk) const;
  1725. [variablelist
  1726. [[Requires:] [The `lk` parameter must be locking the associated mutex.]]
  1727. [[Returns:] [A reference to the cloaked object ]]
  1728. [[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
  1729. ]
  1730. [endsect]
  1731. [///////////////////////////////]
  1732. [section:get2 `get(nested_strict_lock<Lock>&)`]
  1733. template <class Lock>
  1734. T& get(nested_strict_lock<Lock>& lk);
  1735. template <class Lock>
  1736. const T& get(nested_strict_lock<Lock>& lk) const;
  1737. [variablelist
  1738. [[Requires:] [`is_same<mutex_type, typename Lock::mutex_type>` and the `lk` parameter must be locking the associated mutex.]]
  1739. [[Returns:] [A reference to the cloaked object ]]
  1740. [[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
  1741. ]
  1742. [endsect]
  1743. [///////////////////////////////]
  1744. [section:get3 `get(Lock&)`]
  1745. template <class Lock>
  1746. T& get(Lock& lk);
  1747. template <class Lock>
  1748. T const& get(Lock& lk) const;
  1749. [variablelist
  1750. [[Requires:] [`Lock` is a model of __StrictLock, `is_same<mutex_type, typename Lock::mutex_type>` and the `lk` parameter must be locking the associated mutex.]]
  1751. [[Returns:] [A reference to the cloaked object ]]
  1752. [[Throws:] [__lock_error__ if `BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED` is defined and the run-time preconditions are not satisfied .]]
  1753. ]
  1754. [endsect]
  1755. [endsect]
  1756. [///////////////////////////////]
  1757. [section:swap `swap(externally_locked&, externally_locked&)`]
  1758. template <typename T, typename MutexType>
  1759. void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs)
  1760. [endsect]
  1761. [endsect]
  1762. [section:shared_lock_guard Class template `shared_lock_guard`]
  1763. // #include <boost/thread/shared_lock_guard.hpp>
  1764. namespace boost
  1765. {
  1766. template<typename SharedLockable>
  1767. class shared_lock_guard
  1768. {
  1769. public:
  1770. shared_lock_guard(shared_lock_guard const&) = delete;
  1771. shared_lock_guard& operator=(shared_lock_guard const&) = delete;
  1772. explicit shared_lock_guard(SharedLockable& m_);
  1773. shared_lock_guard(SharedLockable& m_,boost::adopt_lock_t);
  1774. ~shared_lock_guard();
  1775. };
  1776. }
  1777. __shared_lock_guard is very simple: on construction it
  1778. acquires shared ownership of the implementation of the __shared_lockable_concept__ supplied as
  1779. the constructor parameter. On destruction, the ownership is released. This
  1780. provides simple RAII-style locking of a __shared_lockable_concept_type__ object, to facilitate exception-safe
  1781. shared locking and unlocking.
  1782. In addition, the `__shared_lock_guard_constructor_adopt(SharedLockable &m, boost::adopt_lock_t)` constructor allows the __shared_lock_guard object to
  1783. take shared ownership of a lock already held by the current thread.
  1784. [section:constructor `shared_lock_guard(SharedLockable & m)`]
  1785. [variablelist
  1786. [[Effects:] [Stores a reference to `m`. Invokes `m.__lock_shared()`.]]
  1787. [[Throws:] [Any exception thrown by the call to `m.__lock_shared()`.]]
  1788. ]
  1789. [endsect]
  1790. [section:constructor_adopt `shared_lock_guard(SharedLockable & m,boost::adopt_lock_t)`]
  1791. [variablelist
  1792. [[Precondition:] [The current thread owns a lock on `m` equivalent to one
  1793. obtained by a call to `m.__lock_shared()`.]]
  1794. [[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of
  1795. `m`.]]
  1796. [[Throws:] [Nothing.]]
  1797. ]
  1798. [endsect]
  1799. [section:destructor `~shared_lock_guard()`]
  1800. [variablelist
  1801. [[Effects:] [Invokes `m.__unlock_shared()` on the __shared_lockable_concept_type__ object passed to the constructor.]]
  1802. [[Throws:] [Nothing.]]
  1803. ]
  1804. [endsect]
  1805. [endsect]
  1806. [section:reverse_lock Class template `reverse_lock`]
  1807. // #include <boost/thread/reverse_lock.hpp>
  1808. namespace boost
  1809. {
  1810. template<typename Lock>
  1811. class reverse_lock
  1812. {
  1813. public:
  1814. reverse_lock(reverse_lock const&) = delete;
  1815. reverse_lock& operator=(reverse_lock const&) = delete;
  1816. explicit reverse_lock(Lock& m_);
  1817. ~reverse_lock();
  1818. };
  1819. }
  1820. __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.
  1821. An instance of __reverse_lock doesn't ['own] the lock never.
  1822. [section:constructor `reverse_lock(Lock & m)`]
  1823. [variablelist
  1824. [[Effects:] [Stores a reference to `m`. Invokes `m.__unlock()` if `m` owns his lock and then stores the mutex by calling `m.release()`.]]
  1825. [[Postcondition:] [`!m.__owns_lock() && m.mutex()==0`.]]
  1826. [[Throws:] [Any exception thrown by the call to `m.__unlock()`.]]
  1827. ]
  1828. [endsect]
  1829. [section:destructor `~reverse_lock()`]
  1830. [variablelist
  1831. [[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.]]
  1832. [[Throws:] [Any exception thrown by `mtx->__lock()`.]]
  1833. [[Remarks:] [Note that if `mtx->__lock()` throws an exception while unwinding the program will terminate, so don't use reverse_lock if an exception can be thrown.]]
  1834. ]
  1835. [endsect]
  1836. [endsect] [/ reverse_lock<>]
  1837. [endsect]
  1838. [section:lock_functions Lock functions]
  1839. [section:lock_multiple Non-member function `lock(Lockable1,Lockable2,...)`]
  1840. // #include <boost/thread/locks.hpp>
  1841. // #include <boost/thread/lock_algorithms.hpp>
  1842. namespace boost
  1843. {
  1844. template<typename Lockable1,typename Lockable2>
  1845. void lock(Lockable1& l1,Lockable2& l2);
  1846. template<typename Lockable1,typename Lockable2,typename Lockable3>
  1847. void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3);
  1848. template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4>
  1849. void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4);
  1850. template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4,typename Lockable5>
  1851. void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4,Lockable5& l5);
  1852. }
  1853. [variablelist
  1854. [[Effects:] [Locks the __lockable_concept_type__ objects supplied as
  1855. arguments in an unspecified and indeterminate order in a way that
  1856. avoids deadlock. It is safe to call this function concurrently from
  1857. multiple threads for any set of mutexes (or other lockable objects) in
  1858. any order without risk of deadlock. If any of the __lock_ref__
  1859. or __try_lock_ref__ operations on the supplied
  1860. __lockable_concept_type__ objects throws an exception any locks
  1861. acquired by the function will be released before the function exits.]]
  1862. [[Throws:] [Any exceptions thrown by calling __lock_ref__ or
  1863. __try_lock_ref__ on the supplied __lockable_concept_type__ objects.]]
  1864. [[Postcondition:] [All the supplied __lockable_concept_type__ objects
  1865. are locked by the calling thread.]]
  1866. ]
  1867. [endsect]
  1868. [section:lock_range Non-member function `lock(begin,end)` // EXTENSION]
  1869. template<typename ForwardIterator>
  1870. void lock(ForwardIterator begin,ForwardIterator end);
  1871. [variablelist
  1872. [[Preconditions:] [The `value_type` of `ForwardIterator` must implement the __lockable_concept__]]
  1873. [[Effects:] [Locks all the __lockable_concept_type__ objects in the
  1874. supplied range in an unspecified and indeterminate order in a way that
  1875. avoids deadlock. It is safe to call this function concurrently from
  1876. multiple threads for any set of mutexes (or other lockable objects) in
  1877. any order without risk of deadlock. If any of the __lock_ref__
  1878. or __try_lock_ref__ operations on the __lockable_concept_type__
  1879. objects in the supplied range throws an exception any locks acquired
  1880. by the function will be released before the function exits.]]
  1881. [[Throws:] [Any exceptions thrown by calling __lock_ref__ or
  1882. __try_lock_ref__ on the supplied __lockable_concept_type__ objects.]]
  1883. [[Postcondition:] [All the __lockable_concept_type__ objects in the
  1884. supplied range are locked by the calling thread.]]
  1885. ]
  1886. [endsect]
  1887. [section:try_lock_multiple Non-member function `try_lock(Lockable1,Lockable2,...)`]
  1888. template<typename Lockable1,typename Lockable2>
  1889. int try_lock(Lockable1& l1,Lockable2& l2);
  1890. template<typename Lockable1,typename Lockable2,typename Lockable3>
  1891. int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3);
  1892. template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4>
  1893. int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4);
  1894. template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4,typename Lockable5>
  1895. int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4,Lockable5& l5);
  1896. [variablelist
  1897. [[Effects:] [Calls __try_lock_ref__ on each of the
  1898. __lockable_concept_type__ objects supplied as arguments. If any of the
  1899. calls to __try_lock_ref__ returns `false` then all locks acquired are
  1900. released and the zero-based index of the failed lock is returned.
  1901. If any of the __try_lock_ref__ operations on the supplied
  1902. __lockable_concept_type__ objects throws an exception any locks
  1903. acquired by the function will be released before the function exits.]]
  1904. [[Returns:] [`-1` if all the supplied __lockable_concept_type__ objects
  1905. are now locked by the calling thread, the zero-based index of the
  1906. object which could not be locked otherwise.]]
  1907. [[Throws:] [Any exceptions thrown by calling __try_lock_ref__ on the
  1908. supplied __lockable_concept_type__ objects.]]
  1909. [[Postcondition:] [If the function returns `-1`, all the supplied
  1910. __lockable_concept_type__ objects are locked by the calling
  1911. thread. Otherwise any locks acquired by this function will have been
  1912. released.]]
  1913. ]
  1914. [endsect]
  1915. [section:try_lock_range Non-member function `try_lock(begin,end)` // EXTENSION]
  1916. template<typename ForwardIterator>
  1917. ForwardIterator try_lock(ForwardIterator begin,ForwardIterator end);
  1918. [variablelist
  1919. [[Preconditions:] [The `value_type` of `ForwardIterator` must implement the __lockable_concept__]]
  1920. [[Effects:] [Calls __try_lock_ref__ on each of the
  1921. __lockable_concept_type__ objects in the supplied range. If any of the
  1922. calls to __try_lock_ref__ returns `false` then all locks acquired are
  1923. released and an iterator referencing the failed lock is returned.
  1924. If any of the __try_lock_ref__ operations on the supplied
  1925. __lockable_concept_type__ objects throws an exception any locks
  1926. acquired by the function will be released before the function exits.]]
  1927. [[Returns:] [`end` if all the supplied __lockable_concept_type__
  1928. objects are now locked by the calling thread, an iterator referencing
  1929. the object which could not be locked otherwise.]]
  1930. [[Throws:] [Any exceptions thrown by calling __try_lock_ref__ on the
  1931. supplied __lockable_concept_type__ objects.]]
  1932. [[Postcondition:] [If the function returns `end` then all the
  1933. __lockable_concept_type__ objects in the supplied range are locked by
  1934. the calling thread, otherwise all locks acquired by the function have
  1935. been released.]]
  1936. ]
  1937. [endsect]
  1938. [endsect]
  1939. [section:lock_factories Lock Factories - EXTENSION]
  1940. namespace boost
  1941. {
  1942. template <typename Lockable>
  1943. unique_lock<Lockable> make_unique_lock(Lockable& mtx); // EXTENSION
  1944. template <typename Lockable>
  1945. unique_lock<Lockable> make_unique_lock(Lockable& mtx, adopt_lock_t); // EXTENSION
  1946. template <typename Lockable>
  1947. unique_lock<Lockable> make_unique_lock(Lockable& mtx, defer_lock_t); // EXTENSION
  1948. template <typename Lockable>
  1949. unique_lock<Lockable> make_unique_lock(Lockable& mtx, try_to_lock_t); // EXTENSION
  1950. #if ! defined(BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS)
  1951. template <typename ...Lockable>
  1952. std::tuple<unique_lock<Lockable> ...> make_unique_locks(Lockable& ...mtx); // EXTENSION
  1953. #endif
  1954. }
  1955. [section:make_unique_lock Non Member Function `make_unique_lock(Lockable&)`]
  1956. template <typename Lockable>
  1957. unique_lock<Lockable> make_unique_lock(Lockable& mtx); // EXTENSION
  1958. [variablelist
  1959. [[Returns:] [a __unique_lock as if initialized with `unique_lock<Lockable>(mtx)`.]]
  1960. [[Throws:] [Any exception thrown by the call to `__unique_lock<Lockable>(mtx)`.]]
  1961. ]
  1962. [endsect]
  1963. [section:make_unique_lock_t Non Member Function `make_unique_lock(Lockable&,tag)`]
  1964. template <typename Lockable>
  1965. unique_lock<Lockable> make_unique_lock(Lockable& mtx, adopt_lock_t tag); // EXTENSION
  1966. template <typename Lockable>
  1967. unique_lock<Lockable> make_unique_lock(Lockable& mtx, defer_lock_t tag); // EXTENSION
  1968. template <typename Lockable>
  1969. unique_lock<Lockable> make_unique_lock(Lockable& mtx, try_to_lock_t tag); // EXTENSION
  1970. [variablelist
  1971. [[Returns:] [a __unique_lock as if initialized with `unique_lock<Lockable>(mtx, tag)`.]]
  1972. [[Throws:] [Any exception thrown by the call to `__unique_lock<Lockable>(mtx, tag)`.]]
  1973. ]
  1974. [endsect]
  1975. [section:make_unique_locks Non Member Function `make_unique_locks(Lockable& ...)`]
  1976. template <typename ...Lockable>
  1977. std::tuple<unique_lock<Lockable> ...> make_unique_locks(Lockable& ...mtx); // EXTENSION
  1978. [variablelist
  1979. [[Effect:] [Locks all the mutexes.]]
  1980. [[Returns:] [a std::tuple of unique __unique_lock owning each one of the mutex.]]
  1981. [[Throws:] [Any exception thrown by `boost::lock(mtx...)`.]]
  1982. ]
  1983. [endsect]
  1984. [endsect]