mirror of
https://github.com/chatmail/core.git
synced 2026-05-22 16:26:31 +03:00
feat!: Add lockfile to account manager (#4310)
Opening the same account (context) from multiple processes is dangerous, can result in duplicate downloads of the same message etc. Same for account manager, attempts to modify the same accounts.toml even if done atomically with may result in corrupted files as atomic replacement procedure does not expect that multiple processes may write to the same temporary file. accounts.toml cannot be used as a lockfile because it is replaced during atomic update. Therefore, a new file next to accounts.toml is needed to prevent starting second account manager in the same directory. But iOS needs to be able to open accounts from multiple processes at the same time. This is required as the "share-to-DC extension" is a separate process by iOS design -- this process may or may not be started while the main app is running. Accounts are not altered however by this extension, so let's add to the `Accounts::new()` constructor an `rdwr` parameter which allows to read the accounts config w/o locking the lockfile.
This commit is contained in:
@@ -2915,12 +2915,15 @@ int dc_receive_backup (dc_context_t* context, const char* qr);
|
||||
* @param dir The directory to create the context-databases in.
|
||||
* If the directory does not exist,
|
||||
* dc_accounts_new() will try to create it.
|
||||
* @param writable Whether the returned account manager is writable, i.e. calling these functions on
|
||||
* it is possible: dc_accounts_add_account(), dc_accounts_add_closed_account(),
|
||||
* dc_accounts_migrate_account(), dc_accounts_remove_account(), dc_accounts_select_account().
|
||||
* @return An account manager object.
|
||||
* The object must be passed to the other account manager functions
|
||||
* and must be freed using dc_accounts_unref() after usage.
|
||||
* On errors, NULL is returned.
|
||||
*/
|
||||
dc_accounts_t* dc_accounts_new (const char* os_name, const char* dir);
|
||||
dc_accounts_t* dc_accounts_new (const char* dir, int writable);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -4676,17 +4676,17 @@ pub type dc_accounts_t = AccountsWrapper;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_accounts_new(
|
||||
_os_name: *const libc::c_char,
|
||||
dbfile: *const libc::c_char,
|
||||
dir: *const libc::c_char,
|
||||
writable: libc::c_int,
|
||||
) -> *mut dc_accounts_t {
|
||||
setup_panic!();
|
||||
|
||||
if dbfile.is_null() {
|
||||
if dir.is_null() {
|
||||
eprintln!("ignoring careless call to dc_accounts_new()");
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
||||
let accs = block_on(Accounts::new(as_path(dbfile).into()));
|
||||
let accs = block_on(Accounts::new(as_path(dir).into(), writable != 0));
|
||||
|
||||
match accs {
|
||||
Ok(accs) => Box::into_raw(Box::new(AccountsWrapper::new(accs))),
|
||||
|
||||
Reference in New Issue
Block a user