Files
rapr-rs/docs/src/futures_channel/mpsc/mod.rs.html
T
Uttarayan Mondal d5ecda4c73 Initial docs commit
2021-03-15 01:27:34 +05:30

2719 lines
174 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/fs0c131y/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/futures-channel-0.3.13/src/mpsc/mod.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>mod.rs - source</title><link rel="stylesheet" type="text/css" href="../../../normalize.css"><link rel="stylesheet" type="text/css" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../../../light.css" id="themeStyle"><link rel="stylesheet" type="text/css" href="../../../dark.css" disabled ><link rel="stylesheet" type="text/css" href="../../../ayu.css" disabled ><script id="default-settings"></script><script src="../../../storage.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="icon" type="image/svg+xml" href="../../../favicon.svg">
<link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png">
<link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><style type="text/css">#crate-search{background-image:url("../../../down-arrow.svg");}</style></head><body class="rustdoc source"><!--[if lte IE 8]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="sidebar-menu">&#9776;</div><a href='../../../futures_channel/index.html'><div class='logo-container rust-logo'><img src='../../../rust-logo.png' alt='logo'></div></a></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!" aria-haspopup="menu"><img src="../../../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices" role="menu"></div></div><script src="../../../theme.js"></script><nav class="sub"><form class="search-form"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" disabled autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><button type="button" class="help-button">?</button>
<a id="settings-menu" href="../../../settings.html"><img src="../../../wheel.svg" width="18" alt="Change settings"></a></div></form></nav><section id="main" class="content"><pre class="line-numbers"><span id="1"> 1</span>
<span id="2"> 2</span>
<span id="3"> 3</span>
<span id="4"> 4</span>
<span id="5"> 5</span>
<span id="6"> 6</span>
<span id="7"> 7</span>
<span id="8"> 8</span>
<span id="9"> 9</span>
<span id="10"> 10</span>
<span id="11"> 11</span>
<span id="12"> 12</span>
<span id="13"> 13</span>
<span id="14"> 14</span>
<span id="15"> 15</span>
<span id="16"> 16</span>
<span id="17"> 17</span>
<span id="18"> 18</span>
<span id="19"> 19</span>
<span id="20"> 20</span>
<span id="21"> 21</span>
<span id="22"> 22</span>
<span id="23"> 23</span>
<span id="24"> 24</span>
<span id="25"> 25</span>
<span id="26"> 26</span>
<span id="27"> 27</span>
<span id="28"> 28</span>
<span id="29"> 29</span>
<span id="30"> 30</span>
<span id="31"> 31</span>
<span id="32"> 32</span>
<span id="33"> 33</span>
<span id="34"> 34</span>
<span id="35"> 35</span>
<span id="36"> 36</span>
<span id="37"> 37</span>
<span id="38"> 38</span>
<span id="39"> 39</span>
<span id="40"> 40</span>
<span id="41"> 41</span>
<span id="42"> 42</span>
<span id="43"> 43</span>
<span id="44"> 44</span>
<span id="45"> 45</span>
<span id="46"> 46</span>
<span id="47"> 47</span>
<span id="48"> 48</span>
<span id="49"> 49</span>
<span id="50"> 50</span>
<span id="51"> 51</span>
<span id="52"> 52</span>
<span id="53"> 53</span>
<span id="54"> 54</span>
<span id="55"> 55</span>
<span id="56"> 56</span>
<span id="57"> 57</span>
<span id="58"> 58</span>
<span id="59"> 59</span>
<span id="60"> 60</span>
<span id="61"> 61</span>
<span id="62"> 62</span>
<span id="63"> 63</span>
<span id="64"> 64</span>
<span id="65"> 65</span>
<span id="66"> 66</span>
<span id="67"> 67</span>
<span id="68"> 68</span>
<span id="69"> 69</span>
<span id="70"> 70</span>
<span id="71"> 71</span>
<span id="72"> 72</span>
<span id="73"> 73</span>
<span id="74"> 74</span>
<span id="75"> 75</span>
<span id="76"> 76</span>
<span id="77"> 77</span>
<span id="78"> 78</span>
<span id="79"> 79</span>
<span id="80"> 80</span>
<span id="81"> 81</span>
<span id="82"> 82</span>
<span id="83"> 83</span>
<span id="84"> 84</span>
<span id="85"> 85</span>
<span id="86"> 86</span>
<span id="87"> 87</span>
<span id="88"> 88</span>
<span id="89"> 89</span>
<span id="90"> 90</span>
<span id="91"> 91</span>
<span id="92"> 92</span>
<span id="93"> 93</span>
<span id="94"> 94</span>
<span id="95"> 95</span>
<span id="96"> 96</span>
<span id="97"> 97</span>
<span id="98"> 98</span>
<span id="99"> 99</span>
<span id="100"> 100</span>
<span id="101"> 101</span>
<span id="102"> 102</span>
<span id="103"> 103</span>
<span id="104"> 104</span>
<span id="105"> 105</span>
<span id="106"> 106</span>
<span id="107"> 107</span>
<span id="108"> 108</span>
<span id="109"> 109</span>
<span id="110"> 110</span>
<span id="111"> 111</span>
<span id="112"> 112</span>
<span id="113"> 113</span>
<span id="114"> 114</span>
<span id="115"> 115</span>
<span id="116"> 116</span>
<span id="117"> 117</span>
<span id="118"> 118</span>
<span id="119"> 119</span>
<span id="120"> 120</span>
<span id="121"> 121</span>
<span id="122"> 122</span>
<span id="123"> 123</span>
<span id="124"> 124</span>
<span id="125"> 125</span>
<span id="126"> 126</span>
<span id="127"> 127</span>
<span id="128"> 128</span>
<span id="129"> 129</span>
<span id="130"> 130</span>
<span id="131"> 131</span>
<span id="132"> 132</span>
<span id="133"> 133</span>
<span id="134"> 134</span>
<span id="135"> 135</span>
<span id="136"> 136</span>
<span id="137"> 137</span>
<span id="138"> 138</span>
<span id="139"> 139</span>
<span id="140"> 140</span>
<span id="141"> 141</span>
<span id="142"> 142</span>
<span id="143"> 143</span>
<span id="144"> 144</span>
<span id="145"> 145</span>
<span id="146"> 146</span>
<span id="147"> 147</span>
<span id="148"> 148</span>
<span id="149"> 149</span>
<span id="150"> 150</span>
<span id="151"> 151</span>
<span id="152"> 152</span>
<span id="153"> 153</span>
<span id="154"> 154</span>
<span id="155"> 155</span>
<span id="156"> 156</span>
<span id="157"> 157</span>
<span id="158"> 158</span>
<span id="159"> 159</span>
<span id="160"> 160</span>
<span id="161"> 161</span>
<span id="162"> 162</span>
<span id="163"> 163</span>
<span id="164"> 164</span>
<span id="165"> 165</span>
<span id="166"> 166</span>
<span id="167"> 167</span>
<span id="168"> 168</span>
<span id="169"> 169</span>
<span id="170"> 170</span>
<span id="171"> 171</span>
<span id="172"> 172</span>
<span id="173"> 173</span>
<span id="174"> 174</span>
<span id="175"> 175</span>
<span id="176"> 176</span>
<span id="177"> 177</span>
<span id="178"> 178</span>
<span id="179"> 179</span>
<span id="180"> 180</span>
<span id="181"> 181</span>
<span id="182"> 182</span>
<span id="183"> 183</span>
<span id="184"> 184</span>
<span id="185"> 185</span>
<span id="186"> 186</span>
<span id="187"> 187</span>
<span id="188"> 188</span>
<span id="189"> 189</span>
<span id="190"> 190</span>
<span id="191"> 191</span>
<span id="192"> 192</span>
<span id="193"> 193</span>
<span id="194"> 194</span>
<span id="195"> 195</span>
<span id="196"> 196</span>
<span id="197"> 197</span>
<span id="198"> 198</span>
<span id="199"> 199</span>
<span id="200"> 200</span>
<span id="201"> 201</span>
<span id="202"> 202</span>
<span id="203"> 203</span>
<span id="204"> 204</span>
<span id="205"> 205</span>
<span id="206"> 206</span>
<span id="207"> 207</span>
<span id="208"> 208</span>
<span id="209"> 209</span>
<span id="210"> 210</span>
<span id="211"> 211</span>
<span id="212"> 212</span>
<span id="213"> 213</span>
<span id="214"> 214</span>
<span id="215"> 215</span>
<span id="216"> 216</span>
<span id="217"> 217</span>
<span id="218"> 218</span>
<span id="219"> 219</span>
<span id="220"> 220</span>
<span id="221"> 221</span>
<span id="222"> 222</span>
<span id="223"> 223</span>
<span id="224"> 224</span>
<span id="225"> 225</span>
<span id="226"> 226</span>
<span id="227"> 227</span>
<span id="228"> 228</span>
<span id="229"> 229</span>
<span id="230"> 230</span>
<span id="231"> 231</span>
<span id="232"> 232</span>
<span id="233"> 233</span>
<span id="234"> 234</span>
<span id="235"> 235</span>
<span id="236"> 236</span>
<span id="237"> 237</span>
<span id="238"> 238</span>
<span id="239"> 239</span>
<span id="240"> 240</span>
<span id="241"> 241</span>
<span id="242"> 242</span>
<span id="243"> 243</span>
<span id="244"> 244</span>
<span id="245"> 245</span>
<span id="246"> 246</span>
<span id="247"> 247</span>
<span id="248"> 248</span>
<span id="249"> 249</span>
<span id="250"> 250</span>
<span id="251"> 251</span>
<span id="252"> 252</span>
<span id="253"> 253</span>
<span id="254"> 254</span>
<span id="255"> 255</span>
<span id="256"> 256</span>
<span id="257"> 257</span>
<span id="258"> 258</span>
<span id="259"> 259</span>
<span id="260"> 260</span>
<span id="261"> 261</span>
<span id="262"> 262</span>
<span id="263"> 263</span>
<span id="264"> 264</span>
<span id="265"> 265</span>
<span id="266"> 266</span>
<span id="267"> 267</span>
<span id="268"> 268</span>
<span id="269"> 269</span>
<span id="270"> 270</span>
<span id="271"> 271</span>
<span id="272"> 272</span>
<span id="273"> 273</span>
<span id="274"> 274</span>
<span id="275"> 275</span>
<span id="276"> 276</span>
<span id="277"> 277</span>
<span id="278"> 278</span>
<span id="279"> 279</span>
<span id="280"> 280</span>
<span id="281"> 281</span>
<span id="282"> 282</span>
<span id="283"> 283</span>
<span id="284"> 284</span>
<span id="285"> 285</span>
<span id="286"> 286</span>
<span id="287"> 287</span>
<span id="288"> 288</span>
<span id="289"> 289</span>
<span id="290"> 290</span>
<span id="291"> 291</span>
<span id="292"> 292</span>
<span id="293"> 293</span>
<span id="294"> 294</span>
<span id="295"> 295</span>
<span id="296"> 296</span>
<span id="297"> 297</span>
<span id="298"> 298</span>
<span id="299"> 299</span>
<span id="300"> 300</span>
<span id="301"> 301</span>
<span id="302"> 302</span>
<span id="303"> 303</span>
<span id="304"> 304</span>
<span id="305"> 305</span>
<span id="306"> 306</span>
<span id="307"> 307</span>
<span id="308"> 308</span>
<span id="309"> 309</span>
<span id="310"> 310</span>
<span id="311"> 311</span>
<span id="312"> 312</span>
<span id="313"> 313</span>
<span id="314"> 314</span>
<span id="315"> 315</span>
<span id="316"> 316</span>
<span id="317"> 317</span>
<span id="318"> 318</span>
<span id="319"> 319</span>
<span id="320"> 320</span>
<span id="321"> 321</span>
<span id="322"> 322</span>
<span id="323"> 323</span>
<span id="324"> 324</span>
<span id="325"> 325</span>
<span id="326"> 326</span>
<span id="327"> 327</span>
<span id="328"> 328</span>
<span id="329"> 329</span>
<span id="330"> 330</span>
<span id="331"> 331</span>
<span id="332"> 332</span>
<span id="333"> 333</span>
<span id="334"> 334</span>
<span id="335"> 335</span>
<span id="336"> 336</span>
<span id="337"> 337</span>
<span id="338"> 338</span>
<span id="339"> 339</span>
<span id="340"> 340</span>
<span id="341"> 341</span>
<span id="342"> 342</span>
<span id="343"> 343</span>
<span id="344"> 344</span>
<span id="345"> 345</span>
<span id="346"> 346</span>
<span id="347"> 347</span>
<span id="348"> 348</span>
<span id="349"> 349</span>
<span id="350"> 350</span>
<span id="351"> 351</span>
<span id="352"> 352</span>
<span id="353"> 353</span>
<span id="354"> 354</span>
<span id="355"> 355</span>
<span id="356"> 356</span>
<span id="357"> 357</span>
<span id="358"> 358</span>
<span id="359"> 359</span>
<span id="360"> 360</span>
<span id="361"> 361</span>
<span id="362"> 362</span>
<span id="363"> 363</span>
<span id="364"> 364</span>
<span id="365"> 365</span>
<span id="366"> 366</span>
<span id="367"> 367</span>
<span id="368"> 368</span>
<span id="369"> 369</span>
<span id="370"> 370</span>
<span id="371"> 371</span>
<span id="372"> 372</span>
<span id="373"> 373</span>
<span id="374"> 374</span>
<span id="375"> 375</span>
<span id="376"> 376</span>
<span id="377"> 377</span>
<span id="378"> 378</span>
<span id="379"> 379</span>
<span id="380"> 380</span>
<span id="381"> 381</span>
<span id="382"> 382</span>
<span id="383"> 383</span>
<span id="384"> 384</span>
<span id="385"> 385</span>
<span id="386"> 386</span>
<span id="387"> 387</span>
<span id="388"> 388</span>
<span id="389"> 389</span>
<span id="390"> 390</span>
<span id="391"> 391</span>
<span id="392"> 392</span>
<span id="393"> 393</span>
<span id="394"> 394</span>
<span id="395"> 395</span>
<span id="396"> 396</span>
<span id="397"> 397</span>
<span id="398"> 398</span>
<span id="399"> 399</span>
<span id="400"> 400</span>
<span id="401"> 401</span>
<span id="402"> 402</span>
<span id="403"> 403</span>
<span id="404"> 404</span>
<span id="405"> 405</span>
<span id="406"> 406</span>
<span id="407"> 407</span>
<span id="408"> 408</span>
<span id="409"> 409</span>
<span id="410"> 410</span>
<span id="411"> 411</span>
<span id="412"> 412</span>
<span id="413"> 413</span>
<span id="414"> 414</span>
<span id="415"> 415</span>
<span id="416"> 416</span>
<span id="417"> 417</span>
<span id="418"> 418</span>
<span id="419"> 419</span>
<span id="420"> 420</span>
<span id="421"> 421</span>
<span id="422"> 422</span>
<span id="423"> 423</span>
<span id="424"> 424</span>
<span id="425"> 425</span>
<span id="426"> 426</span>
<span id="427"> 427</span>
<span id="428"> 428</span>
<span id="429"> 429</span>
<span id="430"> 430</span>
<span id="431"> 431</span>
<span id="432"> 432</span>
<span id="433"> 433</span>
<span id="434"> 434</span>
<span id="435"> 435</span>
<span id="436"> 436</span>
<span id="437"> 437</span>
<span id="438"> 438</span>
<span id="439"> 439</span>
<span id="440"> 440</span>
<span id="441"> 441</span>
<span id="442"> 442</span>
<span id="443"> 443</span>
<span id="444"> 444</span>
<span id="445"> 445</span>
<span id="446"> 446</span>
<span id="447"> 447</span>
<span id="448"> 448</span>
<span id="449"> 449</span>
<span id="450"> 450</span>
<span id="451"> 451</span>
<span id="452"> 452</span>
<span id="453"> 453</span>
<span id="454"> 454</span>
<span id="455"> 455</span>
<span id="456"> 456</span>
<span id="457"> 457</span>
<span id="458"> 458</span>
<span id="459"> 459</span>
<span id="460"> 460</span>
<span id="461"> 461</span>
<span id="462"> 462</span>
<span id="463"> 463</span>
<span id="464"> 464</span>
<span id="465"> 465</span>
<span id="466"> 466</span>
<span id="467"> 467</span>
<span id="468"> 468</span>
<span id="469"> 469</span>
<span id="470"> 470</span>
<span id="471"> 471</span>
<span id="472"> 472</span>
<span id="473"> 473</span>
<span id="474"> 474</span>
<span id="475"> 475</span>
<span id="476"> 476</span>
<span id="477"> 477</span>
<span id="478"> 478</span>
<span id="479"> 479</span>
<span id="480"> 480</span>
<span id="481"> 481</span>
<span id="482"> 482</span>
<span id="483"> 483</span>
<span id="484"> 484</span>
<span id="485"> 485</span>
<span id="486"> 486</span>
<span id="487"> 487</span>
<span id="488"> 488</span>
<span id="489"> 489</span>
<span id="490"> 490</span>
<span id="491"> 491</span>
<span id="492"> 492</span>
<span id="493"> 493</span>
<span id="494"> 494</span>
<span id="495"> 495</span>
<span id="496"> 496</span>
<span id="497"> 497</span>
<span id="498"> 498</span>
<span id="499"> 499</span>
<span id="500"> 500</span>
<span id="501"> 501</span>
<span id="502"> 502</span>
<span id="503"> 503</span>
<span id="504"> 504</span>
<span id="505"> 505</span>
<span id="506"> 506</span>
<span id="507"> 507</span>
<span id="508"> 508</span>
<span id="509"> 509</span>
<span id="510"> 510</span>
<span id="511"> 511</span>
<span id="512"> 512</span>
<span id="513"> 513</span>
<span id="514"> 514</span>
<span id="515"> 515</span>
<span id="516"> 516</span>
<span id="517"> 517</span>
<span id="518"> 518</span>
<span id="519"> 519</span>
<span id="520"> 520</span>
<span id="521"> 521</span>
<span id="522"> 522</span>
<span id="523"> 523</span>
<span id="524"> 524</span>
<span id="525"> 525</span>
<span id="526"> 526</span>
<span id="527"> 527</span>
<span id="528"> 528</span>
<span id="529"> 529</span>
<span id="530"> 530</span>
<span id="531"> 531</span>
<span id="532"> 532</span>
<span id="533"> 533</span>
<span id="534"> 534</span>
<span id="535"> 535</span>
<span id="536"> 536</span>
<span id="537"> 537</span>
<span id="538"> 538</span>
<span id="539"> 539</span>
<span id="540"> 540</span>
<span id="541"> 541</span>
<span id="542"> 542</span>
<span id="543"> 543</span>
<span id="544"> 544</span>
<span id="545"> 545</span>
<span id="546"> 546</span>
<span id="547"> 547</span>
<span id="548"> 548</span>
<span id="549"> 549</span>
<span id="550"> 550</span>
<span id="551"> 551</span>
<span id="552"> 552</span>
<span id="553"> 553</span>
<span id="554"> 554</span>
<span id="555"> 555</span>
<span id="556"> 556</span>
<span id="557"> 557</span>
<span id="558"> 558</span>
<span id="559"> 559</span>
<span id="560"> 560</span>
<span id="561"> 561</span>
<span id="562"> 562</span>
<span id="563"> 563</span>
<span id="564"> 564</span>
<span id="565"> 565</span>
<span id="566"> 566</span>
<span id="567"> 567</span>
<span id="568"> 568</span>
<span id="569"> 569</span>
<span id="570"> 570</span>
<span id="571"> 571</span>
<span id="572"> 572</span>
<span id="573"> 573</span>
<span id="574"> 574</span>
<span id="575"> 575</span>
<span id="576"> 576</span>
<span id="577"> 577</span>
<span id="578"> 578</span>
<span id="579"> 579</span>
<span id="580"> 580</span>
<span id="581"> 581</span>
<span id="582"> 582</span>
<span id="583"> 583</span>
<span id="584"> 584</span>
<span id="585"> 585</span>
<span id="586"> 586</span>
<span id="587"> 587</span>
<span id="588"> 588</span>
<span id="589"> 589</span>
<span id="590"> 590</span>
<span id="591"> 591</span>
<span id="592"> 592</span>
<span id="593"> 593</span>
<span id="594"> 594</span>
<span id="595"> 595</span>
<span id="596"> 596</span>
<span id="597"> 597</span>
<span id="598"> 598</span>
<span id="599"> 599</span>
<span id="600"> 600</span>
<span id="601"> 601</span>
<span id="602"> 602</span>
<span id="603"> 603</span>
<span id="604"> 604</span>
<span id="605"> 605</span>
<span id="606"> 606</span>
<span id="607"> 607</span>
<span id="608"> 608</span>
<span id="609"> 609</span>
<span id="610"> 610</span>
<span id="611"> 611</span>
<span id="612"> 612</span>
<span id="613"> 613</span>
<span id="614"> 614</span>
<span id="615"> 615</span>
<span id="616"> 616</span>
<span id="617"> 617</span>
<span id="618"> 618</span>
<span id="619"> 619</span>
<span id="620"> 620</span>
<span id="621"> 621</span>
<span id="622"> 622</span>
<span id="623"> 623</span>
<span id="624"> 624</span>
<span id="625"> 625</span>
<span id="626"> 626</span>
<span id="627"> 627</span>
<span id="628"> 628</span>
<span id="629"> 629</span>
<span id="630"> 630</span>
<span id="631"> 631</span>
<span id="632"> 632</span>
<span id="633"> 633</span>
<span id="634"> 634</span>
<span id="635"> 635</span>
<span id="636"> 636</span>
<span id="637"> 637</span>
<span id="638"> 638</span>
<span id="639"> 639</span>
<span id="640"> 640</span>
<span id="641"> 641</span>
<span id="642"> 642</span>
<span id="643"> 643</span>
<span id="644"> 644</span>
<span id="645"> 645</span>
<span id="646"> 646</span>
<span id="647"> 647</span>
<span id="648"> 648</span>
<span id="649"> 649</span>
<span id="650"> 650</span>
<span id="651"> 651</span>
<span id="652"> 652</span>
<span id="653"> 653</span>
<span id="654"> 654</span>
<span id="655"> 655</span>
<span id="656"> 656</span>
<span id="657"> 657</span>
<span id="658"> 658</span>
<span id="659"> 659</span>
<span id="660"> 660</span>
<span id="661"> 661</span>
<span id="662"> 662</span>
<span id="663"> 663</span>
<span id="664"> 664</span>
<span id="665"> 665</span>
<span id="666"> 666</span>
<span id="667"> 667</span>
<span id="668"> 668</span>
<span id="669"> 669</span>
<span id="670"> 670</span>
<span id="671"> 671</span>
<span id="672"> 672</span>
<span id="673"> 673</span>
<span id="674"> 674</span>
<span id="675"> 675</span>
<span id="676"> 676</span>
<span id="677"> 677</span>
<span id="678"> 678</span>
<span id="679"> 679</span>
<span id="680"> 680</span>
<span id="681"> 681</span>
<span id="682"> 682</span>
<span id="683"> 683</span>
<span id="684"> 684</span>
<span id="685"> 685</span>
<span id="686"> 686</span>
<span id="687"> 687</span>
<span id="688"> 688</span>
<span id="689"> 689</span>
<span id="690"> 690</span>
<span id="691"> 691</span>
<span id="692"> 692</span>
<span id="693"> 693</span>
<span id="694"> 694</span>
<span id="695"> 695</span>
<span id="696"> 696</span>
<span id="697"> 697</span>
<span id="698"> 698</span>
<span id="699"> 699</span>
<span id="700"> 700</span>
<span id="701"> 701</span>
<span id="702"> 702</span>
<span id="703"> 703</span>
<span id="704"> 704</span>
<span id="705"> 705</span>
<span id="706"> 706</span>
<span id="707"> 707</span>
<span id="708"> 708</span>
<span id="709"> 709</span>
<span id="710"> 710</span>
<span id="711"> 711</span>
<span id="712"> 712</span>
<span id="713"> 713</span>
<span id="714"> 714</span>
<span id="715"> 715</span>
<span id="716"> 716</span>
<span id="717"> 717</span>
<span id="718"> 718</span>
<span id="719"> 719</span>
<span id="720"> 720</span>
<span id="721"> 721</span>
<span id="722"> 722</span>
<span id="723"> 723</span>
<span id="724"> 724</span>
<span id="725"> 725</span>
<span id="726"> 726</span>
<span id="727"> 727</span>
<span id="728"> 728</span>
<span id="729"> 729</span>
<span id="730"> 730</span>
<span id="731"> 731</span>
<span id="732"> 732</span>
<span id="733"> 733</span>
<span id="734"> 734</span>
<span id="735"> 735</span>
<span id="736"> 736</span>
<span id="737"> 737</span>
<span id="738"> 738</span>
<span id="739"> 739</span>
<span id="740"> 740</span>
<span id="741"> 741</span>
<span id="742"> 742</span>
<span id="743"> 743</span>
<span id="744"> 744</span>
<span id="745"> 745</span>
<span id="746"> 746</span>
<span id="747"> 747</span>
<span id="748"> 748</span>
<span id="749"> 749</span>
<span id="750"> 750</span>
<span id="751"> 751</span>
<span id="752"> 752</span>
<span id="753"> 753</span>
<span id="754"> 754</span>
<span id="755"> 755</span>
<span id="756"> 756</span>
<span id="757"> 757</span>
<span id="758"> 758</span>
<span id="759"> 759</span>
<span id="760"> 760</span>
<span id="761"> 761</span>
<span id="762"> 762</span>
<span id="763"> 763</span>
<span id="764"> 764</span>
<span id="765"> 765</span>
<span id="766"> 766</span>
<span id="767"> 767</span>
<span id="768"> 768</span>
<span id="769"> 769</span>
<span id="770"> 770</span>
<span id="771"> 771</span>
<span id="772"> 772</span>
<span id="773"> 773</span>
<span id="774"> 774</span>
<span id="775"> 775</span>
<span id="776"> 776</span>
<span id="777"> 777</span>
<span id="778"> 778</span>
<span id="779"> 779</span>
<span id="780"> 780</span>
<span id="781"> 781</span>
<span id="782"> 782</span>
<span id="783"> 783</span>
<span id="784"> 784</span>
<span id="785"> 785</span>
<span id="786"> 786</span>
<span id="787"> 787</span>
<span id="788"> 788</span>
<span id="789"> 789</span>
<span id="790"> 790</span>
<span id="791"> 791</span>
<span id="792"> 792</span>
<span id="793"> 793</span>
<span id="794"> 794</span>
<span id="795"> 795</span>
<span id="796"> 796</span>
<span id="797"> 797</span>
<span id="798"> 798</span>
<span id="799"> 799</span>
<span id="800"> 800</span>
<span id="801"> 801</span>
<span id="802"> 802</span>
<span id="803"> 803</span>
<span id="804"> 804</span>
<span id="805"> 805</span>
<span id="806"> 806</span>
<span id="807"> 807</span>
<span id="808"> 808</span>
<span id="809"> 809</span>
<span id="810"> 810</span>
<span id="811"> 811</span>
<span id="812"> 812</span>
<span id="813"> 813</span>
<span id="814"> 814</span>
<span id="815"> 815</span>
<span id="816"> 816</span>
<span id="817"> 817</span>
<span id="818"> 818</span>
<span id="819"> 819</span>
<span id="820"> 820</span>
<span id="821"> 821</span>
<span id="822"> 822</span>
<span id="823"> 823</span>
<span id="824"> 824</span>
<span id="825"> 825</span>
<span id="826"> 826</span>
<span id="827"> 827</span>
<span id="828"> 828</span>
<span id="829"> 829</span>
<span id="830"> 830</span>
<span id="831"> 831</span>
<span id="832"> 832</span>
<span id="833"> 833</span>
<span id="834"> 834</span>
<span id="835"> 835</span>
<span id="836"> 836</span>
<span id="837"> 837</span>
<span id="838"> 838</span>
<span id="839"> 839</span>
<span id="840"> 840</span>
<span id="841"> 841</span>
<span id="842"> 842</span>
<span id="843"> 843</span>
<span id="844"> 844</span>
<span id="845"> 845</span>
<span id="846"> 846</span>
<span id="847"> 847</span>
<span id="848"> 848</span>
<span id="849"> 849</span>
<span id="850"> 850</span>
<span id="851"> 851</span>
<span id="852"> 852</span>
<span id="853"> 853</span>
<span id="854"> 854</span>
<span id="855"> 855</span>
<span id="856"> 856</span>
<span id="857"> 857</span>
<span id="858"> 858</span>
<span id="859"> 859</span>
<span id="860"> 860</span>
<span id="861"> 861</span>
<span id="862"> 862</span>
<span id="863"> 863</span>
<span id="864"> 864</span>
<span id="865"> 865</span>
<span id="866"> 866</span>
<span id="867"> 867</span>
<span id="868"> 868</span>
<span id="869"> 869</span>
<span id="870"> 870</span>
<span id="871"> 871</span>
<span id="872"> 872</span>
<span id="873"> 873</span>
<span id="874"> 874</span>
<span id="875"> 875</span>
<span id="876"> 876</span>
<span id="877"> 877</span>
<span id="878"> 878</span>
<span id="879"> 879</span>
<span id="880"> 880</span>
<span id="881"> 881</span>
<span id="882"> 882</span>
<span id="883"> 883</span>
<span id="884"> 884</span>
<span id="885"> 885</span>
<span id="886"> 886</span>
<span id="887"> 887</span>
<span id="888"> 888</span>
<span id="889"> 889</span>
<span id="890"> 890</span>
<span id="891"> 891</span>
<span id="892"> 892</span>
<span id="893"> 893</span>
<span id="894"> 894</span>
<span id="895"> 895</span>
<span id="896"> 896</span>
<span id="897"> 897</span>
<span id="898"> 898</span>
<span id="899"> 899</span>
<span id="900"> 900</span>
<span id="901"> 901</span>
<span id="902"> 902</span>
<span id="903"> 903</span>
<span id="904"> 904</span>
<span id="905"> 905</span>
<span id="906"> 906</span>
<span id="907"> 907</span>
<span id="908"> 908</span>
<span id="909"> 909</span>
<span id="910"> 910</span>
<span id="911"> 911</span>
<span id="912"> 912</span>
<span id="913"> 913</span>
<span id="914"> 914</span>
<span id="915"> 915</span>
<span id="916"> 916</span>
<span id="917"> 917</span>
<span id="918"> 918</span>
<span id="919"> 919</span>
<span id="920"> 920</span>
<span id="921"> 921</span>
<span id="922"> 922</span>
<span id="923"> 923</span>
<span id="924"> 924</span>
<span id="925"> 925</span>
<span id="926"> 926</span>
<span id="927"> 927</span>
<span id="928"> 928</span>
<span id="929"> 929</span>
<span id="930"> 930</span>
<span id="931"> 931</span>
<span id="932"> 932</span>
<span id="933"> 933</span>
<span id="934"> 934</span>
<span id="935"> 935</span>
<span id="936"> 936</span>
<span id="937"> 937</span>
<span id="938"> 938</span>
<span id="939"> 939</span>
<span id="940"> 940</span>
<span id="941"> 941</span>
<span id="942"> 942</span>
<span id="943"> 943</span>
<span id="944"> 944</span>
<span id="945"> 945</span>
<span id="946"> 946</span>
<span id="947"> 947</span>
<span id="948"> 948</span>
<span id="949"> 949</span>
<span id="950"> 950</span>
<span id="951"> 951</span>
<span id="952"> 952</span>
<span id="953"> 953</span>
<span id="954"> 954</span>
<span id="955"> 955</span>
<span id="956"> 956</span>
<span id="957"> 957</span>
<span id="958"> 958</span>
<span id="959"> 959</span>
<span id="960"> 960</span>
<span id="961"> 961</span>
<span id="962"> 962</span>
<span id="963"> 963</span>
<span id="964"> 964</span>
<span id="965"> 965</span>
<span id="966"> 966</span>
<span id="967"> 967</span>
<span id="968"> 968</span>
<span id="969"> 969</span>
<span id="970"> 970</span>
<span id="971"> 971</span>
<span id="972"> 972</span>
<span id="973"> 973</span>
<span id="974"> 974</span>
<span id="975"> 975</span>
<span id="976"> 976</span>
<span id="977"> 977</span>
<span id="978"> 978</span>
<span id="979"> 979</span>
<span id="980"> 980</span>
<span id="981"> 981</span>
<span id="982"> 982</span>
<span id="983"> 983</span>
<span id="984"> 984</span>
<span id="985"> 985</span>
<span id="986"> 986</span>
<span id="987"> 987</span>
<span id="988"> 988</span>
<span id="989"> 989</span>
<span id="990"> 990</span>
<span id="991"> 991</span>
<span id="992"> 992</span>
<span id="993"> 993</span>
<span id="994"> 994</span>
<span id="995"> 995</span>
<span id="996"> 996</span>
<span id="997"> 997</span>
<span id="998"> 998</span>
<span id="999"> 999</span>
<span id="1000">1000</span>
<span id="1001">1001</span>
<span id="1002">1002</span>
<span id="1003">1003</span>
<span id="1004">1004</span>
<span id="1005">1005</span>
<span id="1006">1006</span>
<span id="1007">1007</span>
<span id="1008">1008</span>
<span id="1009">1009</span>
<span id="1010">1010</span>
<span id="1011">1011</span>
<span id="1012">1012</span>
<span id="1013">1013</span>
<span id="1014">1014</span>
<span id="1015">1015</span>
<span id="1016">1016</span>
<span id="1017">1017</span>
<span id="1018">1018</span>
<span id="1019">1019</span>
<span id="1020">1020</span>
<span id="1021">1021</span>
<span id="1022">1022</span>
<span id="1023">1023</span>
<span id="1024">1024</span>
<span id="1025">1025</span>
<span id="1026">1026</span>
<span id="1027">1027</span>
<span id="1028">1028</span>
<span id="1029">1029</span>
<span id="1030">1030</span>
<span id="1031">1031</span>
<span id="1032">1032</span>
<span id="1033">1033</span>
<span id="1034">1034</span>
<span id="1035">1035</span>
<span id="1036">1036</span>
<span id="1037">1037</span>
<span id="1038">1038</span>
<span id="1039">1039</span>
<span id="1040">1040</span>
<span id="1041">1041</span>
<span id="1042">1042</span>
<span id="1043">1043</span>
<span id="1044">1044</span>
<span id="1045">1045</span>
<span id="1046">1046</span>
<span id="1047">1047</span>
<span id="1048">1048</span>
<span id="1049">1049</span>
<span id="1050">1050</span>
<span id="1051">1051</span>
<span id="1052">1052</span>
<span id="1053">1053</span>
<span id="1054">1054</span>
<span id="1055">1055</span>
<span id="1056">1056</span>
<span id="1057">1057</span>
<span id="1058">1058</span>
<span id="1059">1059</span>
<span id="1060">1060</span>
<span id="1061">1061</span>
<span id="1062">1062</span>
<span id="1063">1063</span>
<span id="1064">1064</span>
<span id="1065">1065</span>
<span id="1066">1066</span>
<span id="1067">1067</span>
<span id="1068">1068</span>
<span id="1069">1069</span>
<span id="1070">1070</span>
<span id="1071">1071</span>
<span id="1072">1072</span>
<span id="1073">1073</span>
<span id="1074">1074</span>
<span id="1075">1075</span>
<span id="1076">1076</span>
<span id="1077">1077</span>
<span id="1078">1078</span>
<span id="1079">1079</span>
<span id="1080">1080</span>
<span id="1081">1081</span>
<span id="1082">1082</span>
<span id="1083">1083</span>
<span id="1084">1084</span>
<span id="1085">1085</span>
<span id="1086">1086</span>
<span id="1087">1087</span>
<span id="1088">1088</span>
<span id="1089">1089</span>
<span id="1090">1090</span>
<span id="1091">1091</span>
<span id="1092">1092</span>
<span id="1093">1093</span>
<span id="1094">1094</span>
<span id="1095">1095</span>
<span id="1096">1096</span>
<span id="1097">1097</span>
<span id="1098">1098</span>
<span id="1099">1099</span>
<span id="1100">1100</span>
<span id="1101">1101</span>
<span id="1102">1102</span>
<span id="1103">1103</span>
<span id="1104">1104</span>
<span id="1105">1105</span>
<span id="1106">1106</span>
<span id="1107">1107</span>
<span id="1108">1108</span>
<span id="1109">1109</span>
<span id="1110">1110</span>
<span id="1111">1111</span>
<span id="1112">1112</span>
<span id="1113">1113</span>
<span id="1114">1114</span>
<span id="1115">1115</span>
<span id="1116">1116</span>
<span id="1117">1117</span>
<span id="1118">1118</span>
<span id="1119">1119</span>
<span id="1120">1120</span>
<span id="1121">1121</span>
<span id="1122">1122</span>
<span id="1123">1123</span>
<span id="1124">1124</span>
<span id="1125">1125</span>
<span id="1126">1126</span>
<span id="1127">1127</span>
<span id="1128">1128</span>
<span id="1129">1129</span>
<span id="1130">1130</span>
<span id="1131">1131</span>
<span id="1132">1132</span>
<span id="1133">1133</span>
<span id="1134">1134</span>
<span id="1135">1135</span>
<span id="1136">1136</span>
<span id="1137">1137</span>
<span id="1138">1138</span>
<span id="1139">1139</span>
<span id="1140">1140</span>
<span id="1141">1141</span>
<span id="1142">1142</span>
<span id="1143">1143</span>
<span id="1144">1144</span>
<span id="1145">1145</span>
<span id="1146">1146</span>
<span id="1147">1147</span>
<span id="1148">1148</span>
<span id="1149">1149</span>
<span id="1150">1150</span>
<span id="1151">1151</span>
<span id="1152">1152</span>
<span id="1153">1153</span>
<span id="1154">1154</span>
<span id="1155">1155</span>
<span id="1156">1156</span>
<span id="1157">1157</span>
<span id="1158">1158</span>
<span id="1159">1159</span>
<span id="1160">1160</span>
<span id="1161">1161</span>
<span id="1162">1162</span>
<span id="1163">1163</span>
<span id="1164">1164</span>
<span id="1165">1165</span>
<span id="1166">1166</span>
<span id="1167">1167</span>
<span id="1168">1168</span>
<span id="1169">1169</span>
<span id="1170">1170</span>
<span id="1171">1171</span>
<span id="1172">1172</span>
<span id="1173">1173</span>
<span id="1174">1174</span>
<span id="1175">1175</span>
<span id="1176">1176</span>
<span id="1177">1177</span>
<span id="1178">1178</span>
<span id="1179">1179</span>
<span id="1180">1180</span>
<span id="1181">1181</span>
<span id="1182">1182</span>
<span id="1183">1183</span>
<span id="1184">1184</span>
<span id="1185">1185</span>
<span id="1186">1186</span>
<span id="1187">1187</span>
<span id="1188">1188</span>
<span id="1189">1189</span>
<span id="1190">1190</span>
<span id="1191">1191</span>
<span id="1192">1192</span>
<span id="1193">1193</span>
<span id="1194">1194</span>
<span id="1195">1195</span>
<span id="1196">1196</span>
<span id="1197">1197</span>
<span id="1198">1198</span>
<span id="1199">1199</span>
<span id="1200">1200</span>
<span id="1201">1201</span>
<span id="1202">1202</span>
<span id="1203">1203</span>
<span id="1204">1204</span>
<span id="1205">1205</span>
<span id="1206">1206</span>
<span id="1207">1207</span>
<span id="1208">1208</span>
<span id="1209">1209</span>
<span id="1210">1210</span>
<span id="1211">1211</span>
<span id="1212">1212</span>
<span id="1213">1213</span>
<span id="1214">1214</span>
<span id="1215">1215</span>
<span id="1216">1216</span>
<span id="1217">1217</span>
<span id="1218">1218</span>
<span id="1219">1219</span>
<span id="1220">1220</span>
<span id="1221">1221</span>
<span id="1222">1222</span>
<span id="1223">1223</span>
<span id="1224">1224</span>
<span id="1225">1225</span>
<span id="1226">1226</span>
<span id="1227">1227</span>
<span id="1228">1228</span>
<span id="1229">1229</span>
<span id="1230">1230</span>
<span id="1231">1231</span>
<span id="1232">1232</span>
<span id="1233">1233</span>
<span id="1234">1234</span>
<span id="1235">1235</span>
<span id="1236">1236</span>
<span id="1237">1237</span>
<span id="1238">1238</span>
<span id="1239">1239</span>
<span id="1240">1240</span>
<span id="1241">1241</span>
<span id="1242">1242</span>
<span id="1243">1243</span>
<span id="1244">1244</span>
<span id="1245">1245</span>
<span id="1246">1246</span>
<span id="1247">1247</span>
<span id="1248">1248</span>
<span id="1249">1249</span>
<span id="1250">1250</span>
<span id="1251">1251</span>
<span id="1252">1252</span>
<span id="1253">1253</span>
<span id="1254">1254</span>
<span id="1255">1255</span>
<span id="1256">1256</span>
<span id="1257">1257</span>
<span id="1258">1258</span>
<span id="1259">1259</span>
<span id="1260">1260</span>
<span id="1261">1261</span>
<span id="1262">1262</span>
<span id="1263">1263</span>
<span id="1264">1264</span>
<span id="1265">1265</span>
<span id="1266">1266</span>
<span id="1267">1267</span>
<span id="1268">1268</span>
<span id="1269">1269</span>
<span id="1270">1270</span>
<span id="1271">1271</span>
<span id="1272">1272</span>
<span id="1273">1273</span>
<span id="1274">1274</span>
<span id="1275">1275</span>
<span id="1276">1276</span>
<span id="1277">1277</span>
<span id="1278">1278</span>
<span id="1279">1279</span>
<span id="1280">1280</span>
<span id="1281">1281</span>
<span id="1282">1282</span>
<span id="1283">1283</span>
<span id="1284">1284</span>
<span id="1285">1285</span>
<span id="1286">1286</span>
<span id="1287">1287</span>
<span id="1288">1288</span>
<span id="1289">1289</span>
<span id="1290">1290</span>
<span id="1291">1291</span>
<span id="1292">1292</span>
<span id="1293">1293</span>
<span id="1294">1294</span>
<span id="1295">1295</span>
<span id="1296">1296</span>
<span id="1297">1297</span>
<span id="1298">1298</span>
<span id="1299">1299</span>
<span id="1300">1300</span>
<span id="1301">1301</span>
<span id="1302">1302</span>
<span id="1303">1303</span>
<span id="1304">1304</span>
<span id="1305">1305</span>
<span id="1306">1306</span>
<span id="1307">1307</span>
<span id="1308">1308</span>
<span id="1309">1309</span>
<span id="1310">1310</span>
<span id="1311">1311</span>
<span id="1312">1312</span>
<span id="1313">1313</span>
<span id="1314">1314</span>
<span id="1315">1315</span>
<span id="1316">1316</span>
<span id="1317">1317</span>
<span id="1318">1318</span>
<span id="1319">1319</span>
<span id="1320">1320</span>
<span id="1321">1321</span>
<span id="1322">1322</span>
<span id="1323">1323</span>
<span id="1324">1324</span>
<span id="1325">1325</span>
<span id="1326">1326</span>
<span id="1327">1327</span>
<span id="1328">1328</span>
<span id="1329">1329</span>
<span id="1330">1330</span>
<span id="1331">1331</span>
<span id="1332">1332</span>
<span id="1333">1333</span>
<span id="1334">1334</span>
<span id="1335">1335</span>
<span id="1336">1336</span>
<span id="1337">1337</span>
<span id="1338">1338</span>
<span id="1339">1339</span>
<span id="1340">1340</span>
<span id="1341">1341</span>
<span id="1342">1342</span>
<span id="1343">1343</span>
<span id="1344">1344</span>
<span id="1345">1345</span>
<span id="1346">1346</span>
<span id="1347">1347</span>
<span id="1348">1348</span>
<span id="1349">1349</span>
<span id="1350">1350</span>
<span id="1351">1351</span>
<span id="1352">1352</span>
<span id="1353">1353</span>
<span id="1354">1354</span>
<span id="1355">1355</span>
<span id="1356">1356</span>
</pre><div class="example-wrap"><pre class="rust ">
<span class="doccomment">//! A multi-producer, single-consumer queue for sending values across</span>
<span class="doccomment">//! asynchronous tasks.</span>
<span class="doccomment">//!</span>
<span class="doccomment">//! Similarly to the `std`, channel creation provides [`Receiver`] and</span>
<span class="doccomment">//! [`Sender`] handles. [`Receiver`] implements [`Stream`] and allows a task to</span>
<span class="doccomment">//! read values out of the channel. If there is no message to read from the</span>
<span class="doccomment">//! channel, the current task will be notified when a new value is sent.</span>
<span class="doccomment">//! [`Sender`] implements the `Sink` trait and allows a task to send messages into</span>
<span class="doccomment">//! the channel. If the channel is at capacity, the send will be rejected and</span>
<span class="doccomment">//! the task will be notified when additional capacity is available. In other</span>
<span class="doccomment">//! words, the channel provides backpressure.</span>
<span class="doccomment">//!</span>
<span class="doccomment">//! Unbounded channels are also available using the `unbounded` constructor.</span>
<span class="doccomment">//!</span>
<span class="doccomment">//! # Disconnection</span>
<span class="doccomment">//!</span>
<span class="doccomment">//! When all [`Sender`] handles have been dropped, it is no longer</span>
<span class="doccomment">//! possible to send values into the channel. This is considered the termination</span>
<span class="doccomment">//! event of the stream. As such, [`Receiver::poll_next`]</span>
<span class="doccomment">//! will return `Ok(Ready(None))`.</span>
<span class="doccomment">//!</span>
<span class="doccomment">//! If the [`Receiver`] handle is dropped, then messages can no longer</span>
<span class="doccomment">//! be read out of the channel. In this case, all further attempts to send will</span>
<span class="doccomment">//! result in an error.</span>
<span class="doccomment">//!</span>
<span class="doccomment">//! # Clean Shutdown</span>
<span class="doccomment">//!</span>
<span class="doccomment">//! If the [`Receiver`] is simply dropped, then it is possible for</span>
<span class="doccomment">//! there to be messages still in the channel that will not be processed. As</span>
<span class="doccomment">//! such, it is usually desirable to perform a &quot;clean&quot; shutdown. To do this, the</span>
<span class="doccomment">//! receiver will first call `close`, which will prevent any further messages to</span>
<span class="doccomment">//! be sent into the channel. Then, the receiver consumes the channel to</span>
<span class="doccomment">//! completion, at which point the receiver can be dropped.</span>
<span class="doccomment">//!</span>
<span class="doccomment">//! [`Sender`]: struct.Sender.html</span>
<span class="doccomment">//! [`Receiver`]: struct.Receiver.html</span>
<span class="doccomment">//! [`Stream`]: ../../futures_core/stream/trait.Stream.html</span>
<span class="doccomment">//! [`Receiver::poll_next`]:</span>
<span class="doccomment">//! ../../futures_core/stream/trait.Stream.html#tymethod.poll_next</span>
<span class="comment">// At the core, the channel uses an atomic FIFO queue for message passing. This</span>
<span class="comment">// queue is used as the primary coordination primitive. In order to enforce</span>
<span class="comment">// capacity limits and handle back pressure, a secondary FIFO queue is used to</span>
<span class="comment">// send parked task handles.</span>
<span class="comment">//</span>
<span class="comment">// The general idea is that the channel is created with a `buffer` size of `n`.</span>
<span class="comment">// The channel capacity is `n + num-senders`. Each sender gets one &quot;guaranteed&quot;</span>
<span class="comment">// slot to hold a message. This allows `Sender` to know for a fact that a send</span>
<span class="comment">// will succeed *before* starting to do the actual work of sending the value.</span>
<span class="comment">// Since most of this work is lock-free, once the work starts, it is impossible</span>
<span class="comment">// to safely revert.</span>
<span class="comment">//</span>
<span class="comment">// If the sender is unable to process a send operation, then the current</span>
<span class="comment">// task is parked and the handle is sent on the parked task queue.</span>
<span class="comment">//</span>
<span class="comment">// Note that the implementation guarantees that the channel capacity will never</span>
<span class="comment">// exceed the configured limit, however there is no *strict* guarantee that the</span>
<span class="comment">// receiver will wake up a parked task *immediately* when a slot becomes</span>
<span class="comment">// available. However, it will almost always unpark a task when a slot becomes</span>
<span class="comment">// available and it is *guaranteed* that a sender will be unparked when the</span>
<span class="comment">// message that caused the sender to become parked is read out of the channel.</span>
<span class="comment">//</span>
<span class="comment">// The steps for sending a message are roughly:</span>
<span class="comment">//</span>
<span class="comment">// 1) Increment the channel message count</span>
<span class="comment">// 2) If the channel is at capacity, push the task handle onto the wait queue</span>
<span class="comment">// 3) Push the message onto the message queue.</span>
<span class="comment">//</span>
<span class="comment">// The steps for receiving a message are roughly:</span>
<span class="comment">//</span>
<span class="comment">// 1) Pop a message from the message queue</span>
<span class="comment">// 2) Pop a task handle from the wait queue</span>
<span class="comment">// 3) Decrement the channel message count.</span>
<span class="comment">//</span>
<span class="comment">// It&#39;s important for the order of operations on lock-free structures to happen</span>
<span class="comment">// in reverse order between the sender and receiver. This makes the message</span>
<span class="comment">// queue the primary coordination structure and establishes the necessary</span>
<span class="comment">// happens-before semantics required for the acquire / release semantics used</span>
<span class="comment">// by the queue structure.</span>
<span class="kw">use</span> <span class="ident">futures_core</span>::<span class="ident">stream</span>::{<span class="ident">FusedStream</span>, <span class="ident">Stream</span>};
<span class="kw">use</span> <span class="ident">futures_core</span>::<span class="ident">task</span>::{<span class="ident">Context</span>, <span class="ident">Poll</span>, <span class="ident">Waker</span>};
<span class="kw">use</span> <span class="ident">futures_core</span>::<span class="ident">task</span>::<span class="ident">__internal</span>::<span class="ident">AtomicWaker</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">fmt</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">pin</span>::<span class="ident">Pin</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">sync</span>::{<span class="ident">Arc</span>, <span class="ident">Mutex</span>};
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">sync</span>::<span class="ident">atomic</span>::<span class="ident">AtomicUsize</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">sync</span>::<span class="ident">atomic</span>::<span class="ident">Ordering</span>::<span class="ident">SeqCst</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">thread</span>;
<span class="kw">use</span> <span class="kw">crate</span>::<span class="ident">mpsc</span>::<span class="ident">queue</span>::<span class="ident">Queue</span>;
<span class="kw">mod</span> <span class="ident">queue</span>;
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;sink&quot;</span>)]</span>
<span class="kw">mod</span> <span class="ident">sink_impl</span>;
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">struct</span> <span class="ident">UnboundedSenderInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="comment">// Channel state shared between the sender and receiver.</span>
<span class="ident">inner</span>: <span class="ident">Arc</span><span class="op">&lt;</span><span class="ident">UnboundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">struct</span> <span class="ident">BoundedSenderInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="comment">// Channel state shared between the sender and receiver.</span>
<span class="ident">inner</span>: <span class="ident">Arc</span><span class="op">&lt;</span><span class="ident">BoundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span>,
<span class="comment">// Handle to the task that is blocked on this sender. This handle is sent</span>
<span class="comment">// to the receiver half in order to be notified when the sender becomes</span>
<span class="comment">// unblocked.</span>
<span class="ident">sender_task</span>: <span class="ident">Arc</span><span class="op">&lt;</span><span class="ident">Mutex</span><span class="op">&lt;</span><span class="ident">SenderTask</span><span class="op">&gt;</span><span class="op">&gt;</span>,
<span class="comment">// `true` if the sender might be blocked. This is an optimization to avoid</span>
<span class="comment">// having to lock the mutex most of the time.</span>
<span class="ident">maybe_parked</span>: <span class="ident">bool</span>,
}
<span class="comment">// We never project Pin&lt;&amp;mut SenderInner&gt; to `Pin&lt;&amp;mut T&gt;`</span>
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Unpin</span> <span class="kw">for</span> <span class="ident">UnboundedSenderInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Unpin</span> <span class="kw">for</span> <span class="ident">BoundedSenderInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {}
<span class="doccomment">/// The transmission end of a bounded mpsc channel.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This value is created by the [`channel`](channel) function.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Sender</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>(<span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">BoundedSenderInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span>);
<span class="doccomment">/// The transmission end of an unbounded mpsc channel.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This value is created by the [`unbounded`](unbounded) function.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">UnboundedSender</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>(<span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">UnboundedSenderInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span>);
<span class="kw">trait</span> <span class="ident">AssertKinds</span>: <span class="ident">Send</span> <span class="op">+</span> <span class="ident">Sync</span> <span class="op">+</span> <span class="ident">Clone</span> {}
<span class="kw">impl</span> <span class="ident">AssertKinds</span> <span class="kw">for</span> <span class="ident">UnboundedSender</span><span class="op">&lt;</span><span class="ident">u32</span><span class="op">&gt;</span> {}
<span class="doccomment">/// The receiving end of a bounded mpsc channel.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This value is created by the [`channel`](channel) function.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Receiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="ident">inner</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Arc</span><span class="op">&lt;</span><span class="ident">BoundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span><span class="op">&gt;</span>,
}
<span class="doccomment">/// The receiving end of an unbounded mpsc channel.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This value is created by the [`unbounded`](unbounded) function.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">UnboundedReceiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="ident">inner</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Arc</span><span class="op">&lt;</span><span class="ident">UnboundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span><span class="op">&gt;</span>,
}
<span class="comment">// `Pin&lt;&amp;mut UnboundedReceiver&lt;T&gt;&gt;` is never projected to `Pin&lt;&amp;mut T&gt;`</span>
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Unpin</span> <span class="kw">for</span> <span class="ident">UnboundedReceiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {}
<span class="doccomment">/// The error type for [`Sender`s](Sender) used as `Sink`s.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Debug</span>, <span class="ident">PartialEq</span>, <span class="ident">Eq</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">SendError</span> {
<span class="ident">kind</span>: <span class="ident">SendErrorKind</span>,
}
<span class="doccomment">/// The error type returned from [`try_send`](Sender::try_send).</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">PartialEq</span>, <span class="ident">Eq</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">TrySendError</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="ident">err</span>: <span class="ident">SendError</span>,
<span class="ident">val</span>: <span class="ident">T</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Debug</span>, <span class="ident">PartialEq</span>, <span class="ident">Eq</span>)]</span>
<span class="kw">enum</span> <span class="ident">SendErrorKind</span> {
<span class="ident">Full</span>,
<span class="ident">Disconnected</span>,
}
<span class="doccomment">/// The error type returned from [`try_next`](Receiver::try_next).</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">TryRecvError</span> {
<span class="ident">_priv</span>: (),
}
<span class="kw">impl</span> <span class="ident">fmt</span>::<span class="ident">Display</span> <span class="kw">for</span> <span class="ident">SendError</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">fmt</span>::<span class="ident">Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">fmt</span>::<span class="prelude-ty">Result</span> {
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">is_full</span>() {
<span class="macro">write</span><span class="macro">!</span>(<span class="ident">f</span>, <span class="string">&quot;send failed because channel is full&quot;</span>)
} <span class="kw">else</span> {
<span class="macro">write</span><span class="macro">!</span>(<span class="ident">f</span>, <span class="string">&quot;send failed because receiver is gone&quot;</span>)
}
}
}
<span class="kw">impl</span> <span class="ident">std</span>::<span class="ident">error</span>::<span class="ident">Error</span> <span class="kw">for</span> <span class="ident">SendError</span> {}
<span class="kw">impl</span> <span class="ident">SendError</span> {
<span class="doccomment">/// Returns `true` if this error is a result of the channel being full.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">is_full</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">kind</span> {
<span class="ident">SendErrorKind</span>::<span class="ident">Full</span> <span class="op">=</span><span class="op">&gt;</span> <span class="bool-val">true</span>,
<span class="kw">_</span> <span class="op">=</span><span class="op">&gt;</span> <span class="bool-val">false</span>,
}
}
<span class="doccomment">/// Returns `true` if this error is a result of the receiver being dropped.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">is_disconnected</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">kind</span> {
<span class="ident">SendErrorKind</span>::<span class="ident">Disconnected</span> <span class="op">=</span><span class="op">&gt;</span> <span class="bool-val">true</span>,
<span class="kw">_</span> <span class="op">=</span><span class="op">&gt;</span> <span class="bool-val">false</span>,
}
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">fmt</span>::<span class="ident">Debug</span> <span class="kw">for</span> <span class="ident">TrySendError</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">fmt</span>::<span class="ident">Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">fmt</span>::<span class="prelude-ty">Result</span> {
<span class="ident">f</span>.<span class="ident">debug_struct</span>(<span class="string">&quot;TrySendError&quot;</span>)
.<span class="ident">field</span>(<span class="string">&quot;kind&quot;</span>, <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">err</span>.<span class="ident">kind</span>)
.<span class="ident">finish</span>()
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">fmt</span>::<span class="ident">Display</span> <span class="kw">for</span> <span class="ident">TrySendError</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">fmt</span>::<span class="ident">Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">fmt</span>::<span class="prelude-ty">Result</span> {
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">is_full</span>() {
<span class="macro">write</span><span class="macro">!</span>(<span class="ident">f</span>, <span class="string">&quot;send failed because channel is full&quot;</span>)
} <span class="kw">else</span> {
<span class="macro">write</span><span class="macro">!</span>(<span class="ident">f</span>, <span class="string">&quot;send failed because receiver is gone&quot;</span>)
}
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">core</span>::<span class="ident">any</span>::<span class="ident">Any</span><span class="op">&gt;</span> <span class="ident">std</span>::<span class="ident">error</span>::<span class="ident">Error</span> <span class="kw">for</span> <span class="ident">TrySendError</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">TrySendError</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="doccomment">/// Returns `true` if this error is a result of the channel being full.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">is_full</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="self">self</span>.<span class="ident">err</span>.<span class="ident">is_full</span>()
}
<span class="doccomment">/// Returns `true` if this error is a result of the receiver being dropped.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">is_disconnected</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="self">self</span>.<span class="ident">err</span>.<span class="ident">is_disconnected</span>()
}
<span class="doccomment">/// Returns the message that was attempted to be sent but failed.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">into_inner</span>(<span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">T</span> {
<span class="self">self</span>.<span class="ident">val</span>
}
<span class="doccomment">/// Drops the message and converts into a `SendError`.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">into_send_error</span>(<span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">SendError</span> {
<span class="self">self</span>.<span class="ident">err</span>
}
}
<span class="kw">impl</span> <span class="ident">fmt</span>::<span class="ident">Debug</span> <span class="kw">for</span> <span class="ident">TryRecvError</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">fmt</span>::<span class="ident">Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">fmt</span>::<span class="prelude-ty">Result</span> {
<span class="ident">f</span>.<span class="ident">debug_tuple</span>(<span class="string">&quot;TryRecvError&quot;</span>)
.<span class="ident">finish</span>()
}
}
<span class="kw">impl</span> <span class="ident">fmt</span>::<span class="ident">Display</span> <span class="kw">for</span> <span class="ident">TryRecvError</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">fmt</span>::<span class="ident">Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">fmt</span>::<span class="prelude-ty">Result</span> {
<span class="macro">write</span><span class="macro">!</span>(<span class="ident">f</span>, <span class="string">&quot;receiver channel is empty&quot;</span>)
}
}
<span class="kw">impl</span> <span class="ident">std</span>::<span class="ident">error</span>::<span class="ident">Error</span> <span class="kw">for</span> <span class="ident">TryRecvError</span> {}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">struct</span> <span class="ident">UnboundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="comment">// Internal channel state. Consists of the number of messages stored in the</span>
<span class="comment">// channel as well as a flag signalling that the channel is closed.</span>
<span class="ident">state</span>: <span class="ident">AtomicUsize</span>,
<span class="comment">// Atomic, FIFO queue used to send messages to the receiver</span>
<span class="ident">message_queue</span>: <span class="ident">Queue</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>,
<span class="comment">// Number of senders in existence</span>
<span class="ident">num_senders</span>: <span class="ident">AtomicUsize</span>,
<span class="comment">// Handle to the receiver&#39;s task.</span>
<span class="ident">recv_task</span>: <span class="ident">AtomicWaker</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">struct</span> <span class="ident">BoundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="comment">// Max buffer size of the channel. If `None` then the channel is unbounded.</span>
<span class="ident">buffer</span>: <span class="ident">usize</span>,
<span class="comment">// Internal channel state. Consists of the number of messages stored in the</span>
<span class="comment">// channel as well as a flag signalling that the channel is closed.</span>
<span class="ident">state</span>: <span class="ident">AtomicUsize</span>,
<span class="comment">// Atomic, FIFO queue used to send messages to the receiver</span>
<span class="ident">message_queue</span>: <span class="ident">Queue</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>,
<span class="comment">// Atomic, FIFO queue used to send parked task handles to the receiver.</span>
<span class="ident">parked_queue</span>: <span class="ident">Queue</span><span class="op">&lt;</span><span class="ident">Arc</span><span class="op">&lt;</span><span class="ident">Mutex</span><span class="op">&lt;</span><span class="ident">SenderTask</span><span class="op">&gt;</span><span class="op">&gt;</span><span class="op">&gt;</span>,
<span class="comment">// Number of senders in existence</span>
<span class="ident">num_senders</span>: <span class="ident">AtomicUsize</span>,
<span class="comment">// Handle to the receiver&#39;s task.</span>
<span class="ident">recv_task</span>: <span class="ident">AtomicWaker</span>,
}
<span class="comment">// Struct representation of `Inner::state`.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Clone</span>, <span class="ident">Copy</span>)]</span>
<span class="kw">struct</span> <span class="ident">State</span> {
<span class="comment">// `true` when the channel is open</span>
<span class="ident">is_open</span>: <span class="ident">bool</span>,
<span class="comment">// Number of messages in the channel</span>
<span class="ident">num_messages</span>: <span class="ident">usize</span>,
}
<span class="comment">// The `is_open` flag is stored in the left-most bit of `Inner::state`</span>
<span class="kw">const</span> <span class="ident">OPEN_MASK</span>: <span class="ident">usize</span> <span class="op">=</span> <span class="ident">usize</span>::<span class="ident">max_value</span>() <span class="op">-</span> (<span class="ident">usize</span>::<span class="ident">max_value</span>() <span class="op">&gt;</span><span class="op">&gt;</span> <span class="number">1</span>);
<span class="comment">// When a new channel is created, it is created in the open state with no</span>
<span class="comment">// pending messages.</span>
<span class="kw">const</span> <span class="ident">INIT_STATE</span>: <span class="ident">usize</span> <span class="op">=</span> <span class="ident">OPEN_MASK</span>;
<span class="comment">// The maximum number of messages that a channel can track is `usize::max_value() &gt;&gt; 1`</span>
<span class="kw">const</span> <span class="ident">MAX_CAPACITY</span>: <span class="ident">usize</span> <span class="op">=</span> <span class="op">!</span>(<span class="ident">OPEN_MASK</span>);
<span class="comment">// The maximum requested buffer size must be less than the maximum capacity of</span>
<span class="comment">// a channel. This is because each sender gets a guaranteed slot.</span>
<span class="kw">const</span> <span class="ident">MAX_BUFFER</span>: <span class="ident">usize</span> <span class="op">=</span> <span class="ident">MAX_CAPACITY</span> <span class="op">&gt;</span><span class="op">&gt;</span> <span class="number">1</span>;
<span class="comment">// Sent to the consumer to wake up blocked producers</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">struct</span> <span class="ident">SenderTask</span> {
<span class="ident">task</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Waker</span><span class="op">&gt;</span>,
<span class="ident">is_parked</span>: <span class="ident">bool</span>,
}
<span class="kw">impl</span> <span class="ident">SenderTask</span> {
<span class="kw">fn</span> <span class="ident">new</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">Self</span> {
<span class="ident">task</span>: <span class="prelude-val">None</span>,
<span class="ident">is_parked</span>: <span class="bool-val">false</span>,
}
}
<span class="kw">fn</span> <span class="ident">notify</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
<span class="self">self</span>.<span class="ident">is_parked</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">task</span>) <span class="op">=</span> <span class="self">self</span>.<span class="ident">task</span>.<span class="ident">take</span>() {
<span class="ident">task</span>.<span class="ident">wake</span>();
}
}
}
<span class="doccomment">/// Creates a bounded mpsc channel for communicating between asynchronous tasks.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Being bounded, this channel provides backpressure to ensure that the sender</span>
<span class="doccomment">/// outpaces the receiver by only a limited amount. The channel&#39;s capacity is</span>
<span class="doccomment">/// equal to `buffer + num-senders`. In other words, each sender gets a</span>
<span class="doccomment">/// guaranteed slot in the channel capacity, and on top of that there are</span>
<span class="doccomment">/// `buffer` &quot;first come, first serve&quot; slots available to all senders.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The [`Receiver`](Receiver) returned implements the</span>
<span class="doccomment">/// [`Stream`](futures_core::stream::Stream) trait, while [`Sender`](Sender) implements</span>
<span class="doccomment">/// `Sink`.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">channel</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>(<span class="ident">buffer</span>: <span class="ident">usize</span>) <span class="op">-</span><span class="op">&gt;</span> (<span class="ident">Sender</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>, <span class="ident">Receiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>) {
<span class="comment">// Check that the requested buffer size does not exceed the maximum buffer</span>
<span class="comment">// size permitted by the system.</span>
<span class="macro">assert</span><span class="macro">!</span>(<span class="ident">buffer</span> <span class="op">&lt;</span> <span class="ident">MAX_BUFFER</span>, <span class="string">&quot;requested buffer size too large&quot;</span>);
<span class="kw">let</span> <span class="ident">inner</span> <span class="op">=</span> <span class="ident">Arc</span>::<span class="ident">new</span>(<span class="ident">BoundedInner</span> {
<span class="ident">buffer</span>,
<span class="ident">state</span>: <span class="ident">AtomicUsize</span>::<span class="ident">new</span>(<span class="ident">INIT_STATE</span>),
<span class="ident">message_queue</span>: <span class="ident">Queue</span>::<span class="ident">new</span>(),
<span class="ident">parked_queue</span>: <span class="ident">Queue</span>::<span class="ident">new</span>(),
<span class="ident">num_senders</span>: <span class="ident">AtomicUsize</span>::<span class="ident">new</span>(<span class="number">1</span>),
<span class="ident">recv_task</span>: <span class="ident">AtomicWaker</span>::<span class="ident">new</span>(),
});
<span class="kw">let</span> <span class="ident">tx</span> <span class="op">=</span> <span class="ident">BoundedSenderInner</span> {
<span class="ident">inner</span>: <span class="ident">inner</span>.<span class="ident">clone</span>(),
<span class="ident">sender_task</span>: <span class="ident">Arc</span>::<span class="ident">new</span>(<span class="ident">Mutex</span>::<span class="ident">new</span>(<span class="ident">SenderTask</span>::<span class="ident">new</span>())),
<span class="ident">maybe_parked</span>: <span class="bool-val">false</span>,
};
<span class="kw">let</span> <span class="ident">rx</span> <span class="op">=</span> <span class="ident">Receiver</span> {
<span class="ident">inner</span>: <span class="prelude-val">Some</span>(<span class="ident">inner</span>),
};
(<span class="ident">Sender</span>(<span class="prelude-val">Some</span>(<span class="ident">tx</span>)), <span class="ident">rx</span>)
}
<span class="doccomment">/// Creates an unbounded mpsc channel for communicating between asynchronous</span>
<span class="doccomment">/// tasks.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// A `send` on this channel will always succeed as long as the receive half has</span>
<span class="doccomment">/// not been closed. If the receiver falls behind, messages will be arbitrarily</span>
<span class="doccomment">/// buffered.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// **Note** that the amount of available system memory is an implicit bound to</span>
<span class="doccomment">/// the channel. Using an `unbounded` channel has the ability of causing the</span>
<span class="doccomment">/// process to run out of memory. In this case, the process will be aborted.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">unbounded</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>() <span class="op">-</span><span class="op">&gt;</span> (<span class="ident">UnboundedSender</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>, <span class="ident">UnboundedReceiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>) {
<span class="kw">let</span> <span class="ident">inner</span> <span class="op">=</span> <span class="ident">Arc</span>::<span class="ident">new</span>(<span class="ident">UnboundedInner</span> {
<span class="ident">state</span>: <span class="ident">AtomicUsize</span>::<span class="ident">new</span>(<span class="ident">INIT_STATE</span>),
<span class="ident">message_queue</span>: <span class="ident">Queue</span>::<span class="ident">new</span>(),
<span class="ident">num_senders</span>: <span class="ident">AtomicUsize</span>::<span class="ident">new</span>(<span class="number">1</span>),
<span class="ident">recv_task</span>: <span class="ident">AtomicWaker</span>::<span class="ident">new</span>(),
});
<span class="kw">let</span> <span class="ident">tx</span> <span class="op">=</span> <span class="ident">UnboundedSenderInner</span> {
<span class="ident">inner</span>: <span class="ident">inner</span>.<span class="ident">clone</span>(),
};
<span class="kw">let</span> <span class="ident">rx</span> <span class="op">=</span> <span class="ident">UnboundedReceiver</span> {
<span class="ident">inner</span>: <span class="prelude-val">Some</span>(<span class="ident">inner</span>),
};
(<span class="ident">UnboundedSender</span>(<span class="prelude-val">Some</span>(<span class="ident">tx</span>)), <span class="ident">rx</span>)
}
<span class="comment">/*
*
* ===== impl Sender =====
*
*/</span>
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">UnboundedSenderInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">poll_ready_nb</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">SendError</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">state</span> <span class="op">=</span> <span class="ident">decode_state</span>(<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>));
<span class="kw">if</span> <span class="ident">state</span>.<span class="ident">is_open</span> {
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="prelude-val">Ok</span>(()))
} <span class="kw">else</span> {
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="prelude-val">Err</span>(<span class="ident">SendError</span> {
<span class="ident">kind</span>: <span class="ident">SendErrorKind</span>::<span class="ident">Disconnected</span>,
}))
}
}
<span class="comment">// Push message to the queue and signal to the receiver</span>
<span class="kw">fn</span> <span class="ident">queue_push_and_signal</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">msg</span>: <span class="ident">T</span>) {
<span class="comment">// Push the message onto the message queue</span>
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">message_queue</span>.<span class="ident">push</span>(<span class="ident">msg</span>);
<span class="comment">// Signal to the receiver that a message has been enqueued. If the</span>
<span class="comment">// receiver is parked, this will unpark the task.</span>
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">recv_task</span>.<span class="ident">wake</span>();
}
<span class="comment">// Increment the number of queued messages. Returns the resulting number.</span>
<span class="kw">fn</span> <span class="ident">inc_num_messages</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">usize</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">curr</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>);
<span class="kw">loop</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">state</span> <span class="op">=</span> <span class="ident">decode_state</span>(<span class="ident">curr</span>);
<span class="comment">// The receiver end closed the channel.</span>
<span class="kw">if</span> <span class="op">!</span><span class="ident">state</span>.<span class="ident">is_open</span> {
<span class="kw">return</span> <span class="prelude-val">None</span>;
}
<span class="comment">// This probably is never hit? Odds are the process will run out of</span>
<span class="comment">// memory first. It may be worth to return something else in this</span>
<span class="comment">// case?</span>
<span class="macro">assert</span><span class="macro">!</span>(<span class="ident">state</span>.<span class="ident">num_messages</span> <span class="op">&lt;</span> <span class="ident">MAX_CAPACITY</span>, <span class="string">&quot;buffer space \
exhausted; sending this messages would overflow the state&quot;</span>);
<span class="ident">state</span>.<span class="ident">num_messages</span> <span class="op">+</span><span class="op">=</span> <span class="number">1</span>;
<span class="kw">let</span> <span class="ident">next</span> <span class="op">=</span> <span class="ident">encode_state</span>(<span class="kw-2">&amp;</span><span class="ident">state</span>);
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">compare_exchange</span>(<span class="ident">curr</span>, <span class="ident">next</span>, <span class="ident">SeqCst</span>, <span class="ident">SeqCst</span>) {
<span class="prelude-val">Ok</span>(<span class="kw">_</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">return</span> <span class="prelude-val">Some</span>(<span class="ident">state</span>.<span class="ident">num_messages</span>)
}
<span class="prelude-val">Err</span>(<span class="ident">actual</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">curr</span> <span class="op">=</span> <span class="ident">actual</span>,
}
}
}
<span class="doccomment">/// Returns whether the senders send to the same receiver.</span>
<span class="kw">fn</span> <span class="ident">same_receiver</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">other</span>: <span class="kw-2">&amp;</span><span class="self">Self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="ident">Arc</span>::<span class="ident">ptr_eq</span>(<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">inner</span>, <span class="kw-2">&amp;</span><span class="ident">other</span>.<span class="ident">inner</span>)
}
<span class="doccomment">/// Returns whether the sender send to this receiver.</span>
<span class="kw">fn</span> <span class="ident">is_connected_to</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">inner</span>: <span class="kw-2">&amp;</span><span class="ident">Arc</span><span class="op">&lt;</span><span class="ident">UnboundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="ident">Arc</span>::<span class="ident">ptr_eq</span>(<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">inner</span>, <span class="ident">inner</span>)
}
<span class="doccomment">/// Returns pointer to the Arc containing sender</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The returned pointer is not referenced and should be only used for hashing!</span>
<span class="kw">fn</span> <span class="ident">ptr</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="kw-2">*</span><span class="kw">const</span> <span class="ident">UnboundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw-2">&amp;</span><span class="kw-2">*</span><span class="self">self</span>.<span class="ident">inner</span>
}
<span class="doccomment">/// Returns whether this channel is closed without needing a context.</span>
<span class="kw">fn</span> <span class="ident">is_closed</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="op">!</span><span class="ident">decode_state</span>(<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>)).<span class="ident">is_open</span>
}
<span class="doccomment">/// Closes this channel from the sender side, preventing any new messages.</span>
<span class="kw">fn</span> <span class="ident">close_channel</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) {
<span class="comment">// There&#39;s no need to park this sender, its dropping,</span>
<span class="comment">// and we don&#39;t want to check for capacity, so skip</span>
<span class="comment">// that stuff from `do_send`.</span>
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">set_closed</span>();
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">recv_task</span>.<span class="ident">wake</span>();
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">BoundedSenderInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="doccomment">/// Attempts to send a message on this `Sender`, returning the message</span>
<span class="doccomment">/// if there was an error.</span>
<span class="kw">fn</span> <span class="ident">try_send</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">msg</span>: <span class="ident">T</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">TrySendError</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="comment">// If the sender is currently blocked, reject the message</span>
<span class="kw">if</span> <span class="op">!</span><span class="self">self</span>.<span class="ident">poll_unparked</span>(<span class="prelude-val">None</span>).<span class="ident">is_ready</span>() {
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">TrySendError</span> {
<span class="ident">err</span>: <span class="ident">SendError</span> {
<span class="ident">kind</span>: <span class="ident">SendErrorKind</span>::<span class="ident">Full</span>,
},
<span class="ident">val</span>: <span class="ident">msg</span>,
});
}
<span class="comment">// The channel has capacity to accept the message, so send it</span>
<span class="self">self</span>.<span class="ident">do_send_b</span>(<span class="ident">msg</span>)
}
<span class="comment">// Do the send without failing.</span>
<span class="comment">// Can be called only by bounded sender.</span>
<span class="attribute">#[<span class="ident">allow</span>(<span class="ident">clippy</span>::<span class="ident">debug_assert_with_mut_call</span>)]</span>
<span class="kw">fn</span> <span class="ident">do_send_b</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">msg</span>: <span class="ident">T</span>)
<span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">TrySendError</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span>
{
<span class="comment">// Anyone callig do_send *should* make sure there is room first,</span>
<span class="comment">// but assert here for tests as a sanity check.</span>
<span class="macro">debug_assert</span><span class="macro">!</span>(<span class="self">self</span>.<span class="ident">poll_unparked</span>(<span class="prelude-val">None</span>).<span class="ident">is_ready</span>());
<span class="comment">// First, increment the number of messages contained by the channel.</span>
<span class="comment">// This operation will also atomically determine if the sender task</span>
<span class="comment">// should be parked.</span>
<span class="comment">//</span>
<span class="comment">// `None` is returned in the case that the channel has been closed by the</span>
<span class="comment">// receiver. This happens when `Receiver::close` is called or the</span>
<span class="comment">// receiver is dropped.</span>
<span class="kw">let</span> <span class="ident">park_self</span> <span class="op">=</span> <span class="kw">match</span> <span class="self">self</span>.<span class="ident">inc_num_messages</span>() {
<span class="prelude-val">Some</span>(<span class="ident">num_messages</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="comment">// Block if the current number of pending messages has exceeded</span>
<span class="comment">// the configured buffer size</span>
<span class="ident">num_messages</span> <span class="op">&gt;</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">buffer</span>
}
<span class="prelude-val">None</span> <span class="op">=</span><span class="op">&gt;</span> <span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">TrySendError</span> {
<span class="ident">err</span>: <span class="ident">SendError</span> {
<span class="ident">kind</span>: <span class="ident">SendErrorKind</span>::<span class="ident">Disconnected</span>,
},
<span class="ident">val</span>: <span class="ident">msg</span>,
}),
};
<span class="comment">// If the channel has reached capacity, then the sender task needs to</span>
<span class="comment">// be parked. This will send the task handle on the parked task queue.</span>
<span class="comment">//</span>
<span class="comment">// However, when `do_send` is called while dropping the `Sender`,</span>
<span class="comment">// `task::current()` can&#39;t be called safely. In this case, in order to</span>
<span class="comment">// maintain internal consistency, a blank message is pushed onto the</span>
<span class="comment">// parked task queue.</span>
<span class="kw">if</span> <span class="ident">park_self</span> {
<span class="self">self</span>.<span class="ident">park</span>();
}
<span class="self">self</span>.<span class="ident">queue_push_and_signal</span>(<span class="ident">msg</span>);
<span class="prelude-val">Ok</span>(())
}
<span class="comment">// Push message to the queue and signal to the receiver</span>
<span class="kw">fn</span> <span class="ident">queue_push_and_signal</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">msg</span>: <span class="ident">T</span>) {
<span class="comment">// Push the message onto the message queue</span>
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">message_queue</span>.<span class="ident">push</span>(<span class="ident">msg</span>);
<span class="comment">// Signal to the receiver that a message has been enqueued. If the</span>
<span class="comment">// receiver is parked, this will unpark the task.</span>
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">recv_task</span>.<span class="ident">wake</span>();
}
<span class="comment">// Increment the number of queued messages. Returns the resulting number.</span>
<span class="kw">fn</span> <span class="ident">inc_num_messages</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">usize</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">curr</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>);
<span class="kw">loop</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">state</span> <span class="op">=</span> <span class="ident">decode_state</span>(<span class="ident">curr</span>);
<span class="comment">// The receiver end closed the channel.</span>
<span class="kw">if</span> <span class="op">!</span><span class="ident">state</span>.<span class="ident">is_open</span> {
<span class="kw">return</span> <span class="prelude-val">None</span>;
}
<span class="comment">// This probably is never hit? Odds are the process will run out of</span>
<span class="comment">// memory first. It may be worth to return something else in this</span>
<span class="comment">// case?</span>
<span class="macro">assert</span><span class="macro">!</span>(<span class="ident">state</span>.<span class="ident">num_messages</span> <span class="op">&lt;</span> <span class="ident">MAX_CAPACITY</span>, <span class="string">&quot;buffer space \
exhausted; sending this messages would overflow the state&quot;</span>);
<span class="ident">state</span>.<span class="ident">num_messages</span> <span class="op">+</span><span class="op">=</span> <span class="number">1</span>;
<span class="kw">let</span> <span class="ident">next</span> <span class="op">=</span> <span class="ident">encode_state</span>(<span class="kw-2">&amp;</span><span class="ident">state</span>);
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">compare_exchange</span>(<span class="ident">curr</span>, <span class="ident">next</span>, <span class="ident">SeqCst</span>, <span class="ident">SeqCst</span>) {
<span class="prelude-val">Ok</span>(<span class="kw">_</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">return</span> <span class="prelude-val">Some</span>(<span class="ident">state</span>.<span class="ident">num_messages</span>)
}
<span class="prelude-val">Err</span>(<span class="ident">actual</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">curr</span> <span class="op">=</span> <span class="ident">actual</span>,
}
}
}
<span class="kw">fn</span> <span class="ident">park</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
{
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">sender</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">sender_task</span>.<span class="ident">lock</span>().<span class="ident">unwrap</span>();
<span class="ident">sender</span>.<span class="ident">task</span> <span class="op">=</span> <span class="prelude-val">None</span>;
<span class="ident">sender</span>.<span class="ident">is_parked</span> <span class="op">=</span> <span class="bool-val">true</span>;
}
<span class="comment">// Send handle over queue</span>
<span class="kw">let</span> <span class="ident">t</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">sender_task</span>.<span class="ident">clone</span>();
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">parked_queue</span>.<span class="ident">push</span>(<span class="ident">t</span>);
<span class="comment">// Check to make sure we weren&#39;t closed after we sent our task on the</span>
<span class="comment">// queue</span>
<span class="kw">let</span> <span class="ident">state</span> <span class="op">=</span> <span class="ident">decode_state</span>(<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>));
<span class="self">self</span>.<span class="ident">maybe_parked</span> <span class="op">=</span> <span class="ident">state</span>.<span class="ident">is_open</span>;
}
<span class="doccomment">/// Polls the channel to determine if there is guaranteed capacity to send</span>
<span class="doccomment">/// at least one item without waiting.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Return value</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This method returns:</span>
<span class="doccomment">///</span>
<span class="doccomment">/// - `Poll::Ready(Ok(_))` if there is sufficient capacity;</span>
<span class="doccomment">/// - `Poll::Pending` if the channel may not have</span>
<span class="doccomment">/// capacity, in which case the current task is queued to be notified once</span>
<span class="doccomment">/// capacity is available;</span>
<span class="doccomment">/// - `Poll::Ready(Err(SendError))` if the receiver has been dropped.</span>
<span class="kw">fn</span> <span class="ident">poll_ready</span>(
<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>,
<span class="ident">cx</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">Context</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">SendError</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">state</span> <span class="op">=</span> <span class="ident">decode_state</span>(<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>));
<span class="kw">if</span> <span class="op">!</span><span class="ident">state</span>.<span class="ident">is_open</span> {
<span class="kw">return</span> <span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="prelude-val">Err</span>(<span class="ident">SendError</span> {
<span class="ident">kind</span>: <span class="ident">SendErrorKind</span>::<span class="ident">Disconnected</span>,
}));
}
<span class="self">self</span>.<span class="ident">poll_unparked</span>(<span class="prelude-val">Some</span>(<span class="ident">cx</span>)).<span class="ident">map</span>(<span class="prelude-val">Ok</span>)
}
<span class="doccomment">/// Returns whether the senders send to the same receiver.</span>
<span class="kw">fn</span> <span class="ident">same_receiver</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">other</span>: <span class="kw-2">&amp;</span><span class="self">Self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="ident">Arc</span>::<span class="ident">ptr_eq</span>(<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">inner</span>, <span class="kw-2">&amp;</span><span class="ident">other</span>.<span class="ident">inner</span>)
}
<span class="doccomment">/// Returns whether the sender send to this receiver.</span>
<span class="kw">fn</span> <span class="ident">is_connected_to</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">receiver</span>: <span class="kw-2">&amp;</span><span class="ident">Arc</span><span class="op">&lt;</span><span class="ident">BoundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="ident">Arc</span>::<span class="ident">ptr_eq</span>(<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">inner</span>, <span class="ident">receiver</span>)
}
<span class="doccomment">/// Returns pointer to the Arc containing sender</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The returned pointer is not referenced and should be only used for hashing!</span>
<span class="kw">fn</span> <span class="ident">ptr</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="kw-2">*</span><span class="kw">const</span> <span class="ident">BoundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw-2">&amp;</span><span class="kw-2">*</span><span class="self">self</span>.<span class="ident">inner</span>
}
<span class="doccomment">/// Returns whether this channel is closed without needing a context.</span>
<span class="kw">fn</span> <span class="ident">is_closed</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="op">!</span><span class="ident">decode_state</span>(<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>)).<span class="ident">is_open</span>
}
<span class="doccomment">/// Closes this channel from the sender side, preventing any new messages.</span>
<span class="kw">fn</span> <span class="ident">close_channel</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) {
<span class="comment">// There&#39;s no need to park this sender, its dropping,</span>
<span class="comment">// and we don&#39;t want to check for capacity, so skip</span>
<span class="comment">// that stuff from `do_send`.</span>
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">set_closed</span>();
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">recv_task</span>.<span class="ident">wake</span>();
}
<span class="kw">fn</span> <span class="ident">poll_unparked</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">cx</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">Context</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span>()<span class="op">&gt;</span> {
<span class="comment">// First check the `maybe_parked` variable. This avoids acquiring the</span>
<span class="comment">// lock in most cases</span>
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">maybe_parked</span> {
<span class="comment">// Get a lock on the task handle</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">task</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">sender_task</span>.<span class="ident">lock</span>().<span class="ident">unwrap</span>();
<span class="kw">if</span> <span class="op">!</span><span class="ident">task</span>.<span class="ident">is_parked</span> {
<span class="self">self</span>.<span class="ident">maybe_parked</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="kw">return</span> <span class="ident">Poll</span>::<span class="ident">Ready</span>(())
}
<span class="comment">// At this point, an unpark request is pending, so there will be an</span>
<span class="comment">// unpark sometime in the future. We just need to make sure that</span>
<span class="comment">// the correct task will be notified.</span>
<span class="comment">//</span>
<span class="comment">// Update the task in case the `Sender` has been moved to another</span>
<span class="comment">// task</span>
<span class="ident">task</span>.<span class="ident">task</span> <span class="op">=</span> <span class="ident">cx</span>.<span class="ident">map</span>(<span class="op">|</span><span class="ident">cx</span><span class="op">|</span> <span class="ident">cx</span>.<span class="ident">waker</span>().<span class="ident">clone</span>());
<span class="ident">Poll</span>::<span class="ident">Pending</span>
} <span class="kw">else</span> {
<span class="ident">Poll</span>::<span class="ident">Ready</span>(())
}
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Sender</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="doccomment">/// Attempts to send a message on this `Sender`, returning the message</span>
<span class="doccomment">/// if there was an error.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">try_send</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">msg</span>: <span class="ident">T</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">TrySendError</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">inner</span>) <span class="op">=</span> <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>.<span class="number">0</span> {
<span class="ident">inner</span>.<span class="ident">try_send</span>(<span class="ident">msg</span>)
} <span class="kw">else</span> {
<span class="prelude-val">Err</span>(<span class="ident">TrySendError</span> {
<span class="ident">err</span>: <span class="ident">SendError</span> {
<span class="ident">kind</span>: <span class="ident">SendErrorKind</span>::<span class="ident">Disconnected</span>,
},
<span class="ident">val</span>: <span class="ident">msg</span>,
})
}
}
<span class="doccomment">/// Send a message on the channel.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This function should only be called after</span>
<span class="doccomment">/// [`poll_ready`](Sender::poll_ready) has reported that the channel is</span>
<span class="doccomment">/// ready to receive a message.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">start_send</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">msg</span>: <span class="ident">T</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">SendError</span><span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">try_send</span>(<span class="ident">msg</span>)
.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> <span class="ident">e</span>.<span class="ident">err</span>)
}
<span class="doccomment">/// Polls the channel to determine if there is guaranteed capacity to send</span>
<span class="doccomment">/// at least one item without waiting.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Return value</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This method returns:</span>
<span class="doccomment">///</span>
<span class="doccomment">/// - `Poll::Ready(Ok(_))` if there is sufficient capacity;</span>
<span class="doccomment">/// - `Poll::Pending` if the channel may not have</span>
<span class="doccomment">/// capacity, in which case the current task is queued to be notified once</span>
<span class="doccomment">/// capacity is available;</span>
<span class="doccomment">/// - `Poll::Ready(Err(SendError))` if the receiver has been dropped.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">poll_ready</span>(
<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>,
<span class="ident">cx</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">Context</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">SendError</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">inner</span> <span class="op">=</span> <span class="self">self</span>.<span class="number">0</span>.<span class="ident">as_mut</span>().<span class="ident">ok_or</span>(<span class="ident">SendError</span> {
<span class="ident">kind</span>: <span class="ident">SendErrorKind</span>::<span class="ident">Disconnected</span>,
})<span class="question-mark">?</span>;
<span class="ident">inner</span>.<span class="ident">poll_ready</span>(<span class="ident">cx</span>)
}
<span class="doccomment">/// Returns whether this channel is closed without needing a context.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">is_closed</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="self">self</span>.<span class="number">0</span>.<span class="ident">as_ref</span>().<span class="ident">map</span>(<span class="ident">BoundedSenderInner</span>::<span class="ident">is_closed</span>).<span class="ident">unwrap_or</span>(<span class="bool-val">true</span>)
}
<span class="doccomment">/// Closes this channel from the sender side, preventing any new messages.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">close_channel</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">inner</span>) <span class="op">=</span> <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>.<span class="number">0</span> {
<span class="ident">inner</span>.<span class="ident">close_channel</span>();
}
}
<span class="doccomment">/// Disconnects this sender from the channel, closing it if there are no more senders left.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">disconnect</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
<span class="self">self</span>.<span class="number">0</span> <span class="op">=</span> <span class="prelude-val">None</span>;
}
<span class="doccomment">/// Returns whether the senders send to the same receiver.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">same_receiver</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">other</span>: <span class="kw-2">&amp;</span><span class="self">Self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="kw">match</span> (<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span>, <span class="kw-2">&amp;</span><span class="ident">other</span>.<span class="number">0</span>) {
(<span class="prelude-val">Some</span>(<span class="ident">inner</span>), <span class="prelude-val">Some</span>(<span class="ident">other</span>)) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">inner</span>.<span class="ident">same_receiver</span>(<span class="ident">other</span>),
<span class="kw">_</span> <span class="op">=</span><span class="op">&gt;</span> <span class="bool-val">false</span>,
}
}
<span class="doccomment">/// Returns whether the sender send to this receiver.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">is_connected_to</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">receiver</span>: <span class="kw-2">&amp;</span><span class="ident">Receiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="kw">match</span> (<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span>, <span class="kw-2">&amp;</span><span class="ident">receiver</span>.<span class="ident">inner</span>) {
(<span class="prelude-val">Some</span>(<span class="ident">inner</span>), <span class="prelude-val">Some</span>(<span class="ident">receiver</span>)) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">inner</span>.<span class="ident">is_connected_to</span>(<span class="ident">receiver</span>),
<span class="kw">_</span> <span class="op">=</span><span class="op">&gt;</span> <span class="bool-val">false</span>,
}
}
<span class="doccomment">/// Hashes the receiver into the provided hasher</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">hash_receiver</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">hasher</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">H</span>) <span class="kw">where</span> <span class="ident">H</span>: <span class="ident">std</span>::<span class="ident">hash</span>::<span class="ident">Hasher</span> {
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">hash</span>::<span class="ident">Hash</span>;
<span class="kw">let</span> <span class="ident">ptr</span> <span class="op">=</span> <span class="self">self</span>.<span class="number">0</span>.<span class="ident">as_ref</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">inner</span><span class="op">|</span> <span class="ident">inner</span>.<span class="ident">ptr</span>());
<span class="ident">ptr</span>.<span class="ident">hash</span>(<span class="ident">hasher</span>);
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">UnboundedSender</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="doccomment">/// Check if the channel is ready to receive a message.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">poll_ready</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>,
<span class="kw">_</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">Context</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">SendError</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">inner</span> <span class="op">=</span> <span class="self">self</span>.<span class="number">0</span>.<span class="ident">as_ref</span>().<span class="ident">ok_or</span>(<span class="ident">SendError</span> {
<span class="ident">kind</span>: <span class="ident">SendErrorKind</span>::<span class="ident">Disconnected</span>,
})<span class="question-mark">?</span>;
<span class="ident">inner</span>.<span class="ident">poll_ready_nb</span>()
}
<span class="doccomment">/// Returns whether this channel is closed without needing a context.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">is_closed</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="self">self</span>.<span class="number">0</span>.<span class="ident">as_ref</span>().<span class="ident">map</span>(<span class="ident">UnboundedSenderInner</span>::<span class="ident">is_closed</span>).<span class="ident">unwrap_or</span>(<span class="bool-val">true</span>)
}
<span class="doccomment">/// Closes this channel from the sender side, preventing any new messages.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">close_channel</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">inner</span>) <span class="op">=</span> <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span> {
<span class="ident">inner</span>.<span class="ident">close_channel</span>();
}
}
<span class="doccomment">/// Disconnects this sender from the channel, closing it if there are no more senders left.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">disconnect</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
<span class="self">self</span>.<span class="number">0</span> <span class="op">=</span> <span class="prelude-val">None</span>;
}
<span class="comment">// Do the send without parking current task.</span>
<span class="kw">fn</span> <span class="ident">do_send_nb</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">msg</span>: <span class="ident">T</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">TrySendError</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">inner</span>) <span class="op">=</span> <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span> {
<span class="kw">if</span> <span class="ident">inner</span>.<span class="ident">inc_num_messages</span>().<span class="ident">is_some</span>() {
<span class="ident">inner</span>.<span class="ident">queue_push_and_signal</span>(<span class="ident">msg</span>);
<span class="kw">return</span> <span class="prelude-val">Ok</span>(());
}
}
<span class="prelude-val">Err</span>(<span class="ident">TrySendError</span> {
<span class="ident">err</span>: <span class="ident">SendError</span> {
<span class="ident">kind</span>: <span class="ident">SendErrorKind</span>::<span class="ident">Disconnected</span>,
},
<span class="ident">val</span>: <span class="ident">msg</span>,
})
}
<span class="doccomment">/// Send a message on the channel.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This method should only be called after `poll_ready` has been used to</span>
<span class="doccomment">/// verify that the channel is ready to receive a message.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">start_send</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">msg</span>: <span class="ident">T</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">SendError</span><span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">do_send_nb</span>(<span class="ident">msg</span>)
.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> <span class="ident">e</span>.<span class="ident">err</span>)
}
<span class="doccomment">/// Sends a message along this channel.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This is an unbounded sender, so this function differs from `Sink::send`</span>
<span class="doccomment">/// by ensuring the return type reflects that the channel is always ready to</span>
<span class="doccomment">/// receive messages.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">unbounded_send</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">msg</span>: <span class="ident">T</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">TrySendError</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">do_send_nb</span>(<span class="ident">msg</span>)
}
<span class="doccomment">/// Returns whether the senders send to the same receiver.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">same_receiver</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">other</span>: <span class="kw-2">&amp;</span><span class="self">Self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="kw">match</span> (<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span>, <span class="kw-2">&amp;</span><span class="ident">other</span>.<span class="number">0</span>) {
(<span class="prelude-val">Some</span>(<span class="ident">inner</span>), <span class="prelude-val">Some</span>(<span class="ident">other</span>)) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">inner</span>.<span class="ident">same_receiver</span>(<span class="ident">other</span>),
<span class="kw">_</span> <span class="op">=</span><span class="op">&gt;</span> <span class="bool-val">false</span>,
}
}
<span class="doccomment">/// Returns whether the sender send to this receiver.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">is_connected_to</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">receiver</span>: <span class="kw-2">&amp;</span><span class="ident">UnboundedReceiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="kw">match</span> (<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span>, <span class="kw-2">&amp;</span><span class="ident">receiver</span>.<span class="ident">inner</span>) {
(<span class="prelude-val">Some</span>(<span class="ident">inner</span>), <span class="prelude-val">Some</span>(<span class="ident">receiver</span>)) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">inner</span>.<span class="ident">is_connected_to</span>(<span class="ident">receiver</span>),
<span class="kw">_</span> <span class="op">=</span><span class="op">&gt;</span> <span class="bool-val">false</span>,
}
}
<span class="doccomment">/// Hashes the receiver into the provided hasher</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">hash_receiver</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">hasher</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">H</span>) <span class="kw">where</span> <span class="ident">H</span>: <span class="ident">std</span>::<span class="ident">hash</span>::<span class="ident">Hasher</span> {
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">hash</span>::<span class="ident">Hash</span>;
<span class="kw">let</span> <span class="ident">ptr</span> <span class="op">=</span> <span class="self">self</span>.<span class="number">0</span>.<span class="ident">as_ref</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">inner</span><span class="op">|</span> <span class="ident">inner</span>.<span class="ident">ptr</span>());
<span class="ident">ptr</span>.<span class="ident">hash</span>(<span class="ident">hasher</span>);
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Clone</span> <span class="kw">for</span> <span class="ident">Sender</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">clone</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">Self</span>(<span class="self">self</span>.<span class="number">0</span>.<span class="ident">clone</span>())
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Clone</span> <span class="kw">for</span> <span class="ident">UnboundedSender</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">clone</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">Self</span>(<span class="self">self</span>.<span class="number">0</span>.<span class="ident">clone</span>())
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Clone</span> <span class="kw">for</span> <span class="ident">UnboundedSenderInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">clone</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="comment">// Since this atomic op isn&#39;t actually guarding any memory and we don&#39;t</span>
<span class="comment">// care about any orderings besides the ordering on the single atomic</span>
<span class="comment">// variable, a relaxed ordering is acceptable.</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">curr</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">num_senders</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>);
<span class="kw">loop</span> {
<span class="comment">// If the maximum number of senders has been reached, then fail</span>
<span class="kw">if</span> <span class="ident">curr</span> <span class="op">=</span><span class="op">=</span> <span class="ident">MAX_BUFFER</span> {
<span class="macro">panic</span><span class="macro">!</span>(<span class="string">&quot;cannot clone `Sender` -- too many outstanding senders&quot;</span>);
}
<span class="macro">debug_assert</span><span class="macro">!</span>(<span class="ident">curr</span> <span class="op">&lt;</span> <span class="ident">MAX_BUFFER</span>);
<span class="kw">let</span> <span class="ident">next</span> <span class="op">=</span> <span class="ident">curr</span> <span class="op">+</span> <span class="number">1</span>;
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">num_senders</span>.<span class="ident">compare_exchange</span>(<span class="ident">curr</span>, <span class="ident">next</span>, <span class="ident">SeqCst</span>, <span class="ident">SeqCst</span>) {
<span class="prelude-val">Ok</span>(<span class="kw">_</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="comment">// The ABA problem doesn&#39;t matter here. We only care that the</span>
<span class="comment">// number of senders never exceeds the maximum.</span>
<span class="kw">return</span> <span class="self">Self</span> {
<span class="ident">inner</span>: <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">clone</span>(),
};
}
<span class="prelude-val">Err</span>(<span class="ident">actual</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">curr</span> <span class="op">=</span> <span class="ident">actual</span>,
}
}
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Clone</span> <span class="kw">for</span> <span class="ident">BoundedSenderInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">clone</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="comment">// Since this atomic op isn&#39;t actually guarding any memory and we don&#39;t</span>
<span class="comment">// care about any orderings besides the ordering on the single atomic</span>
<span class="comment">// variable, a relaxed ordering is acceptable.</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">curr</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">num_senders</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>);
<span class="kw">loop</span> {
<span class="comment">// If the maximum number of senders has been reached, then fail</span>
<span class="kw">if</span> <span class="ident">curr</span> <span class="op">=</span><span class="op">=</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">max_senders</span>() {
<span class="macro">panic</span><span class="macro">!</span>(<span class="string">&quot;cannot clone `Sender` -- too many outstanding senders&quot;</span>);
}
<span class="macro">debug_assert</span><span class="macro">!</span>(<span class="ident">curr</span> <span class="op">&lt;</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">max_senders</span>());
<span class="kw">let</span> <span class="ident">next</span> <span class="op">=</span> <span class="ident">curr</span> <span class="op">+</span> <span class="number">1</span>;
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">num_senders</span>.<span class="ident">compare_exchange</span>(<span class="ident">curr</span>, <span class="ident">next</span>, <span class="ident">SeqCst</span>, <span class="ident">SeqCst</span>) {
<span class="prelude-val">Ok</span>(<span class="kw">_</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="comment">// The ABA problem doesn&#39;t matter here. We only care that the</span>
<span class="comment">// number of senders never exceeds the maximum.</span>
<span class="kw">return</span> <span class="self">Self</span> {
<span class="ident">inner</span>: <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">clone</span>(),
<span class="ident">sender_task</span>: <span class="ident">Arc</span>::<span class="ident">new</span>(<span class="ident">Mutex</span>::<span class="ident">new</span>(<span class="ident">SenderTask</span>::<span class="ident">new</span>())),
<span class="ident">maybe_parked</span>: <span class="bool-val">false</span>,
};
}
<span class="prelude-val">Err</span>(<span class="ident">actual</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">curr</span> <span class="op">=</span> <span class="ident">actual</span>,
}
}
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Drop</span> <span class="kw">for</span> <span class="ident">UnboundedSenderInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">drop</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
<span class="comment">// Ordering between variables don&#39;t matter here</span>
<span class="kw">let</span> <span class="ident">prev</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">num_senders</span>.<span class="ident">fetch_sub</span>(<span class="number">1</span>, <span class="ident">SeqCst</span>);
<span class="kw">if</span> <span class="ident">prev</span> <span class="op">=</span><span class="op">=</span> <span class="number">1</span> {
<span class="self">self</span>.<span class="ident">close_channel</span>();
}
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Drop</span> <span class="kw">for</span> <span class="ident">BoundedSenderInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">drop</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
<span class="comment">// Ordering between variables don&#39;t matter here</span>
<span class="kw">let</span> <span class="ident">prev</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">num_senders</span>.<span class="ident">fetch_sub</span>(<span class="number">1</span>, <span class="ident">SeqCst</span>);
<span class="kw">if</span> <span class="ident">prev</span> <span class="op">=</span><span class="op">=</span> <span class="number">1</span> {
<span class="self">self</span>.<span class="ident">close_channel</span>();
}
}
}
<span class="comment">/*
*
* ===== impl Receiver =====
*
*/</span>
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Receiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="doccomment">/// Closes the receiving half of a channel, without dropping it.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This prevents any further messages from being sent on the channel while</span>
<span class="doccomment">/// still enabling the receiver to drain messages that are buffered.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">close</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">inner</span>) <span class="op">=</span> <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>.<span class="ident">inner</span> {
<span class="ident">inner</span>.<span class="ident">set_closed</span>();
<span class="comment">// Wake up any threads waiting as they&#39;ll see that we&#39;ve closed the</span>
<span class="comment">// channel and will continue on their merry way.</span>
<span class="kw">while</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">task</span>) <span class="op">=</span> <span class="kw">unsafe</span> { <span class="ident">inner</span>.<span class="ident">parked_queue</span>.<span class="ident">pop_spin</span>() } {
<span class="ident">task</span>.<span class="ident">lock</span>().<span class="ident">unwrap</span>().<span class="ident">notify</span>();
}
}
}
<span class="doccomment">/// Tries to receive the next message without notifying a context if empty.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// It is not recommended to call this function from inside of a future,</span>
<span class="doccomment">/// only when you&#39;ve otherwise arranged to be notified when the channel is</span>
<span class="doccomment">/// no longer empty.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This function will panic if called after `try_next` or `poll_next` has</span>
<span class="doccomment">/// returned `None`.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">try_next</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>, <span class="ident">TryRecvError</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">next_message</span>() {
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="ident">msg</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="prelude-val">Ok</span>(<span class="ident">msg</span>)
},
<span class="ident">Poll</span>::<span class="ident">Pending</span> <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">TryRecvError</span> { <span class="ident">_priv</span>: () }),
}
}
<span class="kw">fn</span> <span class="ident">next_message</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">inner</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">as_mut</span>().<span class="ident">expect</span>(<span class="string">&quot;Receiver::next_message called after `None`&quot;</span>);
<span class="comment">// Pop off a message</span>
<span class="kw">match</span> <span class="kw">unsafe</span> { <span class="ident">inner</span>.<span class="ident">message_queue</span>.<span class="ident">pop_spin</span>() } {
<span class="prelude-val">Some</span>(<span class="ident">msg</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="comment">// If there are any parked task handles in the parked queue,</span>
<span class="comment">// pop one and unpark it.</span>
<span class="self">self</span>.<span class="ident">unpark_one</span>();
<span class="comment">// Decrement number of messages</span>
<span class="self">self</span>.<span class="ident">dec_num_messages</span>();
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="prelude-val">Some</span>(<span class="ident">msg</span>))
}
<span class="prelude-val">None</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">state</span> <span class="op">=</span> <span class="ident">decode_state</span>(<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>));
<span class="kw">if</span> <span class="ident">state</span>.<span class="ident">is_closed</span>() {
<span class="comment">// If closed flag is set AND there are no pending messages</span>
<span class="comment">// it means end of stream</span>
<span class="self">self</span>.<span class="ident">inner</span> <span class="op">=</span> <span class="prelude-val">None</span>;
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="prelude-val">None</span>)
} <span class="kw">else</span> {
<span class="comment">// If queue is open, we need to return Pending</span>
<span class="comment">// to be woken up when new messages arrive.</span>
<span class="comment">// If queue is closed but num_messages is non-zero,</span>
<span class="comment">// it means that senders updated the state,</span>
<span class="comment">// but didn&#39;t put message to queue yet,</span>
<span class="comment">// so we need to park until sender unparks the task</span>
<span class="comment">// after queueing the message.</span>
<span class="ident">Poll</span>::<span class="ident">Pending</span>
}
}
}
}
<span class="comment">// Unpark a single task handle if there is one pending in the parked queue</span>
<span class="kw">fn</span> <span class="ident">unpark_one</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">inner</span>) <span class="op">=</span> <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>.<span class="ident">inner</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">task</span>) <span class="op">=</span> <span class="kw">unsafe</span> { <span class="ident">inner</span>.<span class="ident">parked_queue</span>.<span class="ident">pop_spin</span>() } {
<span class="ident">task</span>.<span class="ident">lock</span>().<span class="ident">unwrap</span>().<span class="ident">notify</span>();
}
}
}
<span class="kw">fn</span> <span class="ident">dec_num_messages</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">inner</span>) <span class="op">=</span> <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">inner</span> {
<span class="comment">// OPEN_MASK is highest bit, so it&#39;s unaffected by subtraction</span>
<span class="comment">// unless there&#39;s underflow, and we know there&#39;s no underflow</span>
<span class="comment">// because number of messages at this point is always &gt; 0.</span>
<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">fetch_sub</span>(<span class="number">1</span>, <span class="ident">SeqCst</span>);
}
}
}
<span class="comment">// The receiver does not ever take a Pin to the inner T</span>
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Unpin</span> <span class="kw">for</span> <span class="ident">Receiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">FusedStream</span> <span class="kw">for</span> <span class="ident">Receiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">is_terminated</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">is_none</span>()
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Stream</span> <span class="kw">for</span> <span class="ident">Receiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">type</span> <span class="ident">Item</span> <span class="op">=</span> <span class="ident">T</span>;
<span class="kw">fn</span> <span class="ident">poll_next</span>(
<span class="kw-2">mut</span> <span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>,
<span class="ident">cx</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">Context</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="comment">// Try to read a message off of the message queue.</span>
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">next_message</span>() {
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="ident">msg</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="ident">msg</span>.<span class="ident">is_none</span>() {
<span class="self">self</span>.<span class="ident">inner</span> <span class="op">=</span> <span class="prelude-val">None</span>;
}
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="ident">msg</span>)
},
<span class="ident">Poll</span>::<span class="ident">Pending</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="comment">// There are no messages to read, in this case, park.</span>
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">as_ref</span>().<span class="ident">unwrap</span>().<span class="ident">recv_task</span>.<span class="ident">register</span>(<span class="ident">cx</span>.<span class="ident">waker</span>());
<span class="comment">// Check queue again after parking to prevent race condition:</span>
<span class="comment">// a message could be added to the queue after previous `next_message`</span>
<span class="comment">// before `register` call.</span>
<span class="self">self</span>.<span class="ident">next_message</span>()
}
}
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Drop</span> <span class="kw">for</span> <span class="ident">Receiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">drop</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
<span class="comment">// Drain the channel of all pending messages</span>
<span class="self">self</span>.<span class="ident">close</span>();
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">is_some</span>() {
<span class="kw">loop</span> {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">next_message</span>() {
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="prelude-val">Some</span>(<span class="kw">_</span>)) <span class="op">=</span><span class="op">&gt;</span> {}
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="prelude-val">None</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="kw">break</span>,
<span class="ident">Poll</span>::<span class="ident">Pending</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">state</span> <span class="op">=</span> <span class="ident">decode_state</span>(<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">as_ref</span>().<span class="ident">unwrap</span>().<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>));
<span class="comment">// If the channel is closed, then there is no need to park.</span>
<span class="kw">if</span> <span class="ident">state</span>.<span class="ident">is_closed</span>() {
<span class="kw">break</span>;
}
<span class="comment">// TODO: Spinning isn&#39;t ideal, it might be worth</span>
<span class="comment">// investigating using a condvar or some other strategy</span>
<span class="comment">// here. That said, if this case is hit, then another thread</span>
<span class="comment">// is about to push the value into the queue and this isn&#39;t</span>
<span class="comment">// the only spinlock in the impl right now.</span>
<span class="ident">thread</span>::<span class="ident">yield_now</span>();
}
}
}
}
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">UnboundedReceiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="doccomment">/// Closes the receiving half of a channel, without dropping it.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This prevents any further messages from being sent on the channel while</span>
<span class="doccomment">/// still enabling the receiver to drain messages that are buffered.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">close</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">inner</span>) <span class="op">=</span> <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>.<span class="ident">inner</span> {
<span class="ident">inner</span>.<span class="ident">set_closed</span>();
}
}
<span class="doccomment">/// Tries to receive the next message without notifying a context if empty.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// It is not recommended to call this function from inside of a future,</span>
<span class="doccomment">/// only when you&#39;ve otherwise arranged to be notified when the channel is</span>
<span class="doccomment">/// no longer empty.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This function will panic if called after `try_next` or `poll_next` has</span>
<span class="doccomment">/// returned `None`.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">try_next</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>, <span class="ident">TryRecvError</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">next_message</span>() {
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="ident">msg</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="prelude-val">Ok</span>(<span class="ident">msg</span>)
},
<span class="ident">Poll</span>::<span class="ident">Pending</span> <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">TryRecvError</span> { <span class="ident">_priv</span>: () }),
}
}
<span class="kw">fn</span> <span class="ident">next_message</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">inner</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">as_mut</span>().<span class="ident">expect</span>(<span class="string">&quot;Receiver::next_message called after `None`&quot;</span>);
<span class="comment">// Pop off a message</span>
<span class="kw">match</span> <span class="kw">unsafe</span> { <span class="ident">inner</span>.<span class="ident">message_queue</span>.<span class="ident">pop_spin</span>() } {
<span class="prelude-val">Some</span>(<span class="ident">msg</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="comment">// Decrement number of messages</span>
<span class="self">self</span>.<span class="ident">dec_num_messages</span>();
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="prelude-val">Some</span>(<span class="ident">msg</span>))
}
<span class="prelude-val">None</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">state</span> <span class="op">=</span> <span class="ident">decode_state</span>(<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>));
<span class="kw">if</span> <span class="ident">state</span>.<span class="ident">is_closed</span>() {
<span class="comment">// If closed flag is set AND there are no pending messages</span>
<span class="comment">// it means end of stream</span>
<span class="self">self</span>.<span class="ident">inner</span> <span class="op">=</span> <span class="prelude-val">None</span>;
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="prelude-val">None</span>)
} <span class="kw">else</span> {
<span class="comment">// If queue is open, we need to return Pending</span>
<span class="comment">// to be woken up when new messages arrive.</span>
<span class="comment">// If queue is closed but num_messages is non-zero,</span>
<span class="comment">// it means that senders updated the state,</span>
<span class="comment">// but didn&#39;t put message to queue yet,</span>
<span class="comment">// so we need to park until sender unparks the task</span>
<span class="comment">// after queueing the message.</span>
<span class="ident">Poll</span>::<span class="ident">Pending</span>
}
}
}
}
<span class="kw">fn</span> <span class="ident">dec_num_messages</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">inner</span>) <span class="op">=</span> <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">inner</span> {
<span class="comment">// OPEN_MASK is highest bit, so it&#39;s unaffected by subtraction</span>
<span class="comment">// unless there&#39;s underflow, and we know there&#39;s no underflow</span>
<span class="comment">// because number of messages at this point is always &gt; 0.</span>
<span class="ident">inner</span>.<span class="ident">state</span>.<span class="ident">fetch_sub</span>(<span class="number">1</span>, <span class="ident">SeqCst</span>);
}
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">FusedStream</span> <span class="kw">for</span> <span class="ident">UnboundedReceiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">is_terminated</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">is_none</span>()
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Stream</span> <span class="kw">for</span> <span class="ident">UnboundedReceiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">type</span> <span class="ident">Item</span> <span class="op">=</span> <span class="ident">T</span>;
<span class="kw">fn</span> <span class="ident">poll_next</span>(
<span class="kw-2">mut</span> <span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">Self</span><span class="op">&gt;</span>,
<span class="ident">cx</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">Context</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="comment">// Try to read a message off of the message queue.</span>
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">next_message</span>() {
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="ident">msg</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="ident">msg</span>.<span class="ident">is_none</span>() {
<span class="self">self</span>.<span class="ident">inner</span> <span class="op">=</span> <span class="prelude-val">None</span>;
}
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="ident">msg</span>)
},
<span class="ident">Poll</span>::<span class="ident">Pending</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="comment">// There are no messages to read, in this case, park.</span>
<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">as_ref</span>().<span class="ident">unwrap</span>().<span class="ident">recv_task</span>.<span class="ident">register</span>(<span class="ident">cx</span>.<span class="ident">waker</span>());
<span class="comment">// Check queue again after parking to prevent race condition:</span>
<span class="comment">// a message could be added to the queue after previous `next_message`</span>
<span class="comment">// before `register` call.</span>
<span class="self">self</span>.<span class="ident">next_message</span>()
}
}
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Drop</span> <span class="kw">for</span> <span class="ident">UnboundedReceiver</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">drop</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
<span class="comment">// Drain the channel of all pending messages</span>
<span class="self">self</span>.<span class="ident">close</span>();
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">is_some</span>() {
<span class="kw">loop</span> {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">next_message</span>() {
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="prelude-val">Some</span>(<span class="kw">_</span>)) <span class="op">=</span><span class="op">&gt;</span> {}
<span class="ident">Poll</span>::<span class="ident">Ready</span>(<span class="prelude-val">None</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="kw">break</span>,
<span class="ident">Poll</span>::<span class="ident">Pending</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">state</span> <span class="op">=</span> <span class="ident">decode_state</span>(<span class="self">self</span>.<span class="ident">inner</span>.<span class="ident">as_ref</span>().<span class="ident">unwrap</span>().<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>));
<span class="comment">// If the channel is closed, then there is no need to park.</span>
<span class="kw">if</span> <span class="ident">state</span>.<span class="ident">is_closed</span>() {
<span class="kw">break</span>;
}
<span class="comment">// TODO: Spinning isn&#39;t ideal, it might be worth</span>
<span class="comment">// investigating using a condvar or some other strategy</span>
<span class="comment">// here. That said, if this case is hit, then another thread</span>
<span class="comment">// is about to push the value into the queue and this isn&#39;t</span>
<span class="comment">// the only spinlock in the impl right now.</span>
<span class="ident">thread</span>::<span class="ident">yield_now</span>();
}
}
}
}
}
}
<span class="comment">/*
*
* ===== impl Inner =====
*
*/</span>
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">UnboundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="comment">// Clear `open` flag in the state, keep `num_messages` intact.</span>
<span class="kw">fn</span> <span class="ident">set_closed</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) {
<span class="kw">let</span> <span class="ident">curr</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>);
<span class="kw">if</span> <span class="op">!</span><span class="ident">decode_state</span>(<span class="ident">curr</span>).<span class="ident">is_open</span> {
<span class="kw">return</span>;
}
<span class="self">self</span>.<span class="ident">state</span>.<span class="ident">fetch_and</span>(<span class="op">!</span><span class="ident">OPEN_MASK</span>, <span class="ident">SeqCst</span>);
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">BoundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="comment">// The return value is such that the total number of messages that can be</span>
<span class="comment">// enqueued into the channel will never exceed MAX_CAPACITY</span>
<span class="kw">fn</span> <span class="ident">max_senders</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">usize</span> {
<span class="ident">MAX_CAPACITY</span> <span class="op">-</span> <span class="self">self</span>.<span class="ident">buffer</span>
}
<span class="comment">// Clear `open` flag in the state, keep `num_messages` intact.</span>
<span class="kw">fn</span> <span class="ident">set_closed</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) {
<span class="kw">let</span> <span class="ident">curr</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">state</span>.<span class="ident">load</span>(<span class="ident">SeqCst</span>);
<span class="kw">if</span> <span class="op">!</span><span class="ident">decode_state</span>(<span class="ident">curr</span>).<span class="ident">is_open</span> {
<span class="kw">return</span>;
}
<span class="self">self</span>.<span class="ident">state</span>.<span class="ident">fetch_and</span>(<span class="op">!</span><span class="ident">OPEN_MASK</span>, <span class="ident">SeqCst</span>);
}
}
<span class="kw">unsafe</span> <span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Send</span><span class="op">&gt;</span> <span class="ident">Send</span> <span class="kw">for</span> <span class="ident">UnboundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {}
<span class="kw">unsafe</span> <span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Send</span><span class="op">&gt;</span> <span class="ident">Sync</span> <span class="kw">for</span> <span class="ident">UnboundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {}
<span class="kw">unsafe</span> <span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Send</span><span class="op">&gt;</span> <span class="ident">Send</span> <span class="kw">for</span> <span class="ident">BoundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {}
<span class="kw">unsafe</span> <span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Send</span><span class="op">&gt;</span> <span class="ident">Sync</span> <span class="kw">for</span> <span class="ident">BoundedInner</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {}
<span class="kw">impl</span> <span class="ident">State</span> {
<span class="kw">fn</span> <span class="ident">is_closed</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="op">!</span><span class="self">self</span>.<span class="ident">is_open</span> <span class="op">&amp;&amp;</span> <span class="self">self</span>.<span class="ident">num_messages</span> <span class="op">=</span><span class="op">=</span> <span class="number">0</span>
}
}
<span class="comment">/*
*
* ===== Helpers =====
*
*/</span>
<span class="kw">fn</span> <span class="ident">decode_state</span>(<span class="ident">num</span>: <span class="ident">usize</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">State</span> {
<span class="ident">State</span> {
<span class="ident">is_open</span>: <span class="ident">num</span> <span class="op">&amp;</span> <span class="ident">OPEN_MASK</span> <span class="op">=</span><span class="op">=</span> <span class="ident">OPEN_MASK</span>,
<span class="ident">num_messages</span>: <span class="ident">num</span> <span class="op">&amp;</span> <span class="ident">MAX_CAPACITY</span>,
}
}
<span class="kw">fn</span> <span class="ident">encode_state</span>(<span class="ident">state</span>: <span class="kw-2">&amp;</span><span class="ident">State</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">usize</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">num</span> <span class="op">=</span> <span class="ident">state</span>.<span class="ident">num_messages</span>;
<span class="kw">if</span> <span class="ident">state</span>.<span class="ident">is_open</span> {
<span class="ident">num</span> <span class="op">|</span><span class="op">=</span> <span class="ident">OPEN_MASK</span>;
}
<span class="ident">num</span>
}
</pre></div>
</section><section id="search" class="content hidden"></section><section class="footer"></section><div id="rustdoc-vars" data-root-path="../../../" data-current-crate="futures_channel"></div>
<script src="../../../main.js"></script><script src="../../../source-script.js"></script><script src="../../../source-files.js"></script><script defer src="../../../search-index.js"></script></body></html>