refactor(ffi): remove one pointer indirection for dc_accounts_t

Arc can be converted directly to raw pointers,
so there is no need to create a pointer to Arc
using a Box.
This commit is contained in:
link2xt
2025-12-31 15:04:35 +00:00
committed by l
parent 516f0a1a98
commit 0d2f2b3266

View File

@@ -15,7 +15,6 @@ use std::collections::BTreeMap;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fmt::Write; use std::fmt::Write;
use std::future::Future; use std::future::Future;
use std::ops::Deref;
use std::ptr; use std::ptr;
use std::str::FromStr; use std::str::FromStr;
use std::sync::{Arc, LazyLock}; use std::sync::{Arc, LazyLock};
@@ -4739,33 +4738,13 @@ pub unsafe extern "C" fn dc_provider_unref(provider: *mut dc_provider_t) {
/// Reader-writer lock wrapper for accounts manager to guarantee thread safety when using /// Reader-writer lock wrapper for accounts manager to guarantee thread safety when using
/// `dc_accounts_t` in multiple threads at once. /// `dc_accounts_t` in multiple threads at once.
pub struct AccountsWrapper { pub type dc_accounts_t = RwLock<Accounts>;
inner: Arc<RwLock<Accounts>>,
}
impl Deref for AccountsWrapper {
type Target = Arc<RwLock<Accounts>>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl AccountsWrapper {
fn new(accounts: Accounts) -> Self {
let inner = Arc::new(RwLock::new(accounts));
Self { inner }
}
}
/// Struct representing a list of deltachat accounts.
pub type dc_accounts_t = AccountsWrapper;
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_new( pub unsafe extern "C" fn dc_accounts_new(
dir: *const libc::c_char, dir: *const libc::c_char,
writable: libc::c_int, writable: libc::c_int,
) -> *mut dc_accounts_t { ) -> *const dc_accounts_t {
setup_panic!(); setup_panic!();
if dir.is_null() { if dir.is_null() {
@@ -4776,7 +4755,7 @@ pub unsafe extern "C" fn dc_accounts_new(
let accs = block_on(Accounts::new(as_path(dir).into(), writable != 0)); let accs = block_on(Accounts::new(as_path(dir).into(), writable != 0));
match accs { match accs {
Ok(accs) => Box::into_raw(Box::new(AccountsWrapper::new(accs))), Ok(accs) => Arc::into_raw(Arc::new(RwLock::new(accs))),
Err(err) => { Err(err) => {
// We are using Anyhow's .context() and to show the inner error, too, we need the {:#}: // We are using Anyhow's .context() and to show the inner error, too, we need the {:#}:
eprintln!("failed to create accounts: {err:#}"); eprintln!("failed to create accounts: {err:#}");
@@ -4789,17 +4768,17 @@ pub unsafe extern "C" fn dc_accounts_new(
/// ///
/// This function releases the memory of the `dc_accounts_t` structure. /// This function releases the memory of the `dc_accounts_t` structure.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_unref(accounts: *mut dc_accounts_t) { pub unsafe extern "C" fn dc_accounts_unref(accounts: *const dc_accounts_t) {
if accounts.is_null() { if accounts.is_null() {
eprintln!("ignoring careless call to dc_accounts_unref()"); eprintln!("ignoring careless call to dc_accounts_unref()");
return; return;
} }
let _ = Box::from_raw(accounts); let _ = Arc::from_raw(accounts);
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_get_account( pub unsafe extern "C" fn dc_accounts_get_account(
accounts: *mut dc_accounts_t, accounts: *const dc_accounts_t,
id: u32, id: u32,
) -> *mut dc_context_t { ) -> *mut dc_context_t {
if accounts.is_null() { if accounts.is_null() {
@@ -4816,7 +4795,7 @@ pub unsafe extern "C" fn dc_accounts_get_account(
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_get_selected_account( pub unsafe extern "C" fn dc_accounts_get_selected_account(
accounts: *mut dc_accounts_t, accounts: *const dc_accounts_t,
) -> *mut dc_context_t { ) -> *mut dc_context_t {
if accounts.is_null() { if accounts.is_null() {
eprintln!("ignoring careless call to dc_accounts_get_selected_account()"); eprintln!("ignoring careless call to dc_accounts_get_selected_account()");
@@ -4832,7 +4811,7 @@ pub unsafe extern "C" fn dc_accounts_get_selected_account(
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_select_account( pub unsafe extern "C" fn dc_accounts_select_account(
accounts: *mut dc_accounts_t, accounts: *const dc_accounts_t,
id: u32, id: u32,
) -> libc::c_int { ) -> libc::c_int {
if accounts.is_null() { if accounts.is_null() {
@@ -4856,13 +4835,13 @@ pub unsafe extern "C" fn dc_accounts_select_account(
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_add_account(accounts: *mut dc_accounts_t) -> u32 { pub unsafe extern "C" fn dc_accounts_add_account(accounts: *const dc_accounts_t) -> u32 {
if accounts.is_null() { if accounts.is_null() {
eprintln!("ignoring careless call to dc_accounts_add_account()"); eprintln!("ignoring careless call to dc_accounts_add_account()");
return 0; return 0;
} }
let accounts = &mut *accounts; let accounts = &*accounts;
block_on(async move { block_on(async move {
let mut accounts = accounts.write().await; let mut accounts = accounts.write().await;
@@ -4877,13 +4856,13 @@ pub unsafe extern "C" fn dc_accounts_add_account(accounts: *mut dc_accounts_t) -
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_add_closed_account(accounts: *mut dc_accounts_t) -> u32 { pub unsafe extern "C" fn dc_accounts_add_closed_account(accounts: *const dc_accounts_t) -> u32 {
if accounts.is_null() { if accounts.is_null() {
eprintln!("ignoring careless call to dc_accounts_add_closed_account()"); eprintln!("ignoring careless call to dc_accounts_add_closed_account()");
return 0; return 0;
} }
let accounts = &mut *accounts; let accounts = &*accounts;
block_on(async move { block_on(async move {
let mut accounts = accounts.write().await; let mut accounts = accounts.write().await;
@@ -4899,7 +4878,7 @@ pub unsafe extern "C" fn dc_accounts_add_closed_account(accounts: *mut dc_accoun
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_remove_account( pub unsafe extern "C" fn dc_accounts_remove_account(
accounts: *mut dc_accounts_t, accounts: *const dc_accounts_t,
id: u32, id: u32,
) -> libc::c_int { ) -> libc::c_int {
if accounts.is_null() { if accounts.is_null() {
@@ -4907,7 +4886,7 @@ pub unsafe extern "C" fn dc_accounts_remove_account(
return 0; return 0;
} }
let accounts = &mut *accounts; let accounts = &*accounts;
block_on(async move { block_on(async move {
let mut accounts = accounts.write().await; let mut accounts = accounts.write().await;
@@ -4925,7 +4904,7 @@ pub unsafe extern "C" fn dc_accounts_remove_account(
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_migrate_account( pub unsafe extern "C" fn dc_accounts_migrate_account(
accounts: *mut dc_accounts_t, accounts: *const dc_accounts_t,
dbfile: *const libc::c_char, dbfile: *const libc::c_char,
) -> u32 { ) -> u32 {
if accounts.is_null() || dbfile.is_null() { if accounts.is_null() || dbfile.is_null() {
@@ -4933,7 +4912,7 @@ pub unsafe extern "C" fn dc_accounts_migrate_account(
return 0; return 0;
} }
let accounts = &mut *accounts; let accounts = &*accounts;
let dbfile = to_string_lossy(dbfile); let dbfile = to_string_lossy(dbfile);
block_on(async move { block_on(async move {
@@ -4954,7 +4933,7 @@ pub unsafe extern "C" fn dc_accounts_migrate_account(
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_get_all(accounts: *mut dc_accounts_t) -> *mut dc_array_t { pub unsafe extern "C" fn dc_accounts_get_all(accounts: *const dc_accounts_t) -> *mut dc_array_t {
if accounts.is_null() { if accounts.is_null() {
eprintln!("ignoring careless call to dc_accounts_get_all()"); eprintln!("ignoring careless call to dc_accounts_get_all()");
return ptr::null_mut(); return ptr::null_mut();
@@ -4968,18 +4947,18 @@ pub unsafe extern "C" fn dc_accounts_get_all(accounts: *mut dc_accounts_t) -> *m
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_start_io(accounts: *mut dc_accounts_t) { pub unsafe extern "C" fn dc_accounts_start_io(accounts: *const dc_accounts_t) {
if accounts.is_null() { if accounts.is_null() {
eprintln!("ignoring careless call to dc_accounts_start_io()"); eprintln!("ignoring careless call to dc_accounts_start_io()");
return; return;
} }
let accounts = &mut *accounts; let accounts = &*accounts;
block_on(async move { accounts.write().await.start_io().await }); block_on(async move { accounts.write().await.start_io().await });
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_stop_io(accounts: *mut dc_accounts_t) { pub unsafe extern "C" fn dc_accounts_stop_io(accounts: *const dc_accounts_t) {
if accounts.is_null() { if accounts.is_null() {
eprintln!("ignoring careless call to dc_accounts_stop_io()"); eprintln!("ignoring careless call to dc_accounts_stop_io()");
return; return;
@@ -4990,7 +4969,7 @@ pub unsafe extern "C" fn dc_accounts_stop_io(accounts: *mut dc_accounts_t) {
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_maybe_network(accounts: *mut dc_accounts_t) { pub unsafe extern "C" fn dc_accounts_maybe_network(accounts: *const dc_accounts_t) {
if accounts.is_null() { if accounts.is_null() {
eprintln!("ignoring careless call to dc_accounts_maybe_network()"); eprintln!("ignoring careless call to dc_accounts_maybe_network()");
return; return;
@@ -5001,7 +4980,7 @@ pub unsafe extern "C" fn dc_accounts_maybe_network(accounts: *mut dc_accounts_t)
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_maybe_network_lost(accounts: *mut dc_accounts_t) { pub unsafe extern "C" fn dc_accounts_maybe_network_lost(accounts: *const dc_accounts_t) {
if accounts.is_null() { if accounts.is_null() {
eprintln!("ignoring careless call to dc_accounts_maybe_network_lost()"); eprintln!("ignoring careless call to dc_accounts_maybe_network_lost()");
return; return;
@@ -5013,7 +4992,7 @@ pub unsafe extern "C" fn dc_accounts_maybe_network_lost(accounts: *mut dc_accoun
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_background_fetch( pub unsafe extern "C" fn dc_accounts_background_fetch(
accounts: *mut dc_accounts_t, accounts: *const dc_accounts_t,
timeout_in_seconds: u64, timeout_in_seconds: u64,
) -> libc::c_int { ) -> libc::c_int {
if accounts.is_null() || timeout_in_seconds <= 2 { if accounts.is_null() || timeout_in_seconds <= 2 {
@@ -5032,7 +5011,7 @@ pub unsafe extern "C" fn dc_accounts_background_fetch(
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_stop_background_fetch(accounts: *mut dc_accounts_t) { pub unsafe extern "C" fn dc_accounts_stop_background_fetch(accounts: *const dc_accounts_t) {
if accounts.is_null() { if accounts.is_null() {
eprintln!("ignoring careless call to dc_accounts_stop_background_fetch()"); eprintln!("ignoring careless call to dc_accounts_stop_background_fetch()");
return; return;
@@ -5044,7 +5023,7 @@ pub unsafe extern "C" fn dc_accounts_stop_background_fetch(accounts: *mut dc_acc
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_set_push_device_token( pub unsafe extern "C" fn dc_accounts_set_push_device_token(
accounts: *mut dc_accounts_t, accounts: *const dc_accounts_t,
token: *const libc::c_char, token: *const libc::c_char,
) { ) {
if accounts.is_null() { if accounts.is_null() {
@@ -5067,7 +5046,7 @@ pub unsafe extern "C" fn dc_accounts_set_push_device_token(
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_accounts_get_event_emitter( pub unsafe extern "C" fn dc_accounts_get_event_emitter(
accounts: *mut dc_accounts_t, accounts: *const dc_accounts_t,
) -> *mut dc_event_emitter_t { ) -> *mut dc_event_emitter_t {
if accounts.is_null() { if accounts.is_null() {
eprintln!("ignoring careless call to dc_accounts_get_event_emitter()"); eprintln!("ignoring careless call to dc_accounts_get_event_emitter()");
@@ -5087,16 +5066,16 @@ pub struct dc_jsonrpc_instance_t {
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_jsonrpc_init( pub unsafe extern "C" fn dc_jsonrpc_init(
account_manager: *mut dc_accounts_t, account_manager: *const dc_accounts_t,
) -> *mut dc_jsonrpc_instance_t { ) -> *mut dc_jsonrpc_instance_t {
if account_manager.is_null() { if account_manager.is_null() {
eprintln!("ignoring careless call to dc_jsonrpc_init()"); eprintln!("ignoring careless call to dc_jsonrpc_init()");
return ptr::null_mut(); return ptr::null_mut();
} }
let account_manager = &*account_manager; let account_manager = Arc::from_raw(account_manager);
let cmd_api = block_on(deltachat_jsonrpc::api::CommandApi::from_arc( let cmd_api = block_on(deltachat_jsonrpc::api::CommandApi::from_arc(
account_manager.inner.clone(), account_manager.clone(),
)); ));
let (request_handle, receiver) = RpcClient::new(); let (request_handle, receiver) = RpcClient::new();