<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2020-05-13" />
  <title>Locks lock lockables</title>
  <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
      div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
      ul.task-list{list-style: none;}
      pre > code.sourceCode { white-space: pre; position: relative; }
      pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
      pre > code.sourceCode > span:empty { height: 1.2em; }
      code.sourceCode > span { color: inherit; text-decoration: inherit; }
      div.sourceCode { margin: 1em 0; }
      pre.sourceCode { margin: 0; }
      @media screen {
      div.sourceCode { overflow: auto; }
      }
      @media print {
      pre > code.sourceCode { white-space: pre-wrap; }
      pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
      }
      pre.numberSource code
        { counter-reset: source-line 0; }
      pre.numberSource code > span
        { position: relative; left: -4em; counter-increment: source-line; }
      pre.numberSource code > span > a:first-child::before
        { content: counter(source-line);
          position: relative; left: -1em; text-align: right; vertical-align: baseline;
          border: none; display: inline-block;
          -webkit-touch-callout: none; -webkit-user-select: none;
          -khtml-user-select: none; -moz-user-select: none;
          -ms-user-select: none; user-select: none;
          padding: 0 4px; width: 4em;
          color: #aaaaaa;
        }
      pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
      div.sourceCode
        {  background-color: #f6f8fa; }
      @media screen {
      pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
      }
      code span { } /* Normal */
      code span.al { color: #ff0000; } /* Alert */
      code span.an { } /* Annotation */
      code span.at { } /* Attribute */
      code span.bn { color: #9f6807; } /* BaseN */
      code span.bu { color: #9f6807; } /* BuiltIn */
      code span.cf { color: #00607c; } /* ControlFlow */
      code span.ch { color: #9f6807; } /* Char */
      code span.cn { } /* Constant */
      code span.co { color: #008000; font-style: italic; } /* Comment */
      code span.cv { color: #008000; font-style: italic; } /* CommentVar */
      code span.do { color: #008000; } /* Documentation */
      code span.dt { color: #00607c; } /* DataType */
      code span.dv { color: #9f6807; } /* DecVal */
      code span.er { color: #ff0000; font-weight: bold; } /* Error */
      code span.ex { } /* Extension */
      code span.fl { color: #9f6807; } /* Float */
      code span.fu { } /* Function */
      code span.im { } /* Import */
      code span.in { color: #008000; } /* Information */
      code span.kw { color: #00607c; } /* Keyword */
      code span.op { color: #af1915; } /* Operator */
      code span.ot { } /* Other */
      code span.pp { color: #6f4e37; } /* Preprocessor */
      code span.re { } /* RegionMarker */
      code span.sc { color: #9f6807; } /* SpecialChar */
      code span.ss { color: #9f6807; } /* SpecialString */
      code span.st { color: #9f6807; } /* String */
      code span.va { } /* Variable */
      code span.vs { color: #9f6807; } /* VerbatimString */
      code span.wa { color: #008000; font-weight: bold; } /* Warning */
      code.diff {color: #898887}
      code.diff span.va {color: #006e28}
      code.diff span.st {color: #bf0303}
  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
}
div.wrapper {
max-width: 60em;
margin: auto;
}
ul {
list-style-type: none;
padding-left: 2em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
a.self-link {
position: absolute;
top: 0;
left: calc(-1 * (3.5rem - 26px));
width: calc(3.5rem - 26px);
height: 2em;
text-align: center;
border: none;
transition: opacity .2s;
opacity: .5;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }
</style>
  <style type="text/css">a {
color : #4183C4;
text-decoration: underline;
}
a.marginalized {
text-decoration: none;
}
a.self-link {
text-decoration: none;
}
h1#toctitle {
border-bottom: 1px solid #cccccc;
}
#TOC li {
margin-top: 1px;
margin-bottom: 1px;
}
#TOC ul>li:before { display: none; }
h3.subtitle { margin-top: -15px; }
h1:target { background-color: transparent; }
h2:target { background-color: transparent; }
h3:target { background-color: transparent; }
h4:target { background-color: transparent; }
h5:target { background-color: transparent; }
h6:target { background-color: transparent; }
code span.co { font-family: monospace; }
table tr {
background-color: white;
}
table tr:nth-child(2n) {
background-color: #f6f8fa;
}
#title-block-header > table tr:nth-child(2n) {
background-color: white;
}
td > div.sourceCode {
background-color: inherit;
}
table {
border-collapse: collapse;
}
table td, table th {
border: 1px solid #cccccc;
}
table th {
border-bottom: 1px solid black;
text-align: center;
}
table tr:first-child th {
border-top: 0;
}
table tr:last-child td {
border-bottom: 0;
}
table tr td:first-child,
table tr th:first-child {
border-left: 0;
}
table tr td:last-child,
table tr th:last-child {
border-right: 0;
}
table tbody tr:first-child td {
border-top: 1px solid black;
}
#title-block-header td { border: 0; }
@media all {
body {
margin: 2em;
}
}
@media screen and (min-width: 480px) {
body {
margin: 5em;
}
}
#refs code{padding-left: 0px; text-indent: 0px;}
:root {
--diff-ins: #e6ffed;
--diff-strongins: #acf2bd;
--diff-del: #ffdddd;
--diff-strongdel: #ff8888;
}
span.diffins {
background-color: var(--diff-strongins);
}
span.diffdel {
background-color: var(--diff-strongdel);
}
div.rm { text-decoration: line-through; }
div.rm code.sourceCode { text-decoration: line-through; }
div.addu, span.addu {
color: #006e28;
background-color: var(--diff-ins);
}

div.rm pre, div.add pre { background-color: #f6f8fa; }
div.addu pre { background-color: var(--diff-ins); }
div.add, div.add pre, div.add blockquote { background-color: var(--diff-ins); }
div.addu blockquote {
border-left: 4px solid #00a000;
padding: 0 15px;
color: #006e28;
text-decoration: none;
}
div.addu blockquote code.sourceCode { text-decoration: none; }
div.addu blockquote pre { text-decoration: none; }
div.addu blockquote pre code { text-decoration: none; }
code.diff span.va { color: #000000; background-color: var(--diff-ins); }
code.diff span.st { color: #000000; background-color: var(--diff-del); }
blockquote { background-color: #f6f8fa; }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
  
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Locks lock lockables</h1>
<h3 class="subtitle" style="text-align:center">Wording for LWG 2363</h3>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P2160R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2020-05-13</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      LWG<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Tim Song<br>&lt;<a href="mailto:t.canens.cpp@gmail.com" class="email">t.canens.cpp@gmail.com</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<h1 data-number="1" style="border-bottom:1px solid #cccccc" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>This paper provides wording to clean up <span>32.5.4 <a href="https://wg21.link/thread.lock">[thread.lock]</a></span> and resolve <span class="citation" data-cites="LWG2363">[<a href="#ref-LWG2363" role="doc-biblioref">LWG2363</a>]</span>.</p>
<h1 data-number="2" style="border-bottom:1px solid #cccccc" id="drafting-notes"><span class="header-section-number">2</span> Drafting notes<a href="#drafting-notes" class="self-link"></a></h1>
<p>The original complaint of <span class="citation" data-cites="LWG2363">[<a href="#ref-LWG2363" role="doc-biblioref">LWG2363</a>]</span> (a nonexistent <em>SharedTimedMutex</em> named requirement) has since been editorially resolved, and since these requirements are only intended to be used for standard library types rather than user code, I don’t see a need to promote them to <em>CamelCased</em> named requirements as in the current PR.</p>
<p>However, the previous drafting did reveal additional issues:</p>
<ol type="1">
<li>the current WP says that <code class="sourceCode cpp">shared_lock<span class="op">&lt;</span>Mutex<span class="op">&gt;</span></code> requires <code class="sourceCode cpp">Mutex</code> to meet the “shared mutex requirements <span>32.5.3.5 <a href="https://wg21.link/thread.sharedtimedmutex.requirements">[thread.sharedtimedmutex.requirements]</a></span>”; this is a mismatch and also seemingly makes <code class="sourceCode cpp">shared_lock<span class="op">&lt;</span>shared_mutex<span class="op">&gt;</span></code> undefined behavior outright even if the user doesn’t call the timed wait functions.</li>
<li>the current wording for <code class="sourceCode cpp">shared_lock</code> appears to disallow user-defined shared mutex types, because it references our internal requirements. This is a clear defect.</li>
<li>There is a pervasive problem throughout <span>32.5.4 <a href="https://wg21.link/thread.lock">[thread.lock]</a></span> that conflates the preconditions of lock operations with the preconditions of the underlying lockable operations, and also confuses lockables with mutexes. The locks operate on lockables, so it’s a category error to ask whether the lockable is a “recursive mutex” (not to mention that this term is never properly defined); we should just forward to the underlying lockable and let that operation do whatever it does, whether that’s properly recursive locking, throwing an exception, or impregnating someone’s nonexistent cat.</li>
</ol>
<p>The wording below introduces new <em>Cpp17SharedLockable</em> and <em>Cpp17SharedTimedLockable</em> named requirements. I decided to add the <em>Cpp17</em> prefix because they deal with components added in C++17. Because the existing <em>Cpp17MeowLockable</em> requirements are very explicit that they do not deal with the nature of any lock ownership, the same is true for the new requirements. As far as the lockable requirements are concerned, “shared” and “non-shared” locks are distinguished solely by the functions used to acquire them.</p>
<p>As discussed above, the wording removes most explicit preconditions on lock constructors that are of the form “the calling thread does not own the mutex”; when instantiated with types that do not support recursive locking (and consider such attempts undefined behavior), this precondition is implicitly imposed by the call to the locking functions the constructors are specified to perform.</p>
<p>The <code class="sourceCode cpp">adopt_lock_t</code> overloads retain their precondition that the lock has been acquired, but re-expressed in lockable terms. This is not strictly necessary - failure to lock results in a precondition violation when the unlocking occurs - but appears to be harmless and potentially permits early diagnosis.</p>
<h1 data-number="3" style="border-bottom:1px solid #cccccc" id="open-issues"><span class="header-section-number">3</span> Open issues<a href="#open-issues" class="self-link"></a></h1>
<ul>
<li>An earlier draft of this paper included <em>Cpp17Lockable</em> in the <em>Cpp17SharedLockable</em> requirements and similarly included <em>Cpp17TimedLockable</em> in the <em>Cpp17SharedTimedLockable</em> requirements. However, <code class="sourceCode cpp">shared_lock</code> does not appear to have a reason to care whether the lockable also allows non-shared locking, and those requirements have been removed from this version. Do we want to reinstate them?</li>
</ul>
<h1 data-number="4" style="border-bottom:1px solid #cccccc" id="wording"><span class="header-section-number">4</span> Wording<a href="#wording" class="self-link"></a></h1>
<p>This wording is relative to <span class="citation" data-cites="N4861">[<a href="#ref-N4861" role="doc-biblioref">N4861</a>]</span>.</p>
<div>
<ol type="1">
<li>Edit <span>32.2.5 <a href="https://wg21.link/thread.req.lockable">[thread.req.lockable]</a></span> p3 as indicated:</li>
</ol>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> The standard library templates <code class="sourceCode cpp">unique_­lock</code> (<span>32.5.4.3 <a href="https://wg21.link/thread.lock.unique">[thread.lock.unique]</a></span>), <code class="sourceCode cpp">shared_­lock</code> (<span>32.5.4.4 <a href="https://wg21.link/thread.lock.shared">[thread.lock.shared]</a></span>), <code class="sourceCode cpp">scoped_­lock</code> (<span>32.5.4.2 <a href="https://wg21.link/thread.lock.scoped">[thread.lock.scoped]</a></span>), <code class="sourceCode cpp">lock_­guard</code> (<span>32.5.4.1 <a href="https://wg21.link/thread.lock.guard">[thread.lock.guard]</a></span>), <code class="sourceCode cpp">lock</code>, <code class="sourceCode cpp">try_­lock</code> (<span>32.5.5 <a href="https://wg21.link/thread.lock.algorithm">[thread.lock.algorithm]</a></span>), and <code class="sourceCode cpp">condition_­variable_­any</code> (<span>32.6.4 <a href="https://wg21.link/thread.condition.condvarany">[thread.condition.condvarany]</a></span>) all operate on user-supplied lockable objects. The <em>Cpp17BasicLockable</em> requirements, the <em>Cpp17Lockable</em> requirements, <span class="diffdel">and</span> the <em>Cpp17TimedLockable</em> requirements<span class="diffins">, the <em>Cpp17SharedLockable</em> requirements, and the <em>Cpp17SharedTimedLockable</em> requirements</span> list the requirements imposed by these library types in order to acquire or release ownership of a lock by a given execution agent. <span class="note"><span>[ <em>Note:</em> </span>The nature of any lock ownership and any synchronization it entails are not part of these requirements.<span> — <em>end note</em> ]</span></span></p>
</blockquote>
<ol start="2" type="1">
<li>Add the following paragraph at the end of <span>32.2.5 <a href="https://wg21.link/thread.req.lockable">[thread.req.lockable]</a></span>:</li>
</ol>
<blockquote>
<div class="add" style="color: #006e28">
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> A lock on an object <code class="sourceCode default">m</code> is said to be a <em>non-shared lock</em> if it is acquired by a call to <code class="sourceCode default">lock</code>, <code class="sourceCode default">try_lock</code>, <code class="sourceCode default">try_lock_for</code>, or <code class="sourceCode default">try_lock_until</code> on <code class="sourceCode default">m</code>, and a <em>shared lock</em> if it is acquired by a call to <code class="sourceCode default">lock_shared</code>, <code class="sourceCode default">try_lock_shared</code>, <code class="sourceCode default">try_lock_shared_for</code>, or <code class="sourceCode default">try_lock_shared_until</code> on <code class="sourceCode default">m</code>. <span class="note"><span>[ <em>Note:</em> </span>Only the method of lock acquisition is considered; the nature of any lock ownership is not part of these definitions.<span> — <em>end note</em> ]</span></span></p>
</div>
</blockquote>
<ol start="3" type="1">
<li>Edit <span>32.2.5.2 <a href="https://wg21.link/thread.req.lockable.basic">[thread.req.lockable.basic]</a></span> p3 as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a>m<span class="op">.</span>unlock<span class="op">()</span></span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Preconditions:</em> The current execution agent holds a <span class="diffins">non-shared</span> lock on <code class="sourceCode cpp">m</code> .</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Effects:</em> Releases a <span class="diffins">non-shared</span> lock on <code class="sourceCode cpp">m</code> held by the current execution agent.</p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Throws:</em> Nothing.</p>
</blockquote>
</div>
</blockquote>
<ol start="4" type="1">
<li>Add the following subclauses under <span>32.2.5 <a href="https://wg21.link/thread.req.lockable">[thread.req.lockable]</a></span>:</li>
</ol>
<blockquote>
<div class="add" style="color: #006e28">

<h3 id="cpp17sharedlockable-requirements-thread.req.lockable.shared" class="unnumbered">?.?.?.? <em>Cpp17SharedLockable</em> requirements [thread.req.lockable.shared]<a href="#cpp17sharedlockable-requirements-thread.req.lockable.shared" class="self-link"></a></h3>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> A type <code class="sourceCode default">L</code> meets the <em>Cpp17SharedLockable</em> requirements if the following expressions are well-formed, have the specified semantics, and the expression <code class="sourceCode default">m.try_lock_shared()</code> has type <code class="sourceCode default">bool</code> (<code class="sourceCode default">m</code> denotes a value of type <code class="sourceCode default">L</code>):</p>
<div>
<div class="sourceCode" id="cb2"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb2-1"><a href="#cb2-1"></a>m.lock_shared()</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Effects:</em> Blocks until a lock can be acquired for the current execution agent. If an exception is thrown then a lock shall not have been acquired for the current execution agent.</p>
</blockquote>
<div class="sourceCode" id="cb3"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb3-1"><a href="#cb3-1"></a>m.try_lock_shared()</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Effects:</em> Attempts to acquire a lock for the current execution agent without blocking. If an exception is thrown then a lock shall not have been acquired for the current execution agent.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Returns</em>: <code class="sourceCode default">true</code> if the lock was acquired, <code class="sourceCode default">false</code> otherwise.</p>
</blockquote>
<div class="sourceCode" id="cb4"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb4-1"><a href="#cb4-1"></a>m.unlock_shared()</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Preconditions:</em> The current execution agent holds a shared lock on <code class="sourceCode default">m</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Effects:</em> Releases a shared lock on <code class="sourceCode default">m</code> held by the current execution agent.</p>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span> <em>Throws:</em> Nothing.</p>
</blockquote>
</div>
<h3 id="cpp17sharedtimedlockable-requirements-thread.req.lockable.shared.timed" class="unnumbered">?.?.?.? <em>Cpp17SharedTimedLockable</em> requirements [thread.req.lockable.shared.timed]<a href="#cpp17sharedtimedlockable-requirements-thread.req.lockable.shared.timed" class="self-link"></a></h3>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> A type <code class="sourceCode default">L</code> meets the <em>Cpp17SharedTimedLockable</em> requirements if it meets the <em>Cpp17SharedLockable</em> requirements, and the following expressions are well-formed, have type <code class="sourceCode default">bool</code>, and have the specified semantics (<code class="sourceCode default">m</code> denotes a value of type <code class="sourceCode default">L</code>, <code class="sourceCode default">rel_­time</code> denotes a value of a specialization of <code class="sourceCode default">duration</code>, and <code class="sourceCode default">abs_­time</code> denotes a value of a specialization of <code class="sourceCode default">time_­point</code>):</p>
<div>
<div class="sourceCode" id="cb5"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb5-1"><a href="#cb5-1"></a>m.try_lock_shared_for(rel_time)</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Effects:</em> Attempts to acquire a lock for the current execution agent within the relative timeout (<span>32.2.4 <a href="https://wg21.link/thread.req.timing">[thread.req.timing]</a></span>) specified by <code class="sourceCode default">rel_­time</code>. The function will not return within the timeout specified by <code class="sourceCode default">rel_­time</code> unless it has obtained a lock on <code class="sourceCode default">m</code> for the current execution agent. If an exception is thrown then a lock has not been acquired for the current execution agent.</p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Returns</em>: <code class="sourceCode default">true</code> if the lock was acquired, <code class="sourceCode default">false</code> otherwise.</p>
</blockquote>
<div class="sourceCode" id="cb6"><pre class="sourceCode default cpp"><code class="sourceCode default"><span id="cb6-1"><a href="#cb6-1"></a>m.try_lock_shared_until(abs_time)</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Effects:</em> Attempts to acquire a lock for the current execution agent before the absolute timeout (<span>32.2.4 <a href="https://wg21.link/thread.req.timing">[thread.req.timing]</a></span>) specified by <code class="sourceCode default">abs_­time</code>. The function will not return before the timeout specified by <code class="sourceCode default">abs_­time</code> unless it has obtained a lock on <code class="sourceCode default">m</code> for the current execution agent. If an exception is thrown then a lock has not been acquired for the current execution agent.</p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Returns</em>: <code class="sourceCode default">true</code> if the lock was acquired, <code class="sourceCode default">false</code> otherwise.</p>
</blockquote>
</div>

</div>
</blockquote>
<ol start="5" type="1">
<li>Convert <span>32.5.3.2 <a href="https://wg21.link/thread.mutex.requirements.mutex">[thread.mutex.requirements.mutex]</a></span> p2 into a note:</li>
</ol>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> <span class="diffins">[ <em>Note:</em></span> The mutex types meet the <em>Cpp17Lockable</em> requirements (<span>32.2.5.3 <a href="https://wg21.link/thread.req.lockable.req">[thread.req.lockable.req]</a></span>). <span class="diffins">— <em>end note</em> ]</span></p>
</blockquote>
<ol start="6" type="1">
<li>Convert <span>32.5.3.3 <a href="https://wg21.link/thread.timedmutex.requirements">[thread.timedmutex.requirements]</a></span> p2 into a note:</li>
</ol>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> <span class="diffins">[ <em>Note:</em></span> The timed mutex types meet the <em>Cpp17TimedLockable</em> requirements (<span>32.2.5.4 <a href="https://wg21.link/thread.req.lockable.timed">[thread.req.lockable.timed]</a></span>). <span class="diffins">— <em>end note</em> ]</span></p>
</blockquote>
<ol start="7" type="1">
<li>Add a note after <span>32.5.3.4 <a href="https://wg21.link/thread.sharedmutex.requirements">[thread.sharedmutex.requirements]</a></span> p1:</li>
</ol>
<blockquote>
<div class="add" style="color: #006e28">
<p><span class="marginalizedparent"><a class="marginalized">?</a></span> <span class="note"><span>[ <em>Note:</em> </span>The shared mutex types meet the <em>Cpp17SharedLockable</em> requirements (?.?.?.? [thread.req.lockable.shared]).<span> — <em>end note</em> ]</span></span></p>
</div>
</blockquote>
<ol start="8" type="1">
<li>Add a note after <span>32.5.3.5 <a href="https://wg21.link/thread.sharedtimedmutex.requirements">[thread.sharedtimedmutex.requirements]</a></span> p1:</li>
</ol>
<blockquote>
<div class="add" style="color: #006e28">
<p><span class="marginalizedparent"><a class="marginalized">?</a></span> <span class="note"><span>[ <em>Note:</em> </span>The shared timed mutex types meet the <em>Cpp17SharedTimedLockable</em> requirements (?.?.?.? [thread.req.lockable.shared.timed]).<span> — <em>end note</em> ]</span></span></p>
</div>
</blockquote>
<ol start="9" type="1">
<li>Edit <span>32.5.4.1 <a href="https://wg21.link/thread.lock.guard">[thread.lock.guard]</a></span> as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">explicit</span> lock_guard<span class="op">(</span>mutex_type<span class="op">&amp;</span> m<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="diffdel"><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Preconditions:</em> If <code class="sourceCode cpp">mutex_­type</code> is not a recursive mutex, the calling thread does not own the mutex <code class="sourceCode cpp">m</code>.</span></p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Effects:</em> Initializes <code class="sourceCode cpp">pm</code> with <code class="sourceCode cpp">m</code>. Calls <code class="sourceCode cpp">m<span class="op">.</span>lock<span class="op">()</span></code>.</p>
</blockquote>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1"></a>lock_guard<span class="op">(</span>mutex_type<span class="op">&amp;</span> m, adopt_lock_t<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Preconditions:</em> The calling thread <span class="diffdel">owns the mutex <code class="sourceCode cpp">m</code></span> <span class="diffins">holds a non-shared lock on <code class="sourceCode cpp">m</code></span>.</p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Effects:</em> Initializes <code class="sourceCode cpp">pm</code> with <code class="sourceCode cpp">m</code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Throws:</em> Nothing.</p>
</blockquote>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1"></a><span class="op">~</span>lock_guard<span class="op">()</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span> <em>Effects:</em> <span class="diffdel">As if by</span> <span class="diffins">Equivalent to:</span> <code class="sourceCode cpp">pm<span class="op">.</span>unlock<span class="op">()</span></code>.</p>
</blockquote>
</div>
</blockquote>
<ol start="10" type="1">
<li>Edit <span>32.5.4.2 <a href="https://wg21.link/thread.lock.scoped">[thread.lock.scoped]</a></span> as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1"></a><span class="kw">explicit</span> scoped_lock<span class="op">(</span>MutexTypes<span class="op">&amp;...</span> m<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="diffdel"><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Preconditions:</em> If a <code class="sourceCode cpp">MutexTypes</code> type is not a recursive mutex, the calling thread does not own the corresponding mutex element of <code class="sourceCode cpp">m</code>.</span></p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Effects:</em> Initializes <code class="sourceCode cpp">pm</code> with <code class="sourceCode cpp">tie<span class="op">(</span>m<span class="op">...)</span></code>. Then if <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>MutexTypes<span class="op">)</span></code> is <code class="sourceCode cpp"><span class="dv">0</span></code>, no effects. Otherwise if <code class="sourceCode cpp"><span class="kw">sizeof</span><span class="op">...(</span>MutexTypes<span class="op">)</span></code> is <code class="sourceCode cpp"><span class="dv">1</span></code>, then <code class="sourceCode cpp">m<span class="op">.</span>lock<span class="op">()</span></code>. Otherwise, <code class="sourceCode cpp">lock<span class="op">(</span>m<span class="op">...)</span></code>.</p>
</blockquote>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1"></a><span class="kw">explicit</span> scoped_lock<span class="op">(</span>adopt_lock_t, MutexTypes<span class="op">&amp;...</span> m<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Preconditions:</em> The calling thread <span class="diffdel">owns all the mutexes in <code class="sourceCode cpp">m</code></span> <span class="diffins">holds a non-shared lock on each element of <code class="sourceCode cpp">m</code></span>.</p>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Effects:</em> Initializes <code class="sourceCode cpp">pm</code> with <code class="sourceCode cpp">tie<span class="op">(</span>m<span class="op">...)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Throws:</em> Nothing.</p>
</blockquote>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1"></a><span class="op">~</span>scoped_lock<span class="op">()</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span> <em>Effects:</em> For all <code class="sourceCode cpp">i</code> in <code class="sourceCode cpp"><span class="op">[</span><span class="dv">0</span>, <span class="kw">sizeof</span><span class="op">...(</span>MutexTypes<span class="op">))</span></code>, <code class="sourceCode cpp">get<span class="op">&lt;</span>i<span class="op">&gt;(</span>pm<span class="op">).</span>unlock<span class="op">()</span></code>.</p>
</blockquote>
</div>
</blockquote>
<ol start="11" type="1">
<li>Edit <span>32.5.4.3.1 <a href="https://wg21.link/thread.lock.unique.cons">[thread.lock.unique.cons]</a></span> as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1"></a><span class="kw">explicit</span> unique_lock<span class="op">(</span>mutex_type<span class="op">&amp;</span> m<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="diffdel"><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Preconditions:</em> If <code class="sourceCode cpp">mutex_­type</code> is not a recursive mutex the calling thread does not own the mutex.</span></p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Effects:</em> Calls <code class="sourceCode cpp">m<span class="op">.</span>lock<span class="op">()</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">pm <span class="op">==</span> addressof<span class="op">(</span>m<span class="op">)</span></code> and <code class="sourceCode cpp">owns <span class="op">==</span> <span class="kw">true</span></code>.</p>
</blockquote>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1"></a>unique_lock<span class="op">(</span>mutex_type<span class="op">&amp;</span> m, defer_lock_t<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> Postconditions: <code class="sourceCode cpp">pm <span class="op">==</span> addressof<span class="op">(</span>m<span class="op">)</span></code>and <code class="sourceCode cpp">owns <span class="op">==</span> <span class="kw">false</span></code>.</p>
</blockquote>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1"></a>unique_lock<span class="op">(</span>mutex_type<span class="op">&amp;</span> m, try_to_lock_t<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Preconditions:</em> The supplied <code class="sourceCode cpp">Mutex</code> type meets the <em>Cpp17Lockable</em> requirements (<span>32.2.5.3 <a href="https://wg21.link/thread.req.lockable.req">[thread.req.lockable.req]</a></span>). <span class="diffdel">If <code class="sourceCode cpp">mutex_­type</code> is not a recursive mutex the calling thread does not own the mutex.</span></p>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span> <em>Effects:</em> Calls <code class="sourceCode cpp">m<span class="op">.</span>try_­lock<span class="op">()</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">pm <span class="op">==</span> addressof<span class="op">(</span>m<span class="op">)</span></code> and <code class="sourceCode cpp">owns <span class="op">==</span> res</code>, where <code class="sourceCode cpp">res</code> is the value returned by the call to <code class="sourceCode cpp">m<span class="op">.</span>try_­lock<span class="op">()</span></code>.</p>
</blockquote>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1"></a>unique_lock<span class="op">(</span>mutex_type<span class="op">&amp;</span> m, adopt_lock_t<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span> <em>Preconditions:</em> The calling thread <span class="diffdel">owns the mutex</span> <span class="diffins">holds a non-shared lock on <code class="sourceCode cpp">m</code></span>.</p>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">pm <span class="op">==</span> addressof<span class="op">(</span>m<span class="op">)</span></code> and <code class="sourceCode cpp">owns <span class="op">==</span> <span class="kw">true</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span> <em>Throws:</em> Nothing.</p>
</blockquote>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> Clock, <span class="kw">class</span> Duration<span class="op">&gt;</span></span>
<span id="cb17-2"><a href="#cb17-2"></a>  unique_lock<span class="op">(</span>mutex_type<span class="op">&amp;</span> m, <span class="kw">const</span> chrono<span class="op">::</span>time_point<span class="op">&lt;</span>Clock, Duration<span class="op">&gt;&amp;</span> abs_time<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span> <em>Preconditions:</em> <span class="diffdel">If <code class="sourceCode cpp">mutex_­type</code> is not a recursive mutex the calling thread does not own the mutex.</span> The supplied <code class="sourceCode cpp">Mutex</code> type meets the <em>Cpp17TimedLockable</em> requirements (<span>32.2.5.4 <a href="https://wg21.link/thread.req.lockable.timed">[thread.req.lockable.timed]</a></span>).</p>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span> <em>Effects:</em> Calls <code class="sourceCode cpp">m<span class="op">.</span>try_­lock_­until<span class="op">(</span>abs_­time<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">14</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">pm <span class="op">==</span> addressof<span class="op">(</span>m<span class="op">)</span></code> and <code class="sourceCode cpp">owns <span class="op">==</span> res</code>, where <code class="sourceCode cpp">res</code> is the value returned by the call to <code class="sourceCode cpp">m<span class="op">.</span>try_­lock_­until<span class="op">(</span>abs_­time<span class="op">)</span></code>.</p>
</blockquote>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> Rep, <span class="kw">class</span> Period<span class="op">&gt;</span></span>
<span id="cb18-2"><a href="#cb18-2"></a>  unique_lock<span class="op">(</span>mutex_type<span class="op">&amp;</span> m, <span class="kw">const</span> chrono<span class="op">::</span>duration<span class="op">&lt;</span>Rep, Period<span class="op">&gt;&amp;</span> rel_time<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">15</a></span> <em>Preconditions:</em> <span class="diffdel">If <code class="sourceCode cpp">mutex_­type</code> is not a recursive mutex the calling thread does not own the mutex.</span> The supplied <code class="sourceCode cpp">Mutex</code> type meets the <em>Cpp17TimedLockable</em> requirements (<span>32.2.5.4 <a href="https://wg21.link/thread.req.lockable.timed">[thread.req.lockable.timed]</a></span>).</p>
<p><span class="marginalizedparent"><a class="marginalized">16</a></span> <em>Effects:</em> Calls <code class="sourceCode cpp">m<span class="op">.</span>try_­lock_­for<span class="op">(</span>rel_­time<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">17</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">pm <span class="op">==</span> addressof<span class="op">(</span>m<span class="op">)</span></code> and <code class="sourceCode cpp">owns <span class="op">==</span> res</code>, where <code class="sourceCode cpp">res</code> is the value returned by the call to <code class="sourceCode cpp">m<span class="op">.</span>try_­lock_­for<span class="op">(</span>rel_­time<span class="op">)</span></code>.</p>
</blockquote>
</div>
</blockquote>
<ol start="12" type="1">
<li>Edit <span>32.5.4.4 <a href="https://wg21.link/thread.lock.shared">[thread.lock.shared]</a></span> as indicated:</li>
</ol>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">1</a></span> An object of type <code class="sourceCode cpp">shared_­lock</code> controls the shared ownership of a lockable object within a scope. Shared ownership of the lockable object may be acquired at construction or after construction, and may be transferred, after acquisition, to another <code class="sourceCode cpp">shared_­lock</code> object. Objects of type <code class="sourceCode cpp">shared_­lock</code> are not copyable but are movable. The behavior of a program is undefined if the contained pointer <code class="sourceCode cpp">pm</code> is not null and the lockable object pointed to by <code class="sourceCode cpp">pm</code> does not exist for the entire remaining lifetime (<span>6.7.3 <a href="https://wg21.link/basic.life">[basic.life]</a></span>) of the <code class="sourceCode cpp">shared_­lock</code> object. The supplied <code class="sourceCode cpp">Mutex</code> type shall meet the <span class="diffdel">shared mutex</span> <span class="diffins"><em>Cpp17SharedLockable</em></span> requirements (<span class="diffdel"><span>32.5.3.5 <a href="https://wg21.link/thread.sharedtimedmutex.requirements">[thread.sharedtimedmutex.requirements]</a></span></span> <span class="diffins">?.?.?.? [thread.req.lockable.shared]</span>).</p>
<p><span class="marginalizedparent"><a class="marginalized">2</a></span> <span class="note"><span>[ <em>Note:</em> </span><code class="sourceCode cpp">shared_­lock<span class="op">&lt;</span>Mutex<span class="op">&gt;</span></code> meets the <span class="diffins"><em>Cpp17Lockable</em> requirements (<span>32.2.5.3 <a href="https://wg21.link/thread.req.lockable.req">[thread.req.lockable.req]</a></span>). If <code class="sourceCode cpp">Mutex</code> meets the <em>Cpp17SharedTimedLockable</em> requirements (?.?.?.? [thread.req.lockable.shared.timed]), <code class="sourceCode cpp">shared_lock<span class="op">&lt;</span>Mutex<span class="op">&gt;</span></code> also meets the</span> <em>Cpp17TimedLockable</em> requirements (<span>32.2.5.4 <a href="https://wg21.link/thread.req.lockable.timed">[thread.req.lockable.timed]</a></span>).<span> — <em>end note</em> ]</span></span></p>
</blockquote>
<ol start="13" type="1">
<li>Edit <span>32.5.4.4.1 <a href="https://wg21.link/thread.lock.shared.cons">[thread.lock.shared.cons]</a></span> as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1"></a><span class="kw">explicit</span> shared_lock<span class="op">(</span>mutex_type<span class="op">&amp;</span> m<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="diffdel"><span class="marginalizedparent"><a class="marginalized">2</a></span> <em>Preconditions:</em> The calling thread does not own the mutex for any ownership mode.</span></p>
<p><span class="marginalizedparent"><a class="marginalized">3</a></span> <em>Effects:</em> Calls <code class="sourceCode cpp">m<span class="op">.</span>lock_­shared<span class="op">()</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">4</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">pm <span class="op">==</span> addressof<span class="op">(</span>m<span class="op">)</span></code> and <code class="sourceCode cpp">owns <span class="op">==</span> <span class="kw">true</span></code>.</p>
</blockquote>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1"></a>shared_lock<span class="op">(</span>mutex_type<span class="op">&amp;</span> m, defer_lock_t<span class="op">)</span> <span class="kw">noexcept</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">5</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">pm <span class="op">==</span> addressof<span class="op">(</span>m<span class="op">)</span></code> and <code class="sourceCode cpp">owns <span class="op">==</span> <span class="kw">false</span></code>.</p>
</blockquote>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1"></a>shared_lock<span class="op">(</span>mutex_type<span class="op">&amp;</span> m, try_to_lock_t<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="diffdel"><span class="marginalizedparent"><a class="marginalized">6</a></span> <em>Preconditions:</em> The calling thread does not own the mutex for any ownership mode.</span></p>
<p><span class="marginalizedparent"><a class="marginalized">7</a></span> <em>Effects:</em> Calls <code class="sourceCode cpp">m<span class="op">.</span>try_­lock_­shared<span class="op">()</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">8</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">pm <span class="op">==</span> addressof<span class="op">(</span>m<span class="op">)</span></code> and <code class="sourceCode cpp">owns <span class="op">==</span> res</code> where <code class="sourceCode cpp">res</code> is the value returned by the call to <code class="sourceCode cpp">m<span class="op">.</span>try_­lock_­shared<span class="op">()</span></code>.</p>
</blockquote>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1"></a>shared_lock<span class="op">(</span>mutex_type<span class="op">&amp;</span> m, adopt_lock_t<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">9</a></span> <em>Preconditions:</em> The calling thread <span class="diffdel">has shared ownership of the mutex.</span> <span class="diffins">holds a shared lock on <code class="sourceCode cpp">m</code>.</span></p>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">pm <span class="op">==</span> addressof<span class="op">(</span>m<span class="op">)</span></code> and <code class="sourceCode cpp">owns <span class="op">==</span> <span class="kw">true</span></code>.</p>
</blockquote>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> Clock, <span class="kw">class</span> Duration<span class="op">&gt;</span></span>
<span id="cb23-2"><a href="#cb23-2"></a>  shared_lock<span class="op">(</span>mutex_type<span class="op">&amp;</span> m,</span>
<span id="cb23-3"><a href="#cb23-3"></a>              <span class="kw">const</span> chrono<span class="op">::</span>time_point<span class="op">&lt;</span>Clock, Duration<span class="op">&gt;&amp;</span> abs_time<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span> <em>Preconditions:</em> <span class="diffdel">The calling thread does not own the mutex for any ownership mode.</span> <span class="diffins"><code class="sourceCode cpp">Mutex</code> meets the <em>Cpp17SharedTimedLockable</em> requirements (?.?.?.? [thread.req.lockable.shared.timed]).</span></p>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span> <em>Effects:</em> Calls <code class="sourceCode cpp">m<span class="op">.</span>try_­lock_­shared_­until<span class="op">(</span>abs_­time<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">pm <span class="op">==</span> addressof<span class="op">(</span>m<span class="op">)</span></code> and <code class="sourceCode cpp">owns <span class="op">==</span> res</code> where <code class="sourceCode cpp">res</code> is the value returned by the call to <code class="sourceCode cpp">m<span class="op">.</span>try_­lock_­shared_­until<span class="op">(</span>abs_­time<span class="op">)</span></code>.</p>
</blockquote>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> Rep, <span class="kw">class</span> Period<span class="op">&gt;</span></span>
<span id="cb24-2"><a href="#cb24-2"></a>  shared_lock<span class="op">(</span>mutex_type<span class="op">&amp;</span> m,</span>
<span id="cb24-3"><a href="#cb24-3"></a>              <span class="kw">const</span> chrono<span class="op">::</span>duration<span class="op">&lt;</span>Rep, Period<span class="op">&gt;&amp;</span> rel_time<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">14</a></span> <em>Preconditions:</em> <span class="diffdel">The calling thread does not own the mutex for any ownership mode.</span> <span class="diffins"><code class="sourceCode cpp">Mutex</code> meets the <em>Cpp17SharedTimedLockable</em> requirements (?.?.?.? [thread.req.lockable.shared.timed]).</span></p>
<p><span class="marginalizedparent"><a class="marginalized">15</a></span> <em>Effects:</em> Calls <code class="sourceCode cpp">m<span class="op">.</span>try_­lock_­shared_­for<span class="op">(</span>rel_­time<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">16</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">pm <span class="op">==</span> addressof<span class="op">(</span>m<span class="op">)</span></code> and <code class="sourceCode cpp">owns <span class="op">==</span> res</code> where <code class="sourceCode cpp">res</code> is the value returned by the call to <code class="sourceCode cpp">m<span class="op">.</span>try_­lock_­shared_­for<span class="op">(</span>rel_­time<span class="op">)</span></code>.</p>
</blockquote>
</div>
</blockquote>
<ol start="14" type="1">
<li>Edit <span>32.5.4.4.2 <a href="https://wg21.link/thread.lock.shared.locking">[thread.lock.shared.locking]</a></span> as indicated:</li>
</ol>
<blockquote>
<div>
<div class="sourceCode" id="cb25"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb25-1"><a href="#cb25-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> Clock, <span class="kw">class</span> Duration<span class="op">&gt;</span></span>
<span id="cb25-2"><a href="#cb25-2"></a>  <span class="dt">bool</span> try_lock_until<span class="op">(</span><span class="kw">const</span> chrono<span class="op">::</span>time_point<span class="op">&lt;</span>Clock, Duration<span class="op">&gt;&amp;</span> abs_time<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">9 ¾</a></span> <span class="diffins"><em>Preconditions</em>: <code class="sourceCode cpp">Mutex</code> meets the <em>Cpp17SharedTimedLockable</em> requirements (?.?.?.? [thread.req.lockable.shared.timed]).</span></p>
<p><span class="marginalizedparent"><a class="marginalized">10</a></span> <em>Effects:</em> As if by <code class="sourceCode cpp">pm<span class="op">-&gt;</span>try_­lock_­shared_­until<span class="op">(</span>abs_­time<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">11</a></span> <em>Returns:</em> The value returned by the call to <code class="sourceCode cpp">pm<span class="op">-&gt;</span>try_­lock_­shared_­until<span class="op">(</span>abs_­time<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">12</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">owns <span class="op">==</span> res</code>, where <code class="sourceCode cpp">res</code> is the value returned by the call to <code class="sourceCode cpp">pm<span class="op">-&gt;</span>try_­lock_­shared_­until<span class="op">(</span>abs_­time<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">13</a></span> <em>Throws</em>: Any exception thrown by <code class="sourceCode cpp">pm<span class="op">-&gt;</span>try_­lock_­shared_­until<span class="op">(</span>abs_­time<span class="op">)</span></code>. <code class="sourceCode cpp">system_­error</code> when an exception is required (<span>32.2.2 <a href="https://wg21.link/thread.req.exception">[thread.req.exception]</a></span>).</p>
<p><span class="marginalizedparent"><a class="marginalized">14</a></span> <em>Error conditions:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(14.1)</a></span> <code class="sourceCode cpp">operation_­not_­permitted</code> — if <code class="sourceCode cpp">pm</code> is <code class="sourceCode cpp"><span class="kw">nullptr</span></code>.</li>
<li><span class="marginalizedparent"><a class="marginalized">(14.2)</a></span> <code class="sourceCode cpp">resource_­deadlock_­would_­occur</code> — if on entry <code class="sourceCode cpp">owns</code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</li>
</ul>
</blockquote>
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> Rep, <span class="kw">class</span> Period<span class="op">&gt;</span></span>
<span id="cb26-2"><a href="#cb26-2"></a>  <span class="dt">bool</span> try_lock_for<span class="op">(</span><span class="kw">const</span> chrono<span class="op">::</span>duration<span class="op">&lt;</span>Rep, Period<span class="op">&gt;&amp;</span> rel_time<span class="op">)</span>;</span></code></pre></div>
<blockquote>
<p><span class="marginalizedparent"><a class="marginalized">14 ½</a></span> <span class="diffins"><em>Preconditions</em>: <code class="sourceCode cpp">Mutex</code> meets the <em>Cpp17SharedTimedLockable</em> requirements (?.?.?.? [thread.req.lockable.shared.timed]).</span></p>
<p><span class="marginalizedparent"><a class="marginalized">15</a></span> <em>Effects:</em> As if by <code class="sourceCode cpp">pm<span class="op">-&gt;</span>try_­lock_­shared_­for<span class="op">(</span>rel_­time<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">16</a></span> <em>Returns:</em> The value returned by the call to <code class="sourceCode cpp">pm<span class="op">-&gt;</span>try_­lock_­shared_­for<span class="op">(</span>rel_­time<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">17</a></span> <em>Postconditions:</em> <code class="sourceCode cpp">owns <span class="op">==</span> res</code>, where <code class="sourceCode cpp">res</code> is the value returned by the call to <code class="sourceCode cpp">pm<span class="op">-&gt;</span>try_­lock_­shared_­for<span class="op">(</span>rel_­time<span class="op">)</span></code>.</p>
<p><span class="marginalizedparent"><a class="marginalized">18</a></span> <em>Throws</em>: Any exception thrown by <code class="sourceCode cpp">pm<span class="op">-&gt;</span>try_­lock_­shared_­for<span class="op">(</span>rel_­time<span class="op">)</span></code>. <code class="sourceCode cpp">system_­error</code> when an exception is required (<span>32.2.2 <a href="https://wg21.link/thread.req.exception">[thread.req.exception]</a></span>).</p>
<p><span class="marginalizedparent"><a class="marginalized">19</a></span> <em>Error conditions:</em></p>
<ul>
<li><span class="marginalizedparent"><a class="marginalized">(19.1)</a></span> <code class="sourceCode cpp">operation_­not_­permitted</code> — if <code class="sourceCode cpp">pm</code> is <code class="sourceCode cpp"><span class="kw">nullptr</span></code>.</li>
<li><span class="marginalizedparent"><a class="marginalized">(19.2)</a></span> <code class="sourceCode cpp">resource_­deadlock_­would_­occur</code> — if on entry <code class="sourceCode cpp">owns</code> is <code class="sourceCode cpp"><span class="kw">true</span></code>.</li>
</ul>
</blockquote>
</div>
</blockquote>
</div>
<h1 data-number="5" style="border-bottom:1px solid #cccccc" id="bibliography"><span class="header-section-number">5</span> References<a href="#bibliography" class="self-link"></a></h1>
<div id="refs" class="references hanging-indent" role="doc-bibliography">
<div id="ref-LWG2363">
<p>[LWG2363] Richard Smith. Defect in 30.4.1.4.1 [thread.sharedtimedmutex.class]. <br />
<a href="https://wg21.link/lwg2363">https://wg21.link/lwg2363</a></p>
</div>
<div id="ref-N4861">
<p>[N4861] Richard Smith, Thomas Koeppe, Jens Maurer, Dawn Perchik. 2020. Working Draft, Standard for Programming Language C++. <br />
<a href="https://wg21.link/n4861">https://wg21.link/n4861</a></p>
</div>
</div>
</div>
</div>
</body>
</html>
