From c8ef15f23f795b925b051a9899f819c849d06909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Flemstr=C3=B6m?= Date: Mon, 18 Nov 2019 22:23:07 +0100 Subject: [PATCH 1/5] Deserialize maps as maps The maps are already being serialized as maps, and serde_json will detect that despite us claiming that maps are seqs, it falls back to parsing them as maps; however, serde-json-core does not have that fallback logic, so it makes more sense to give the correct hint here (especially when this is merged: https://github.com/japaric/serde-json-core/pull/23) --- src/de.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/de.rs b/src/de.rs index 14b62146..e3d75824 100644 --- a/src/de.rs +++ b/src/de.rs @@ -182,7 +182,7 @@ where Ok(values) } } - deserializer.deserialize_seq(ValueVisitor(PhantomData)) + deserializer.deserialize_map(ValueVisitor(PhantomData)) } } @@ -225,7 +225,7 @@ where Ok(values) } } - deserializer.deserialize_seq(ValueVisitor(PhantomData)) + deserializer.deserialize_map(ValueVisitor(PhantomData)) } } From fedcf84cb49bb9372eb440c17c9a5b808f40e7a9 Mon Sep 17 00:00:00 2001 From: David Sawatzke Date: Fri, 29 Nov 2019 10:42:57 +0100 Subject: [PATCH 2/5] Fix improper handling of overflow in `len_usize` (fix #128) This will lead to implausibly large lengths, nearly endless iterators and possibly unsound behaviour through the Drop implementation Switches the `truncate` method to refer to the common defintion of simply chopping of the test bits. (Implemented by `as`, which is defined to do this). Adds a new `saturate` method to replace the previous `truncate` method --- src/sealed.rs | 31 +++++++++++++++++++++++-------- src/spsc/mod.rs | 18 ++++++++++++++++-- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/sealed.rs b/src/sealed.rs index 82292434..46147c50 100644 --- a/src/sealed.rs +++ b/src/sealed.rs @@ -21,6 +21,9 @@ unsafe impl XCore for MultiCore { } pub unsafe trait Uxx: Into + Send { + #[doc(hidden)] + fn saturate(x: usize) -> Self; + #[doc(hidden)] fn truncate(x: usize) -> Self; @@ -39,15 +42,19 @@ pub unsafe trait Uxx: Into + Send { } unsafe impl Uxx for u8 { - fn truncate(x: usize) -> Self { - let max = ::core::u8::MAX; + fn saturate(x: usize) -> Self { + let max = Self::max_value() as usize; if x >= usize::from(max) { - max + max as Self } else { - x as u8 + x as Self } } + fn truncate(x: usize) -> Self { + x as Self + } + unsafe fn load_acquire(x: *const Self) -> Self where C: XCore, @@ -79,15 +86,19 @@ unsafe impl Uxx for u8 { } unsafe impl Uxx for u16 { - fn truncate(x: usize) -> Self { - let max = ::core::u16::MAX; + fn saturate(x: usize) -> Self { + let max = Self::max_value() as usize; if x >= usize::from(max) { - max + max as Self } else { - x as u16 + x as Self } } + fn truncate(x: usize) -> Self { + x as Self + } + unsafe fn load_acquire(x: *const Self) -> Self where C: XCore, @@ -119,6 +130,10 @@ unsafe impl Uxx for u16 { } unsafe impl Uxx for usize { + fn saturate(x: usize) -> Self { + x + } + fn truncate(x: usize) -> Self { x } diff --git a/src/spsc/mod.rs b/src/spsc/mod.rs index 444d75ac..73c86838 100644 --- a/src/spsc/mod.rs +++ b/src/spsc/mod.rs @@ -174,7 +174,7 @@ where { /// Returns the maximum number of elements the queue can hold pub fn capacity(&self) -> U { - U::truncate(N::to_usize()) + U::saturate(N::to_usize()) } /// Returns `true` if the queue has a length of 0 @@ -205,7 +205,7 @@ where let head = self.0.head.load_relaxed().into(); let tail = self.0.tail.load_relaxed().into(); - tail.wrapping_sub(head) + U::truncate(tail.wrapping_sub(head)).into() } } @@ -693,6 +693,20 @@ mod tests { assert_eq!(items.next(), None); } + #[test] + fn iter_overflow() { + let mut rb: Queue = Queue::u8(); + + rb.enqueue(0).unwrap(); + for _ in 0..300 { + let mut items = rb.iter_mut(); + assert_eq!(items.next(), Some(&mut 0)); + assert_eq!(items.next(), None); + rb.dequeue().unwrap(); + rb.enqueue(0).unwrap(); + } + } + #[test] fn iter_mut() { let mut rb: Queue = Queue::new(); From 17180a1a55a9bd12dd3a4aa65790627517684700 Mon Sep 17 00:00:00 2001 From: Harry Sarson Date: Mon, 16 Dec 2019 11:43:26 +0000 Subject: [PATCH 3/5] remove unnecessary parentheses This commit handles a new rustc warning currently in nightly --- src/string.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/string.rs b/src/string.rs index 49d69f8c..2885fb0e 100644 --- a/src/string.rs +++ b/src/string.rs @@ -96,7 +96,7 @@ where /// assert!(String::from_utf8(v).is_err()); /// ``` #[inline] - pub fn from_utf8(vec: Vec) -> Result<(String), Utf8Error> { + pub fn from_utf8(vec: Vec) -> Result, Utf8Error> { // validate input str::from_utf8(&*vec)?; From baa5e620d46ec2ed0e59a4d62d16de9101c37971 Mon Sep 17 00:00:00 2001 From: konstantin Date: Fri, 4 Oct 2019 17:07:35 +0200 Subject: [PATCH 4/5] bugfix in mpmc.dequeue --- src/mpmc.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mpmc.rs b/src/mpmc.rs index 4faaae01..0dfa386f 100644 --- a/src/mpmc.rs +++ b/src/mpmc.rs @@ -494,7 +494,11 @@ unsafe fn dequeue(buffer: *mut Cell, dequeue_pos: &AtomicU8, mask: u8) -> } else if dif < 0 { return None; } else { - pos = dequeue_pos.load(Ordering::Relaxed); + if pos == 255 && dif == 255{ + return None; + } else { + pos = dequeue_pos.load(Ordering::Relaxed); + } } } From 90c90ec418eba399ca5120c86eeb131e73baf07f Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Tue, 17 Dec 2019 11:46:08 +0100 Subject: [PATCH 5/5] add test to PR #121 --- src/mpmc.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/mpmc.rs b/src/mpmc.rs index 0dfa386f..dcc950bd 100644 --- a/src/mpmc.rs +++ b/src/mpmc.rs @@ -564,4 +564,15 @@ mod tests { assert_eq!(q.dequeue(), Some(1)); assert_eq!(q.dequeue(), None); } + + #[test] + fn blocking(){ + let q = Q2::new(); + for _ in 0..255 { + q.enqueue(0).unwrap(); + q.dequeue(); + } + // this should not block forever + q.dequeue(); + } }