From b87db4d6cbcee96ad05114e699173f48d9a91c86 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 17 Aug 2022 14:19:05 +0100 Subject: [PATCH] bounded senders --- Cargo.lock | 354 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 + src/main.rs | 134 +++++++++----------- 3 files changed, 418 insertions(+), 72 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e816493..41ce6c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "darling" version = "0.14.1" @@ -94,10 +106,110 @@ name = "foo" version = "0.1.0" dependencies = [ "derive_builder", + "futures", "ron", "serde", "serde-value", "serde_json", + "tokio", +] + +[[package]] +name = "futures" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-executor" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" + +[[package]] +name = "futures-macro" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", ] [[package]] @@ -112,6 +224,49 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +[[package]] +name = "libc" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "lock_api" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mio" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + [[package]] name = "num-traits" version = "0.2.14" @@ -121,6 +276,22 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" + [[package]] name = "ordered-float" version = "2.10.0" @@ -130,6 +301,41 @@ dependencies = [ "num-traits", ] +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "proc-macro2" version = "1.0.37" @@ -148,6 +354,15 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +dependencies = [ + "bitflags", +] + [[package]] name = "ron" version = "0.7.0" @@ -165,6 +380,12 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "serde" version = "1.0.136" @@ -206,6 +427,37 @@ dependencies = [ "serde", ] +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" + +[[package]] +name = "smallvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" + +[[package]] +name = "socket2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "strsim" version = "0.10.0" @@ -223,8 +475,110 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tokio" +version = "1.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" +dependencies = [ + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "once_cell", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "unicode-xid" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" diff --git a/Cargo.toml b/Cargo.toml index 3b562af..0a62d73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,5 @@ serde = { version="1", features=["derive"] } ron = "*" serde_json = "*" derive_builder = { version = "0.11.2", git = "https://github.com/ijackson/rust-derive-builder", rev = "ba0c1a5311bd9f93ddf5f5b8ec2a5f6f03b22fbe" } +tokio = { version="1", features=["full"] } +futures = "0.3" diff --git a/src/main.rs b/src/main.rs index d5e0cbd..d9fd485 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,80 +5,70 @@ use std::mem; use std::mem::MaybeUninit; -type S = &'static str; +#[tokio::main] +async fn main(){ + let (mut tx, mut rx) = futures::channel::mpsc::channel(0); + let () = tx.try_send(0).unwrap(); + for i in 1..=3 { + let mut tx2 = tx.clone(); + let () = tx2.try_send(i).unwrap(); + assert!{ tx2.try_send(i+10).unwrap_err().is_full() } + assert!{ tx.try_send(i+20).unwrap_err().is_full() } + eprintln!("S {:?}", i); + } -#[repr(C)] -struct Concat( - [S; A], - [S; B], -); - -trait Ish { - const N: usize; -} - -trait Has { - const F: [S; N]; -} - -struct Inner { i: usize, } - -impl Ish for Inner { - const N: usize = 1; -} -impl Has<1> for Inner { - const F: [S; 1] = ["i"]; -} - -struct Outer { o: usize, p: usize } - -impl Ish for Outer { - const N: usize = Inner::N + 2; -} -impl Has<{ Inner::N + 2 }> for Outer { - const F: [S; Inner::N + 2] = { - const TUPLE: Concat< - 2, - { Inner::N }, - > = Concat( - ["o", "p"], - Inner::F, - ); - unsafe { mem::transmute(TUPLE) } + let m = loop { + let m = rx.try_next(); + let m = if let Ok(Some(m)) = m { m } else { break m }; + eprintln!("Y {:?}", m); }; + eprintln!("N {:?}", m); } -/* -const fn plus -(x: &'static [S], - b: &'static [S], - ary: &mut [MaybeUninit], -) - -> &'static [S] -{ -// unsafe { - -// } - panic!() -} - -struct Outer { o: usize, } -impl Ish for Outer { - const N: usize = Inner::N + 1; - const F: &'static [S] = { - static mut ARY: [MaybeUninit; Inner::N + 1] = [MaybeUninit::uninit(); Inner::N + 1]; - - plus::<{Inner::N + 1}>( - Inner::F, - &["o"], - &mut ARY[..], - ) - }; -} -*/ - -fn main(){ - eprintln!("IF {:?}", Inner::F); - eprintln!("OF {:?}", Outer::F); -} +14:58 <+Diziet> TIL that if you have a sender for a bounded + futures::channel::mpsc::channel, you can always cheat and + squeeze an extra message in: clone your sender (giving you a + free slot); try_send is guaranteed to succeed because you have + a reserved slot; then drop your cloned sender and now your + message lives on the heap somewhere +14:58 <+nickm> that's evil +14:58 <+nickm> let's not do it in arti? +14:59 <+Diziet> I have a use for it +14:59 <+nickm> not in arti I hope? +14:59 <+Diziet> We want to send channel padding negotiation cells +15:00 <+Diziet> We only want to wake up to send such a cell when the output is + writeable, so it wants to be in the inner select where we read + the input +15:00 <+Diziet> This trick lets us put the renegotiation message into the input + without adding *any* code to the hot path in the reactor +15:01 <+Diziet> The reactor code for handling the control message can do this + even though it doesn't know (and can't know) the output is + unblocked. +15:02 <+nickm> Hm. I still think this might be a bad idea, but I'm less + certain. One request: Please define a new wrapper for + mpsc::channel that explicitly has these semantics; maybe some + kind of "semibounded" channel? +15:02 <+Diziet> Well, the semantics we need don't actually include that the + message gets delivered. +15:02 <+nickm> Ah. Then that's okay. +15:02 <+Diziet> We can keep the cloned sender around until the *next* channel + renegotiation message. +15:02 <+nickm> try_send is correct if we don't care if it gets delivered +15:03 <+Diziet> We care that *this* message will get delivered *eventually*, + *unless* some other superseding message arises. +15:03 <+Diziet> So we need try_send to succeed but we don't care if dropping + the sender drops the message it was queueing +15:04 <+nickm> Hrrm. Then I think a wrapper might be right. Unless this is + docmented behavior? +15:04 <+Diziet> That every channel comes with a sending slot *is* documented +15:04 <+Diziet> That the sending slot is reserved *for that channel* is not + documented but is implied by the semantics of Sink +15:05 <+Diziet> What happens if you drop the sender after using the slot is + *not* documented but that is the part we don't care about (so + long as it's not some crazy malfunction or panic) +15:05 <+Diziet> So I think the right answer is to c&p my ad-hoc experiment into + a test case :-) +15:05 <+nickm> also add careful comments :) +15:05 <+Diziet> Absolutely! +15:05 <+nickm> eta: You may have thoughts on the above too -- 2.30.2