From 609bb29cef7596e299a1c7c506678c1f81f173c2 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 22 Jul 2021 14:54:26 +0200 Subject: [PATCH] signature: Impl thread-safe `Cell` (#329) Signed-off-by: PhilippGackstatter --- .../src/crypto/signature/signature.rs | 55 ++++++++++++++++++- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/identity-core/src/crypto/signature/signature.rs b/identity-core/src/crypto/signature/signature.rs index 3f3b230ff2..15b598b12e 100644 --- a/identity-core/src/crypto/signature/signature.rs +++ b/identity-core/src/crypto/signature/signature.rs @@ -1,7 +1,6 @@ // Copyright 2020-2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use core::cell::Cell; use core::fmt::Debug; use core::fmt::Formatter; use core::fmt::Result as FmtResult; @@ -9,6 +8,7 @@ use serde::__private::ser::FlatMapSerializer; use serde::ser::SerializeMap; use serde::ser::Serializer; use serde::Serialize; +use std::sync::atomic::{AtomicBool, Ordering}; use crate::crypto::SignatureValue; use crate::error::Result; @@ -23,7 +23,7 @@ pub struct Signature { #[serde(rename = "verificationMethod")] method: String, #[serde(default, skip_deserializing)] - hidden: Cell, + hidden: AtomicBoolCell, } impl Signature { @@ -33,7 +33,7 @@ impl Signature { type_: type_.into(), value: SignatureValue::None, method: method.into(), - hidden: Cell::new(false), + hidden: AtomicBoolCell(AtomicBool::new(false)), } } @@ -115,3 +115,52 @@ impl Serialize for Signature { state.end() } } + +/// Cell-style wrapper around an AtomicBool. +/// This is essentially a `Cell` but with `Sync` implemented. +pub(crate) struct AtomicBoolCell(AtomicBool); + +impl AtomicBoolCell { + pub(crate) fn set(&self, value: bool) { + self.0.store(value, Ordering::Relaxed); + } + + pub(crate) fn get(&self) -> bool { + self.0.load(Ordering::Relaxed) + } +} + +impl Clone for AtomicBoolCell { + fn clone(&self) -> Self { + Self(AtomicBool::new(self.0.load(Ordering::Relaxed))) + } +} + +impl PartialEq for AtomicBoolCell { + fn eq(&self, other: &Self) -> bool { + self.0.load(Ordering::Relaxed) == other.0.load(Ordering::Relaxed) + } +} + +impl Eq for AtomicBoolCell {} + +impl Default for AtomicBoolCell { + fn default() -> Self { + Self(AtomicBool::new(false)) + } +} + +impl PartialOrd for AtomicBoolCell { + fn partial_cmp(&self, other: &Self) -> Option { + self + .0 + .load(Ordering::Relaxed) + .partial_cmp(&other.0.load(Ordering::Relaxed)) + } +} + +impl Ord for AtomicBoolCell { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.load(Ordering::Relaxed).cmp(&other.0.load(Ordering::Relaxed)) + } +}