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)]

Reply via email to