This is an automated email from the ASF dual-hosted git repository. mgrigorov pushed a commit to branch avro-3758-use-atomic-types-instead-of-static-mut in repository https://gitbox.apache.org/repos/asf/avro.git
commit c7bca82a7ac2086f77428858e12259ff07e89345 Author: Martin Tzvetanov Grigorov <[email protected]> AuthorDate: Thu May 11 10:10:27 2023 +0300 AVRO-3758: [Rust] Use AtomicXyz types instead of static mutable ones Use AtomicBool for apache_avro::util::SERDE_HUMAN_READABLE Signed-off-by: Martin Tzvetanov Grigorov <[email protected]> --- lang/rust/avro/src/de.rs | 20 ++++++++------------ lang/rust/avro/src/ser.rs | 9 +++------ lang/rust/avro/src/util.rs | 19 ++++++++----------- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/lang/rust/avro/src/de.rs b/lang/rust/avro/src/de.rs index 691faae27..c20aa5f4b 100644 --- a/lang/rust/avro/src/de.rs +++ b/lang/rust/avro/src/de.rs @@ -649,6 +649,7 @@ pub fn from_value<'de, D: Deserialize<'de>>(value: &'de Value) -> Result<D, Erro #[cfg(test)] mod tests { + use std::sync::atomic::Ordering; use pretty_assertions::assert_eq; use serde::Serialize; use uuid::Uuid; @@ -1227,32 +1228,27 @@ mod tests { #[test] fn avro_3747_human_readable_false() -> TestResult<()> { - // AVRO-3747: set serde's is_human_readable to false use serde::de::Deserializer as SerdeDeserializer; - unsafe { - crate::util::SERDE_HUMAN_READABLE = false; - } + let is_human_readable = false; + crate::util::SERDE_HUMAN_READABLE.store(is_human_readable, Ordering::Release); - let deser = Deserializer::new(&Value::Null); + let deser = &Deserializer::new(&Value::Null); - assert_eq!((&deser).is_human_readable(), false); + assert_eq!(deser.is_human_readable(), is_human_readable); Ok(()) } #[test] fn avro_3747_human_readable_true() -> TestResult<()> { - // AVRO-3747: set serde's is_human_readable to true use serde::de::Deserializer as SerdeDeserializer; - unsafe { - crate::util::SERDE_HUMAN_READABLE = true; - } + crate::util::SERDE_HUMAN_READABLE.store(true, Ordering::Release); - let deser = Deserializer::new(&Value::Null); + let deser = &Deserializer::new(&Value::Null); - assert!((&deser).is_human_readable()); + assert!(deser.is_human_readable()); Ok(()) } diff --git a/lang/rust/avro/src/ser.rs b/lang/rust/avro/src/ser.rs index 1c7718ba7..a5203e3be 100644 --- a/lang/rust/avro/src/ser.rs +++ b/lang/rust/avro/src/ser.rs @@ -488,6 +488,7 @@ pub fn to_value<S: Serialize>(value: S) -> Result<Value, Error> { #[cfg(test)] mod tests { + use std::sync::atomic::Ordering; use super::*; use pretty_assertions::assert_eq; use serde::{Deserialize, Serialize}; @@ -1007,9 +1008,7 @@ mod tests { fn avro_3747_human_readable_false() { use serde::ser::Serializer as SerdeSerializer; - unsafe { - crate::util::SERDE_HUMAN_READABLE = false; - } + crate::util::SERDE_HUMAN_READABLE.store(false, Ordering::Release); let ser = &mut Serializer {}; @@ -1020,9 +1019,7 @@ mod tests { fn avro_3747_human_readable_true() { use serde::ser::Serializer as SerdeSerializer; - unsafe { - crate::util::SERDE_HUMAN_READABLE = true; - } + crate::util::SERDE_HUMAN_READABLE.store(true, Ordering::Release); let ser = &mut Serializer {}; diff --git a/lang/rust/avro/src/util.rs b/lang/rust/avro/src/util.rs index 695a1a6c7..4dc115947 100644 --- a/lang/rust/avro/src/util.rs +++ b/lang/rust/avro/src/util.rs @@ -18,6 +18,7 @@ use crate::{schema::Documentation, AvroResult, Error}; use serde_json::{Map, Value}; use std::{convert::TryFrom, i64, io::Read, sync::Once}; +use std::sync::atomic::{AtomicBool, Ordering}; /// Maximum number of bytes that can be allocated when decoding /// Avro-encoded values. This is a protection against ill-formed @@ -30,9 +31,8 @@ static MAX_ALLOCATION_BYTES_ONCE: Once = Once::new(); /// Whether to set serialization & deserialization traits /// as `human_readable` or not. /// See [set_serde_human_readable] to change this value. -pub const DEFAULT_SERDE_HUMAN_READABLE: bool = true; -// crate visible for testing -pub(crate) static mut SERDE_HUMAN_READABLE: bool = DEFAULT_SERDE_HUMAN_READABLE; +// crate-visible for testing +pub(crate) static SERDE_HUMAN_READABLE: AtomicBool = AtomicBool::new(true); static SERDE_HUMAN_READABLE_ONCE: Once = Once::new(); pub trait MapHelper { @@ -169,17 +169,14 @@ pub fn safe_len(len: usize) -> AvroResult<usize> { /// library leverages [`std::sync::Once`](https://doc.rust-lang.org/std/sync/struct.Once.html) /// to set the limit either when calling this method, or when decoding for /// the first time. -pub fn set_serde_human_readable(human_readable: bool) -> bool { - unsafe { - SERDE_HUMAN_READABLE_ONCE.call_once(|| { - SERDE_HUMAN_READABLE = human_readable; - }); - SERDE_HUMAN_READABLE - } +pub fn set_serde_human_readable(human_readable: bool) { + SERDE_HUMAN_READABLE_ONCE.call_once(|| { + SERDE_HUMAN_READABLE.store(human_readable, Ordering::Release); + }); } pub(crate) fn is_human_readable() -> bool { - unsafe { SERDE_HUMAN_READABLE } + SERDE_HUMAN_READABLE.load(Ordering::Acquire) } #[cfg(test)]
