Rust-for-Arduboy/docs/doc/src/critical_section/mutex.rs.html

401 lines
No EOL
19 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `/home/zenn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/critical-section-1.1.2/src/mutex.rs`."><title>mutex.rs - source</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/FiraSans-Regular-018c141bf0843ffd.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/FiraSans-Medium-8f9a781e4970d388.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2"><link rel="stylesheet" href="../../static.files/normalize-76eba96aa4d2e634.css"><link rel="stylesheet" href="../../static.files/rustdoc-cb6f1f67f1bcd037.css" id="mainThemeStyle"><meta name="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="critical_section" data-themes="" data-resource-suffix="" data-rustdoc-version="1.73.0-nightly (500647fd8 2023-07-27)" data-channel="nightly" data-search-js="search-6dfdfced5eff6596.js" data-settings-js="settings-de11bff964e9d4e5.js" data-settings-css="settings-8c76f75bfb6bd192.css" data-theme-light-css="light-6d2c9675f3d09c26.css" data-theme-dark-css="dark-45ceb8f2e522f4d1.css" data-theme-ayu-css="ayu-fd19013d6ce078bf.css" ><script src="../../static.files/storage-db41da1a38ea3cb8.js"></script><script defer src="../../static.files/src-script-3280b574d94e47b4.js"></script><script defer src="../../src-files.js"></script><script defer src="../../static.files/main-0795b7d26be81095.js"></script><noscript><link rel="stylesheet" media="(prefers-color-scheme:light)" href="../../static.files/light-6d2c9675f3d09c26.css"><link rel="stylesheet" media="(prefers-color-scheme:dark)" href="../../static.files/dark-45ceb8f2e522f4d1.css"><link rel="stylesheet" href="../../static.files/noscript-cffde32267a19fd6.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-16x16-8b506e7a72182f1c.png"><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-422f7d1d52889060.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-2c020d218678b618.svg"></head><body class="rustdoc src"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"></nav><main><nav class="sub"><a class="sub-logo-container" href="../../critical_section/index.html"><img class="rust-logo" src="../../static.files/rust-logo-151179464ae7ed46.svg" alt="logo"></a><form class="search-form"><span></span><input class="search-input" name="search" aria-label="Run search in the documentation" autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../static.files/wheel-7b819b6101059cd0.svg"></a></div></form></nav><section id="main-content" class="content"><div class="example-wrap"><div data-nosnippet><pre class="src-line-numbers"><a href="#1" id="1">1</a>
<a href="#2" id="2">2</a>
<a href="#3" id="3">3</a>
<a href="#4" id="4">4</a>
<a href="#5" id="5">5</a>
<a href="#6" id="6">6</a>
<a href="#7" id="7">7</a>
<a href="#8" id="8">8</a>
<a href="#9" id="9">9</a>
<a href="#10" id="10">10</a>
<a href="#11" id="11">11</a>
<a href="#12" id="12">12</a>
<a href="#13" id="13">13</a>
<a href="#14" id="14">14</a>
<a href="#15" id="15">15</a>
<a href="#16" id="16">16</a>
<a href="#17" id="17">17</a>
<a href="#18" id="18">18</a>
<a href="#19" id="19">19</a>
<a href="#20" id="20">20</a>
<a href="#21" id="21">21</a>
<a href="#22" id="22">22</a>
<a href="#23" id="23">23</a>
<a href="#24" id="24">24</a>
<a href="#25" id="25">25</a>
<a href="#26" id="26">26</a>
<a href="#27" id="27">27</a>
<a href="#28" id="28">28</a>
<a href="#29" id="29">29</a>
<a href="#30" id="30">30</a>
<a href="#31" id="31">31</a>
<a href="#32" id="32">32</a>
<a href="#33" id="33">33</a>
<a href="#34" id="34">34</a>
<a href="#35" id="35">35</a>
<a href="#36" id="36">36</a>
<a href="#37" id="37">37</a>
<a href="#38" id="38">38</a>
<a href="#39" id="39">39</a>
<a href="#40" id="40">40</a>
<a href="#41" id="41">41</a>
<a href="#42" id="42">42</a>
<a href="#43" id="43">43</a>
<a href="#44" id="44">44</a>
<a href="#45" id="45">45</a>
<a href="#46" id="46">46</a>
<a href="#47" id="47">47</a>
<a href="#48" id="48">48</a>
<a href="#49" id="49">49</a>
<a href="#50" id="50">50</a>
<a href="#51" id="51">51</a>
<a href="#52" id="52">52</a>
<a href="#53" id="53">53</a>
<a href="#54" id="54">54</a>
<a href="#55" id="55">55</a>
<a href="#56" id="56">56</a>
<a href="#57" id="57">57</a>
<a href="#58" id="58">58</a>
<a href="#59" id="59">59</a>
<a href="#60" id="60">60</a>
<a href="#61" id="61">61</a>
<a href="#62" id="62">62</a>
<a href="#63" id="63">63</a>
<a href="#64" id="64">64</a>
<a href="#65" id="65">65</a>
<a href="#66" id="66">66</a>
<a href="#67" id="67">67</a>
<a href="#68" id="68">68</a>
<a href="#69" id="69">69</a>
<a href="#70" id="70">70</a>
<a href="#71" id="71">71</a>
<a href="#72" id="72">72</a>
<a href="#73" id="73">73</a>
<a href="#74" id="74">74</a>
<a href="#75" id="75">75</a>
<a href="#76" id="76">76</a>
<a href="#77" id="77">77</a>
<a href="#78" id="78">78</a>
<a href="#79" id="79">79</a>
<a href="#80" id="80">80</a>
<a href="#81" id="81">81</a>
<a href="#82" id="82">82</a>
<a href="#83" id="83">83</a>
<a href="#84" id="84">84</a>
<a href="#85" id="85">85</a>
<a href="#86" id="86">86</a>
<a href="#87" id="87">87</a>
<a href="#88" id="88">88</a>
<a href="#89" id="89">89</a>
<a href="#90" id="90">90</a>
<a href="#91" id="91">91</a>
<a href="#92" id="92">92</a>
<a href="#93" id="93">93</a>
<a href="#94" id="94">94</a>
<a href="#95" id="95">95</a>
<a href="#96" id="96">96</a>
<a href="#97" id="97">97</a>
<a href="#98" id="98">98</a>
<a href="#99" id="99">99</a>
<a href="#100" id="100">100</a>
<a href="#101" id="101">101</a>
<a href="#102" id="102">102</a>
<a href="#103" id="103">103</a>
<a href="#104" id="104">104</a>
<a href="#105" id="105">105</a>
<a href="#106" id="106">106</a>
<a href="#107" id="107">107</a>
<a href="#108" id="108">108</a>
<a href="#109" id="109">109</a>
<a href="#110" id="110">110</a>
<a href="#111" id="111">111</a>
<a href="#112" id="112">112</a>
<a href="#113" id="113">113</a>
<a href="#114" id="114">114</a>
<a href="#115" id="115">115</a>
<a href="#116" id="116">116</a>
<a href="#117" id="117">117</a>
<a href="#118" id="118">118</a>
<a href="#119" id="119">119</a>
<a href="#120" id="120">120</a>
<a href="#121" id="121">121</a>
<a href="#122" id="122">122</a>
<a href="#123" id="123">123</a>
<a href="#124" id="124">124</a>
<a href="#125" id="125">125</a>
<a href="#126" id="126">126</a>
<a href="#127" id="127">127</a>
<a href="#128" id="128">128</a>
<a href="#129" id="129">129</a>
<a href="#130" id="130">130</a>
<a href="#131" id="131">131</a>
<a href="#132" id="132">132</a>
<a href="#133" id="133">133</a>
<a href="#134" id="134">134</a>
<a href="#135" id="135">135</a>
<a href="#136" id="136">136</a>
<a href="#137" id="137">137</a>
<a href="#138" id="138">138</a>
<a href="#139" id="139">139</a>
<a href="#140" id="140">140</a>
<a href="#141" id="141">141</a>
<a href="#142" id="142">142</a>
<a href="#143" id="143">143</a>
<a href="#144" id="144">144</a>
<a href="#145" id="145">145</a>
<a href="#146" id="146">146</a>
<a href="#147" id="147">147</a>
<a href="#148" id="148">148</a>
<a href="#149" id="149">149</a>
<a href="#150" id="150">150</a>
<a href="#151" id="151">151</a>
<a href="#152" id="152">152</a>
<a href="#153" id="153">153</a>
<a href="#154" id="154">154</a>
<a href="#155" id="155">155</a>
<a href="#156" id="156">156</a>
<a href="#157" id="157">157</a>
<a href="#158" id="158">158</a>
<a href="#159" id="159">159</a>
<a href="#160" id="160">160</a>
<a href="#161" id="161">161</a>
<a href="#162" id="162">162</a>
<a href="#163" id="163">163</a>
<a href="#164" id="164">164</a>
<a href="#165" id="165">165</a>
<a href="#166" id="166">166</a>
<a href="#167" id="167">167</a>
<a href="#168" id="168">168</a>
<a href="#169" id="169">169</a>
<a href="#170" id="170">170</a>
<a href="#171" id="171">171</a>
<a href="#172" id="172">172</a>
<a href="#173" id="173">173</a>
<a href="#174" id="174">174</a>
<a href="#175" id="175">175</a>
<a href="#176" id="176">176</a>
<a href="#177" id="177">177</a>
<a href="#178" id="178">178</a>
<a href="#179" id="179">179</a>
<a href="#180" id="180">180</a>
<a href="#181" id="181">181</a>
<a href="#182" id="182">182</a>
<a href="#183" id="183">183</a>
<a href="#184" id="184">184</a>
<a href="#185" id="185">185</a>
<a href="#186" id="186">186</a>
<a href="#187" id="187">187</a>
<a href="#188" id="188">188</a>
<a href="#189" id="189">189</a>
<a href="#190" id="190">190</a>
<a href="#191" id="191">191</a>
<a href="#192" id="192">192</a>
<a href="#193" id="193">193</a>
<a href="#194" id="194">194</a>
<a href="#195" id="195">195</a>
<a href="#196" id="196">196</a>
<a href="#197" id="197">197</a>
<a href="#198" id="198">198</a>
<a href="#199" id="199">199</a>
<a href="#200" id="200">200</a>
</pre></div><pre class="rust"><code><span class="kw">use </span><span class="kw">super</span>::CriticalSection;
<span class="kw">use </span>core::cell::{Ref, RefCell, RefMut, UnsafeCell};
<span class="doccomment">/// A mutex based on critical sections.
///
/// # Example
///
/// ```no_run
/// # use critical_section::Mutex;
/// # use std::cell::Cell;
///
/// static FOO: Mutex&lt;Cell&lt;i32&gt;&gt; = Mutex::new(Cell::new(42));
///
/// fn main() {
/// critical_section::with(|cs| {
/// FOO.borrow(cs).set(43);
/// });
/// }
///
/// fn interrupt_handler() {
/// let _x = critical_section::with(|cs| FOO.borrow(cs).get());
/// }
/// ```
///
///
/// # Design
///
/// [`std::sync::Mutex`] has two purposes. It converts types that are [`Send`]
/// but not [`Sync`] into types that are both; and it provides
/// [interior mutability]. `critical_section::Mutex`, on the other hand, only adds
/// `Sync`. It does *not* provide interior mutability.
///
/// This was a conscious design choice. It is possible to create multiple
/// [`CriticalSection`] tokens, either by nesting critical sections or `Copy`ing
/// an existing token. As a result, it would not be sound for [`Mutex::borrow`]
/// to return `&amp;mut T`, because there would be nothing to prevent calling
/// `borrow` multiple times to create aliased `&amp;mut T` references.
///
/// The solution is to include a runtime check to ensure that each resource is
/// borrowed only once. This is what `std::sync::Mutex` does. However, this is
/// a runtime cost that may not be required in all circumstances. For instance,
/// `Mutex&lt;Cell&lt;T&gt;&gt;` never needs to create `&amp;mut T` or equivalent.
///
/// If `&amp;mut T` is needed, the simplest solution is to use `Mutex&lt;RefCell&lt;T&gt;&gt;`,
/// which is the closest analogy to `std::sync::Mutex`. [`RefCell`] inserts the
/// exact runtime check necessary to guarantee that the `&amp;mut T` reference is
/// unique.
///
/// To reduce verbosity when using `Mutex&lt;RefCell&lt;T&gt;&gt;`, we reimplement some of
/// `RefCell`&#39;s methods on it directly.
///
/// ```no_run
/// # use critical_section::Mutex;
/// # use std::cell::RefCell;
///
/// static FOO: Mutex&lt;RefCell&lt;i32&gt;&gt; = Mutex::new(RefCell::new(42));
///
/// fn main() {
/// critical_section::with(|cs| {
/// // Instead of calling this
/// let _ = FOO.borrow(cs).take();
/// // Call this
/// let _ = FOO.take(cs);
/// // `RefCell::borrow` and `RefCell::borrow_mut` are renamed to
/// // `borrow_ref` and `borrow_ref_mut` to avoid name collisions
/// let _: &amp;mut i32 = &amp;mut *FOO.borrow_ref_mut(cs);
/// })
/// }
/// ```
///
/// [`std::sync::Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
/// [interior mutability]: https://doc.rust-lang.org/reference/interior-mutability.html
</span><span class="attr">#[derive(Debug)]
</span><span class="kw">pub struct </span>Mutex&lt;T&gt; {
inner: UnsafeCell&lt;T&gt;,
}
<span class="kw">impl</span>&lt;T&gt; Mutex&lt;T&gt; {
<span class="doccomment">/// Creates a new mutex.
</span><span class="attr">#[inline]
</span><span class="kw">pub const fn </span>new(value: T) -&gt; <span class="self">Self </span>{
Mutex {
inner: UnsafeCell::new(value),
}
}
<span class="doccomment">/// Gets a mutable reference to the contained value when the mutex is already uniquely borrowed.
///
/// This does not require locking or a critical section since it takes `&amp;mut self`, which
/// guarantees unique ownership already. Care must be taken when using this method to
/// **unsafely** access `static mut` variables, appropriate fences must be used to prevent
/// unwanted optimizations.
</span><span class="attr">#[inline]
</span><span class="kw">pub fn </span>get_mut(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;mut </span>T {
<span class="kw">unsafe </span>{ <span class="kw-2">&amp;mut *</span><span class="self">self</span>.inner.get() }
}
<span class="doccomment">/// Unwraps the contained value, consuming the mutex.
</span><span class="attr">#[inline]
</span><span class="kw">pub fn </span>into_inner(<span class="self">self</span>) -&gt; T {
<span class="self">self</span>.inner.into_inner()
}
<span class="doccomment">/// Borrows the data for the duration of the critical section.
</span><span class="attr">#[inline]
</span><span class="kw">pub fn </span>borrow&lt;<span class="lifetime">&#39;cs</span>&gt;(<span class="kw-2">&amp;</span><span class="lifetime">&#39;cs </span><span class="self">self</span>, _cs: CriticalSection&lt;<span class="lifetime">&#39;cs</span>&gt;) -&gt; <span class="kw-2">&amp;</span><span class="lifetime">&#39;cs </span>T {
<span class="kw">unsafe </span>{ <span class="kw-2">&amp;*</span><span class="self">self</span>.inner.get() }
}
}
<span class="kw">impl</span>&lt;T&gt; Mutex&lt;RefCell&lt;T&gt;&gt; {
<span class="doccomment">/// Borrow the data and call [`RefCell::replace`]
///
/// This is equivalent to `self.borrow(cs).replace(t)`
///
/// # Panics
///
/// This call could panic. See the documentation for [`RefCell::replace`]
/// for more details.
</span><span class="attr">#[inline]
#[track_caller]
</span><span class="kw">pub fn </span>replace&lt;<span class="lifetime">&#39;cs</span>&gt;(<span class="kw-2">&amp;</span><span class="lifetime">&#39;cs </span><span class="self">self</span>, cs: CriticalSection&lt;<span class="lifetime">&#39;cs</span>&gt;, t: T) -&gt; T {
<span class="self">self</span>.borrow(cs).replace(t)
}
<span class="doccomment">/// Borrow the data and call [`RefCell::replace_with`]
///
/// This is equivalent to `self.borrow(cs).replace_with(f)`
///
/// # Panics
///
/// This call could panic. See the documentation for
/// [`RefCell::replace_with`] for more details.
</span><span class="attr">#[inline]
#[track_caller]
</span><span class="kw">pub fn </span>replace_with&lt;<span class="lifetime">&#39;cs</span>, F&gt;(<span class="kw-2">&amp;</span><span class="lifetime">&#39;cs </span><span class="self">self</span>, cs: CriticalSection&lt;<span class="lifetime">&#39;cs</span>&gt;, f: F) -&gt; T
<span class="kw">where
</span>F: FnOnce(<span class="kw-2">&amp;mut </span>T) -&gt; T,
{
<span class="self">self</span>.borrow(cs).replace_with(f)
}
<span class="doccomment">/// Borrow the data and call [`RefCell::borrow`]
///
/// This is equivalent to `self.borrow(cs).borrow()`
///
/// # Panics
///
/// This call could panic. See the documentation for [`RefCell::borrow`]
/// for more details.
</span><span class="attr">#[inline]
#[track_caller]
</span><span class="kw">pub fn </span>borrow_ref&lt;<span class="lifetime">&#39;cs</span>&gt;(<span class="kw-2">&amp;</span><span class="lifetime">&#39;cs </span><span class="self">self</span>, cs: CriticalSection&lt;<span class="lifetime">&#39;cs</span>&gt;) -&gt; Ref&lt;<span class="lifetime">&#39;cs</span>, T&gt; {
<span class="self">self</span>.borrow(cs).borrow()
}
<span class="doccomment">/// Borrow the data and call [`RefCell::borrow_mut`]
///
/// This is equivalent to `self.borrow(cs).borrow_mut()`
///
/// # Panics
///
/// This call could panic. See the documentation for [`RefCell::borrow_mut`]
/// for more details.
</span><span class="attr">#[inline]
#[track_caller]
</span><span class="kw">pub fn </span>borrow_ref_mut&lt;<span class="lifetime">&#39;cs</span>&gt;(<span class="kw-2">&amp;</span><span class="lifetime">&#39;cs </span><span class="self">self</span>, cs: CriticalSection&lt;<span class="lifetime">&#39;cs</span>&gt;) -&gt; RefMut&lt;<span class="lifetime">&#39;cs</span>, T&gt; {
<span class="self">self</span>.borrow(cs).borrow_mut()
}
}
<span class="kw">impl</span>&lt;T: Default&gt; Mutex&lt;RefCell&lt;T&gt;&gt; {
<span class="doccomment">/// Borrow the data and call [`RefCell::take`]
///
/// This is equivalent to `self.borrow(cs).take()`
///
/// # Panics
///
/// This call could panic. See the documentation for [`RefCell::take`]
/// for more details.
</span><span class="attr">#[inline]
#[track_caller]
</span><span class="kw">pub fn </span>take&lt;<span class="lifetime">&#39;cs</span>&gt;(<span class="kw-2">&amp;</span><span class="lifetime">&#39;cs </span><span class="self">self</span>, cs: CriticalSection&lt;<span class="lifetime">&#39;cs</span>&gt;) -&gt; T {
<span class="self">self</span>.borrow(cs).take()
}
}
<span class="comment">// NOTE A `Mutex` can be used as a channel so the protected data must be `Send`
// to prevent sending non-Sendable stuff (e.g. access tokens) across different
// threads.
</span><span class="kw">unsafe impl</span>&lt;T&gt; Sync <span class="kw">for </span>Mutex&lt;T&gt; <span class="kw">where </span>T: Send {}
<span class="doccomment">/// ``` compile_fail
/// fn bad(cs: critical_section::CriticalSection) -&gt; &amp;u32 {
/// let x = critical_section::Mutex::new(42u32);
/// x.borrow(cs)
/// }
/// ```
</span><span class="attr">#[cfg(doctest)]
</span><span class="kw">const </span>BorrowMustNotOutliveMutexTest: () = ();
</code></pre></div></section></main></body></html>