fix(imex): Clone provider in dc_backup_provider_wait()

This is a long running process and there has been at lease one crash
in this function.  By owning both the context and the provider when
waiting we can avoid them being deallocated while we are still using
them.

To make the BackupProvider clonable this transforms all the errors
from it into Strings.  These are clonable and how we report most our
errors anyway.  The Future impl of BackupProvider then turns this into
an anyhow::Error so all other code can keep using anyhow as usual.
This commit is contained in:
Floris Bruynooghe
2023-03-29 12:54:26 +02:00
parent fc25bba514
commit 6a34cb7ad8
2 changed files with 22 additions and 7 deletions

View File

@@ -4221,10 +4221,17 @@ pub unsafe extern "C" fn dc_backup_provider_wait(provider: *mut dc_backup_provid
let ffi_provider = &mut *provider;
let ctx = &*ffi_provider.context;
let provider = &mut ffi_provider.provider;
backup_provider_wait(ctx.clone(), provider.clone());
}
// Because this is a long-running operation make sure we own the Context and BackupProvider.
// This stops a FFI user from deallocating it by calling unref on the object while we are
// using it.
fn backup_provider_wait(context: Context, provider: BackupProvider) {
block_on(provider)
.log_err(ctx, "Failed to await BackupProvider")
.log_err(&context, "Failed to await BackupProvider")
.context("Failed to await BackupProvider")
.set_last_error(ctx)
.set_last_error(&context)
.ok();
}