mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 13:36:30 +03:00
fix: shutdown shortly after call
This commit is contained in:
11
src/calls.rs
11
src/calls.rs
@@ -6,7 +6,7 @@ use crate::chat::ChatIdBlocked;
|
||||
use crate::chat::{Chat, ChatId, send_msg};
|
||||
use crate::constants::{Blocked, Chattype};
|
||||
use crate::contact::ContactId;
|
||||
use crate::context::Context;
|
||||
use crate::context::{Context, WeakContext};
|
||||
use crate::events::EventType;
|
||||
use crate::headerdef::HeaderDef;
|
||||
use crate::log::warn;
|
||||
@@ -199,8 +199,9 @@ impl Context {
|
||||
call.id = send_msg(self, chat_id, &mut call).await?;
|
||||
|
||||
let wait = RINGING_SECONDS;
|
||||
let context = self.get_weak_context();
|
||||
task::spawn(Context::emit_end_call_if_unaccepted(
|
||||
self.clone(),
|
||||
context,
|
||||
wait.try_into()?,
|
||||
call.id,
|
||||
));
|
||||
@@ -291,11 +292,12 @@ impl Context {
|
||||
}
|
||||
|
||||
async fn emit_end_call_if_unaccepted(
|
||||
context: Context,
|
||||
context: WeakContext,
|
||||
wait: u64,
|
||||
call_id: MsgId,
|
||||
) -> Result<()> {
|
||||
sleep(Duration::from_secs(wait)).await;
|
||||
let context = context.upgrade()?;
|
||||
let Some(mut call) = context.load_call_by_id(call_id).await? else {
|
||||
warn!(
|
||||
context,
|
||||
@@ -368,8 +370,9 @@ impl Context {
|
||||
}
|
||||
}
|
||||
let wait = call.remaining_ring_seconds();
|
||||
let context = self.get_weak_context();
|
||||
task::spawn(Context::emit_end_call_if_unaccepted(
|
||||
self.clone(),
|
||||
context,
|
||||
wait.try_into()?,
|
||||
call.msg.id,
|
||||
));
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::ffi::OsString;
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::{Arc, OnceLock};
|
||||
use std::sync::{Arc, OnceLock, Weak};
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{Context as _, Result, bail, ensure};
|
||||
@@ -201,6 +201,25 @@ impl Deref for Context {
|
||||
}
|
||||
}
|
||||
|
||||
/// A weak reference to a [`Context`]
|
||||
///
|
||||
/// Can be used to obtain a [`Context`]. An existing weak reference does not prevent the corresponding [`Context`] from being dropped.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct WeakContext {
|
||||
inner: Weak<InnerContext>,
|
||||
}
|
||||
|
||||
impl WeakContext {
|
||||
/// Returns the [`Context`] if it is still available.
|
||||
pub(crate) fn upgrade(&self) -> Result<Context> {
|
||||
let inner = self
|
||||
.inner
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow::anyhow!("Inner struct has been dropped"))?;
|
||||
Ok(Context { inner })
|
||||
}
|
||||
}
|
||||
|
||||
/// Actual context, expensive to clone.
|
||||
#[derive(Debug)]
|
||||
pub struct InnerContext {
|
||||
@@ -385,6 +404,13 @@ impl Context {
|
||||
Ok(context)
|
||||
}
|
||||
|
||||
/// Returns a weak reference to this [`Context`].
|
||||
pub(crate) fn get_weak_context(&self) -> WeakContext {
|
||||
WeakContext {
|
||||
inner: Arc::downgrade(&self.inner),
|
||||
}
|
||||
}
|
||||
|
||||
/// Opens the database with the given passphrase.
|
||||
/// NB: Db encryption is deprecated, so `passphrase` should be empty normally. See
|
||||
/// [`ContextBuilder::with_password()`] for reasoning.
|
||||
|
||||
Reference in New Issue
Block a user