Make getting backup use the ongoing process

This commit is contained in:
Floris Bruynooghe
2023-02-14 12:19:40 +01:00
parent e1087b4145
commit ff0d675082
2 changed files with 27 additions and 8 deletions

View File

@@ -4159,7 +4159,7 @@ pub unsafe extern "C" fn dc_backup_provider_qr(
provider: *const dc_backup_provider_t,
) -> *mut libc::c_char {
let provider = &*provider;
deltachat::qr::format_backup(provider.qr())
deltachat::qr::format_backup(&provider.qr())
.unwrap_or_default()
.strdup()
}

View File

@@ -28,10 +28,6 @@ use std::sync::atomic::{AtomicU16, AtomicU64, Ordering};
use std::sync::Arc;
use std::task::Poll;
use crate::chat::delete_and_reset_all_device_msgs;
use crate::context::Context;
use crate::qr::Qr;
use crate::{e2ee, EventType};
use anyhow::{anyhow, bail, ensure, format_err, Context as _, Result};
use async_channel::Receiver;
use futures_lite::StreamExt;
@@ -46,6 +42,11 @@ use tokio::sync::broadcast::error::RecvError;
use tokio::task::JoinHandle;
use tokio_stream::wrappers::ReadDirStream;
use crate::chat::delete_and_reset_all_device_msgs;
use crate::context::Context;
use crate::qr::Qr;
use crate::{e2ee, EventType};
use super::{export_database, BlobDirContents, DeleteOnDrop, DBFILE_BACKUP_NAME};
/// Provide or send a backup of this device.
@@ -273,9 +274,10 @@ impl From<SendProgress> for EventType {
/// does avoid having [`sendme::provider::Ticket`] in the primary API however, without
/// having to revert to untyped bytes.
pub async fn get_backup(context: &Context, qr: Qr) -> Result<()> {
let Qr::Backup { ticket } = qr else {
bail!("QR code for backup must be of type DCBACKUP");
};
ensure!(
matches!(qr, Qr::Backup { .. }),
"QR code for backup must be of type DCBACKUP"
);
ensure!(
!context.is_configured().await?,
"Cannot import backups to accounts in use."
@@ -284,6 +286,23 @@ pub async fn get_backup(context: &Context, qr: Qr) -> Result<()> {
context.scheduler.read().await.is_none(),
"cannot import backup, IO is running"
);
// Acquire global "ongoing" mutex.
let cancel_token = context.alloc_ongoing().await?;
tokio::select! {
biased;
res = get_backup_inner(context, qr) => {
context.free_ongoing().await;
res
}
_ = cancel_token.recv() => Err(format_err!("cancelled")),
}
}
async fn get_backup_inner(context: &Context, qr: Qr) -> Result<()> {
let Qr::Backup { ticket } = qr else {
bail!("QR code for backup must be of type DCBACKUP");
};
let opts = Options {
addr: ticket.addr,
peer_id: Some(ticket.peer),