You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by mg...@apache.org on 2023/05/12 05:54:07 UTC
[avro] branch branch-1.11 updated: AVRO-3758: [Rust] use atomic types instead of static mut (#2225)
This is an automated email from the ASF dual-hosted git repository.
mgrigorov pushed a commit to branch branch-1.11
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/branch-1.11 by this push:
new 0674b690c AVRO-3758: [Rust] use atomic types instead of static mut (#2225)
0674b690c is described below
commit 0674b690c930b94dccf4fd939e794431d5ef3116
Author: Martin Grigorov <ma...@users.noreply.github.com>
AuthorDate: Fri May 12 08:52:53 2023 +0300
AVRO-3758: [Rust] use atomic types instead of static mut (#2225)
* 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 <mg...@apache.org>
* AVRO-3758: [Rust] Use AtomicXyz types instead of static mutable ones
Use AtomicUsize for apache_avro::util::MAX_ALLOCATION_BYTES
Signed-off-by: Martin Tzvetanov Grigorov <mg...@apache.org>
---------
Signed-off-by: Martin Tzvetanov Grigorov <mg...@apache.org>
(cherry picked from commit b86c63baeff4ef4a08c2559913d6e7c9d40d95b9)
---
lang/rust/avro/src/de.rs | 20 ++++++++------------
lang/rust/avro/src/ser.rs | 9 +++------
lang/rust/avro/src/util.rs | 40 +++++++++++++++++++++-------------------
3 files changed, 32 insertions(+), 37 deletions(-)
diff --git a/lang/rust/avro/src/de.rs b/lang/rust/avro/src/de.rs
index 691faae27..a1b52e6c5 100644
--- a/lang/rust/avro/src/de.rs
+++ b/lang/rust/avro/src/de.rs
@@ -651,6 +651,7 @@ pub fn from_value<'de, D: Deserialize<'de>>(value: &'de Value) -> Result<D, Erro
mod tests {
use pretty_assertions::assert_eq;
use serde::Serialize;
+ use std::sync::atomic::Ordering;
use uuid::Uuid;
use super::*;
@@ -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..2237c1d99 100644
--- a/lang/rust/avro/src/ser.rs
+++ b/lang/rust/avro/src/ser.rs
@@ -491,6 +491,7 @@ mod tests {
use super::*;
use pretty_assertions::assert_eq;
use serde::{Deserialize, Serialize};
+ use std::sync::atomic::Ordering;
#[derive(Debug, Deserialize, Serialize, Clone)]
struct Test {
@@ -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..d94acce7a 100644
--- a/lang/rust/avro/src/util.rs
+++ b/lang/rust/avro/src/util.rs
@@ -17,22 +17,29 @@
use crate::{schema::Documentation, AvroResult, Error};
use serde_json::{Map, Value};
-use std::{convert::TryFrom, i64, io::Read, sync::Once};
+use std::{
+ convert::TryFrom,
+ i64,
+ io::Read,
+ sync::{
+ atomic::{AtomicBool, AtomicUsize, Ordering},
+ Once,
+ },
+};
/// Maximum number of bytes that can be allocated when decoding
/// Avro-encoded values. This is a protection against ill-formed
/// data, whose length field might be interpreted as enormous.
/// See max_allocation_bytes to change this limit.
pub const DEFAULT_MAX_ALLOCATION_BYTES: usize = 512 * 1024 * 1024;
-static mut MAX_ALLOCATION_BYTES: usize = DEFAULT_MAX_ALLOCATION_BYTES;
+static MAX_ALLOCATION_BYTES: AtomicUsize = AtomicUsize::new(DEFAULT_MAX_ALLOCATION_BYTES);
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 {
@@ -140,12 +147,10 @@ fn decode_variable<R: Read>(reader: &mut R) -> AvroResult<u64> {
/// to set the limit either when calling this method, or when decoding for
/// the first time.
pub fn max_allocation_bytes(num_bytes: usize) -> usize {
- unsafe {
- MAX_ALLOCATION_BYTES_ONCE.call_once(|| {
- MAX_ALLOCATION_BYTES = num_bytes;
- });
- MAX_ALLOCATION_BYTES
- }
+ MAX_ALLOCATION_BYTES_ONCE.call_once(|| {
+ MAX_ALLOCATION_BYTES.store(num_bytes, Ordering::Release);
+ });
+ MAX_ALLOCATION_BYTES.load(Ordering::Acquire)
}
pub fn safe_len(len: usize) -> AvroResult<usize> {
@@ -169,17 +174,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)]