From fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:14:29 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- toolkit/components/kvstore/src/lib.rs | 44 ++++++++++++++++++++++++++++++---- toolkit/components/kvstore/src/task.rs | 26 ++++++++++++++------ 2 files changed, 59 insertions(+), 11 deletions(-) (limited to 'toolkit/components/kvstore/src') diff --git a/toolkit/components/kvstore/src/lib.rs b/toolkit/components/kvstore/src/lib.rs index 5601ecb12a..c110313ad2 100644 --- a/toolkit/components/kvstore/src/lib.rs +++ b/toolkit/components/kvstore/src/lib.rs @@ -29,7 +29,7 @@ use moz_task::{create_background_task_queue, DispatchOptions, TaskRunnable}; use nserror::{nsresult, NS_ERROR_FAILURE, NS_OK}; use nsstring::{nsACString, nsCString}; use owned_value::{owned_to_variant, variant_to_owned}; -use rkv::backend::{SafeModeDatabase, SafeModeEnvironment}; +use rkv::backend::{RecoveryStrategy, SafeModeDatabase, SafeModeEnvironment}; use rkv::OwnedValue; use std::{ ptr, @@ -37,14 +37,16 @@ use std::{ vec::IntoIter, }; use task::{ - ClearTask, DeleteTask, EnumerateTask, GetOrCreateTask, GetTask, HasTask, PutTask, WriteManyTask, + ClearTask, DeleteTask, EnumerateTask, GetOrCreateWithOptionsTask, GetTask, HasTask, PutTask, + WriteManyTask, }; use thin_vec::ThinVec; use xpcom::{ getter_addrefs, interfaces::{ nsIKeyValueDatabaseCallback, nsIKeyValueEnumeratorCallback, nsIKeyValuePair, - nsIKeyValueVariantCallback, nsIKeyValueVoidCallback, nsISerialEventTarget, nsIVariant, + nsIKeyValueService, nsIKeyValueVariantCallback, nsIKeyValueVoidCallback, + nsISerialEventTarget, nsIVariant, }, nsIID, xpcom, xpcom_method, RefPtr, }; @@ -109,15 +111,49 @@ impl KeyValueService { path: &nsACString, name: &nsACString, ) -> Result<(), nsresult> { - let task = Box::new(GetOrCreateTask::new( + let task = Box::new(GetOrCreateWithOptionsTask::new( RefPtr::new(callback), nsCString::from(path), nsCString::from(name), + RecoveryStrategy::Error, )); TaskRunnable::new("KVService::GetOrCreate", task)? .dispatch_background_task_with_options(DispatchOptions::default().may_block(true)) } + + xpcom_method!( + get_or_create_with_options => GetOrCreateWithOptions( + callback: *const nsIKeyValueDatabaseCallback, + path: *const nsACString, + name: *const nsACString, + strategy: u8 + ) + ); + + fn get_or_create_with_options( + &self, + callback: &nsIKeyValueDatabaseCallback, + path: &nsACString, + name: &nsACString, + xpidl_strategy: u8, + ) -> Result<(), nsresult> { + let strategy = match xpidl_strategy { + nsIKeyValueService::ERROR => RecoveryStrategy::Error, + nsIKeyValueService::DISCARD => RecoveryStrategy::Discard, + nsIKeyValueService::RENAME => RecoveryStrategy::Rename, + _ => return Err(NS_ERROR_FAILURE), + }; + let task = Box::new(GetOrCreateWithOptionsTask::new( + RefPtr::new(callback), + nsCString::from(path), + nsCString::from(name), + strategy, + )); + + TaskRunnable::new("KVService::GetOrCreateWithOptions", task)? + .dispatch_background_task_with_options(DispatchOptions::default().may_block(true)) + } } #[xpcom(implement(nsIKeyValueDatabase), atomic)] diff --git a/toolkit/components/kvstore/src/task.rs b/toolkit/components/kvstore/src/task.rs index 3608dc9665..2e0ba02e0b 100644 --- a/toolkit/components/kvstore/src/task.rs +++ b/toolkit/components/kvstore/src/task.rs @@ -10,7 +10,10 @@ use moz_task::Task; use nserror::{nsresult, NS_ERROR_FAILURE}; use nsstring::nsCString; use owned_value::owned_to_variant; -use rkv::backend::{BackendInfo, SafeMode, SafeModeDatabase, SafeModeEnvironment}; +use rkv::backend::{ + BackendEnvironmentBuilder, BackendInfo, RecoveryStrategy, SafeMode, SafeModeDatabase, + SafeModeEnvironment, +}; use rkv::{OwnedValue, StoreError, StoreOptions, Value}; use std::{ path::Path, @@ -161,23 +164,26 @@ fn passive_resize(env: &Rkv, wanted: usize) -> Result<(), StoreError> { Ok(()) } -pub struct GetOrCreateTask { +pub struct GetOrCreateWithOptionsTask { callback: AtomicCell>>, path: nsCString, name: nsCString, + strategy: RecoveryStrategy, result: AtomicCell>>, } -impl GetOrCreateTask { +impl GetOrCreateWithOptionsTask { pub fn new( callback: RefPtr, path: nsCString, name: nsCString, - ) -> GetOrCreateTask { - GetOrCreateTask { + strategy: RecoveryStrategy, + ) -> GetOrCreateWithOptionsTask { + GetOrCreateWithOptionsTask { callback: AtomicCell::new(Some(ThreadBoundRefPtr::new(callback))), path, name, + strategy, result: AtomicCell::default(), } } @@ -187,18 +193,24 @@ impl GetOrCreateTask { } } -impl Task for GetOrCreateTask { +impl Task for GetOrCreateWithOptionsTask { fn run(&self) { // We do the work within a closure that returns a Result so we can // use the ? operator to simplify the implementation. self.result .store(Some(|| -> Result { let store; + let mut builder = Rkv::environment_builder::(); + builder.set_corruption_recovery_strategy(self.strategy); let mut manager = Manager::singleton().write()?; // Note that path canonicalization is diabled to work around crashes on Fennec: // https://bugzilla.mozilla.org/show_bug.cgi?id=1531887 let path = Path::new(str::from_utf8(&self.path)?); - let rkv = manager.get_or_create(path, Rkv::new::)?; + let rkv = manager.get_or_create_from_builder( + path, + builder, + Rkv::from_builder::, + )?; { let env = rkv.read()?; let load_ratio = env.load_ratio()?.unwrap_or(0.0); -- cgit v1.2.3