mirror of
https://github.com/deltachat/deltachat-core.git
synced 2025-10-06 03:50:08 +02:00
simplify cancellation of ongoing processes
This commit is contained in:
parent
a2ffdfe004
commit
9f07e59a0d
3 changed files with 129 additions and 120 deletions
|
@ -241,7 +241,7 @@ int32_t mrmailbox_get_config_int (mrmailbox_t*, const char* key, int3
|
|||
char* mrmailbox_get_version_str (void);
|
||||
|
||||
int mrmailbox_configure_and_connect(mrmailbox_t*);
|
||||
void mrmailbox_configure_cancel (mrmailbox_t*);
|
||||
void mrmailbox_stop_ongoing_process(mrmailbox_t*);
|
||||
int mrmailbox_is_configured (mrmailbox_t*);
|
||||
|
||||
void mrmailbox_connect (mrmailbox_t*);
|
||||
|
@ -326,7 +326,6 @@ mrcontact_t* mrmailbox_get_contact (mrmailbox_t*, uint32_t contact_id);
|
|||
#define MR_BAK_PREFIX "delta-chat"
|
||||
#define MR_BAK_SUFFIX "bak"
|
||||
int mrmailbox_imex (mrmailbox_t*, int what, const char* param1, const char* param2);
|
||||
void mrmailbox_imex_cancel (mrmailbox_t*);
|
||||
char* mrmailbox_imex_has_backup (mrmailbox_t*, const char* dir);
|
||||
int mrmailbox_check_password (mrmailbox_t*, const char* pw);
|
||||
char* mrmailbox_initiate_key_transfer(mrmailbox_t*);
|
||||
|
@ -352,6 +351,8 @@ int mrmailbox_get_thread_index (void);
|
|||
int mrchat_set_draft (mrchat_t*, const char* msg); /* deprecated - use mrmailbox_set_draft() instead */
|
||||
#define mrpoortext_t mrlot_t
|
||||
#define mrpoortext_unref mrlot_unref
|
||||
#define mrmailbox_imex_cancel mrmailbox_stop_ongoing_process
|
||||
#define mrmailbox_configure_cancel mrmailbox_stop_ongoing_process
|
||||
|
||||
|
||||
/* library-internal */
|
||||
|
@ -418,6 +419,11 @@ int mrmailbox_ensure_secret_key_exists (mrmailbox_t*); /* makes sure
|
|||
char* mrmailbox_create_setup_code (mrmailbox_t*);
|
||||
int mrmailbox_render_setup_file (mrmailbox_t* mailbox, const char* passphrase, char** ret_msg);
|
||||
|
||||
extern int mr_shall_stop_ongoing;
|
||||
int mrmailbox_alloc_ongoing (mrmailbox_t*);
|
||||
void mrmailbox_free_ongoing (mrmailbox_t*);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* /extern "C" */
|
||||
#endif
|
||||
|
|
|
@ -358,10 +358,6 @@ cleanup:
|
|||
******************************************************************************/
|
||||
|
||||
|
||||
static int s_configure_running = 0;
|
||||
static int s_configure_do_exit = 1; /* the value 1 avoids mrmailbox_configure_cancel() from stopping already stopped threads */
|
||||
|
||||
|
||||
/**
|
||||
* Configure and connect a mailbox.
|
||||
*
|
||||
|
@ -369,7 +365,7 @@ static int s_configure_do_exit = 1; /* the value 1 avoids mrmailbox_config
|
|||
* using mrmailbox_set_config().
|
||||
*
|
||||
* - mrmailbox_configure_and_connect() may take a while, so it might be a good idea to let it run in a non-GUI-thread;
|
||||
* to cancel the configuration progress, you can then use mrmailbox_configure_cancel().
|
||||
* to stop the configuration progress, you can use mrmailbox_stop_ongoing_process().
|
||||
*
|
||||
* - The function sends out a number of #MR_EVENT_CONFIGURE_PROGRESS events that may be used to create
|
||||
* a progress bar or stuff like that.
|
||||
|
@ -399,33 +395,28 @@ int mrmailbox_configure_and_connect(mrmailbox_t* mailbox)
|
|||
int success = 0, locked = 0, i;
|
||||
int imap_connected_here = 0;
|
||||
|
||||
mrloginparam_t* param = mrloginparam_new();
|
||||
mrloginparam_t* param = NULL;
|
||||
char* param_domain = NULL; /* just a pointer inside param, must not be freed! */
|
||||
char* param_addr_urlencoded = NULL;
|
||||
mrloginparam_t* param_autoconfig = NULL;
|
||||
|
||||
#define PROGRESS(p) \
|
||||
if( s_configure_do_exit ) { goto cleanup; } \
|
||||
mailbox->m_cb(mailbox, MR_EVENT_CONFIGURE_PROGRESS, (p), 0);
|
||||
|
||||
if( mailbox == NULL ) {
|
||||
goto cleanup;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !mrmailbox_alloc_ongoing(mailbox) ) {
|
||||
return 0; /* no cleanup as this would call mrmailbox_free_ongoing() */
|
||||
}
|
||||
|
||||
#define PROGRESS(p) \
|
||||
if( mr_shall_stop_ongoing ) { goto cleanup; } \
|
||||
mailbox->m_cb(mailbox, MR_EVENT_CONFIGURE_PROGRESS, (p), 0);
|
||||
|
||||
if( !mrsqlite3_is_open(mailbox->m_sql) ) {
|
||||
mrmailbox_log_error(mailbox, 0, "Cannot configure, database not opened.");
|
||||
s_configure_do_exit = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if( s_configure_running || s_configure_do_exit == 0 ) {
|
||||
mrmailbox_log_error(mailbox, 0, "Already configuring.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
s_configure_running = 1;
|
||||
s_configure_do_exit = 0;
|
||||
|
||||
/* disconnect */
|
||||
mrmailbox_disconnect(mailbox);
|
||||
|
||||
|
@ -454,6 +445,8 @@ int mrmailbox_configure_and_connect(mrmailbox_t* mailbox)
|
|||
/* 1. Load the parameters and check email-address and password
|
||||
**************************************************************************/
|
||||
|
||||
param = mrloginparam_new();
|
||||
|
||||
mrsqlite3_lock(mailbox->m_sql);
|
||||
locked = 1;
|
||||
|
||||
|
@ -691,50 +684,11 @@ cleanup:
|
|||
mrloginparam_unref(param_autoconfig);
|
||||
free(param_addr_urlencoded);
|
||||
|
||||
s_configure_do_exit = 1; /* avoids mrmailbox_configure_cancel() to stop the thread */
|
||||
s_configure_running = 0;
|
||||
mrmailbox_free_ongoing(mailbox);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Signal the configure-process to stop.
|
||||
*
|
||||
* After that, mrmailbox_configure_cancel() returns _without_ waiting
|
||||
* for mrmailbox_configure_and_connect() to return.
|
||||
*
|
||||
* mrmailbox_configure_and_connect() will return ASAP then, however, it may
|
||||
* still take a moment. If in doubt, the caller may also decide the kill the
|
||||
* thread after a few seconds; eg. the configuration process may hang in a
|
||||
* function not under the control of the core (eg. #MR_EVENT_HTTP_GET). Another
|
||||
* reason for mrmailbox_configure_cancel() not to wait is that otherwise it
|
||||
* would be GUI-blocking and should be started in another thread then; this
|
||||
* would make things even more complicated.
|
||||
*
|
||||
* @memberof mrmailbox_t
|
||||
*
|
||||
* @param mailbox The mailbox object as created by mrmailbox_new()
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void mrmailbox_configure_cancel(mrmailbox_t* mailbox)
|
||||
{
|
||||
if( mailbox == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( s_configure_running && s_configure_do_exit==0 )
|
||||
{
|
||||
mrmailbox_log_info(mailbox, 0, "Signaling the configure-process to stop ASAP.");
|
||||
s_configure_do_exit = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mrmailbox_log_info(mailbox, 0, "No configure-process to stop.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the mailbox is already configured.
|
||||
*
|
||||
|
@ -769,3 +723,78 @@ int mrmailbox_is_configured(mrmailbox_t* mailbox)
|
|||
return is_configured? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Request an ongoing process to start.
|
||||
* Returns 0=process started, 1=not started, there is running another process
|
||||
*/
|
||||
static int s_ongoing_running = 0;
|
||||
int mr_shall_stop_ongoing = 1; /* the value 1 avoids mrmailbox_stop_ongoing_process() from stopping already stopped threads */
|
||||
int mrmailbox_alloc_ongoing(mrmailbox_t* mailbox)
|
||||
{
|
||||
if( mailbox == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( s_ongoing_running || mr_shall_stop_ongoing == 0 ) {
|
||||
mrmailbox_log_warning(mailbox, 0, "There is already another ongoing process running.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
s_ongoing_running = 1;
|
||||
mr_shall_stop_ongoing = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Frees the process allocated with mrmailbox_alloc_ongoing() - independingly of mr_shall_stop_ongoing.
|
||||
* If mrmailbox_alloc_ongoing() fails, this function MUST NOT be called.
|
||||
*/
|
||||
void mrmailbox_free_ongoing(mrmailbox_t* mailbox)
|
||||
{
|
||||
s_ongoing_running = 0;
|
||||
mr_shall_stop_ongoing = 1; /* avoids mrmailbox_stop_ongoing_process() to stop the thread */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Signal an ongoing process to stop.
|
||||
*
|
||||
* After that, mrmailbox_stop_ongoing_process() returns _without_ waiting
|
||||
* for the ongoing process to return.
|
||||
*
|
||||
* The ongoing process will return ASAP then, however, it may
|
||||
* still take a moment. If in doubt, the caller may also decide the kill the
|
||||
* thread after a few seconds; eg. the process may hang in a
|
||||
* function not under the control of the core (eg. #MR_EVENT_HTTP_GET). Another
|
||||
* reason for mrmailbox_stop_ongoing_process() not to wait is that otherwise it
|
||||
* would be GUI-blocking and should be started in another thread then; this
|
||||
* would make things even more complicated.
|
||||
*
|
||||
* Typical ongoing processes are started by mrmailbox_configure_and_connect(),
|
||||
* mrmailbox_initiate_key_transfer() or mrmailbox_imex(). As there is always at most only
|
||||
* one onging process at the same time, there is no need to define _which_ process to exit.
|
||||
*
|
||||
* @memberof mrmailbox_t
|
||||
*
|
||||
* @param mailbox The mailbox object.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void mrmailbox_stop_ongoing_process(mrmailbox_t* mailbox)
|
||||
{
|
||||
if( mailbox == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( s_ongoing_running && mr_shall_stop_ongoing==0 )
|
||||
{
|
||||
mrmailbox_log_info(mailbox, 0, "Signaling the ongoing process to stop ASAP.");
|
||||
mr_shall_stop_ongoing = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mrmailbox_log_info(mailbox, 0, "No ongoing process to stop.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,10 +35,6 @@
|
|||
#include "mrmimefactory.h"
|
||||
|
||||
|
||||
static int s_imex_running = 0;
|
||||
static int s_imex_do_exit = 1; /* the value 1 avoids mrmailbox_imex_cancel() from stopping already stopped threads */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Autocrypt Key Transfer
|
||||
******************************************************************************/
|
||||
|
@ -464,6 +460,10 @@ char* mrmailbox_create_setup_code(mrmailbox_t* mailbox)
|
|||
*
|
||||
* For more details about the Autocrypt setup process, please refer to
|
||||
* https://autocrypt.org/en/latest/level1.html#autocrypt-setup-message
|
||||
*
|
||||
* NB: If the user has never sent a message before, this function requires a key to be created.
|
||||
* In this case, the function may take some seconds to finish and it might be a good idea
|
||||
* to start it in a separate thread. If so, it can be interrupted using mrmailbox_stop_ongoing_process().
|
||||
*/
|
||||
char* mrmailbox_initiate_key_transfer(mrmailbox_t* mailbox)
|
||||
{
|
||||
|
@ -475,13 +475,25 @@ char* mrmailbox_initiate_key_transfer(mrmailbox_t* mailbox)
|
|||
char* self_addr = NULL;
|
||||
uint32_t contact_id = 0;
|
||||
uint32_t chat_id = 0;
|
||||
mrmsg_t* msg = mrmsg_new();
|
||||
mrmsg_t* msg = NULL;
|
||||
|
||||
if( (setup_code=mrmailbox_create_setup_code(mailbox)) == NULL
|
||||
|| !mrmailbox_render_setup_file(mailbox, setup_code, &setup_file_content) ) {
|
||||
if( !mrmailbox_alloc_ongoing(mailbox) ) {
|
||||
return 0; /* no cleanup as this would call mrmailbox_free_ongoing() */
|
||||
}
|
||||
#define CHECK_EXIT if( mr_shall_stop_ongoing ) { goto cleanup; }
|
||||
|
||||
if( (setup_code=mrmailbox_create_setup_code(mailbox)) == NULL ) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
CHECK_EXIT
|
||||
|
||||
if( !mrmailbox_render_setup_file(mailbox, setup_code, &setup_file_content) ) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
CHECK_EXIT
|
||||
|
||||
if( (setup_file_name=mr_get_fine_pathNfilename(mailbox->m_blobdir, "autocrypt-setup-message.html")) == NULL
|
||||
|| !mr_write_file(setup_file_name, setup_file_content, strlen(setup_file_content), mailbox) ) {
|
||||
goto cleanup;
|
||||
|
@ -497,10 +509,14 @@ char* mrmailbox_initiate_key_transfer(mrmailbox_t* mailbox)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
msg = mrmsg_new();
|
||||
msg->m_type = MR_MSG_FILE;
|
||||
mrparam_set (msg->m_param, MRP_FILE, setup_file_name);
|
||||
mrparam_set (msg->m_param, MRP_MIMETYPE, "application/autocrypt-setup");
|
||||
mrparam_set_int(msg->m_param, MRP_SYSTEM_CMD, MR_SYSTEM_AUTOCRYPT_SETUP_MESSAGE);
|
||||
|
||||
CHECK_EXIT
|
||||
|
||||
if( mrmailbox_send_msg_object(mailbox, chat_id, msg) == 0 ) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -514,6 +530,7 @@ cleanup:
|
|||
mrmsg_unref(msg);
|
||||
free(self_name);
|
||||
free(self_addr);
|
||||
mrmailbox_free_ongoing(mailbox);
|
||||
return setup_code;
|
||||
}
|
||||
|
||||
|
@ -817,7 +834,7 @@ static int export_backup(mrmailbox_t* mailbox, const char* dir)
|
|||
stmt = mrsqlite3_prepare_v2_(dest_sql, "INSERT INTO backup_blobs (file_name, file_content) VALUES (?, ?);");
|
||||
while( (dir_entry=readdir(dir_handle))!=NULL )
|
||||
{
|
||||
if( s_imex_do_exit ) {
|
||||
if( mr_shall_stop_ongoing ) {
|
||||
delete_dest_file = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -954,7 +971,7 @@ static int import_backup(mrmailbox_t* mailbox, const char* backup_to_import)
|
|||
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql, "SELECT file_name, file_content FROM backup_blobs ORDER BY id;");
|
||||
while( sqlite3_step(stmt) == SQLITE_ROW )
|
||||
{
|
||||
if( s_imex_do_exit ) {
|
||||
if( mr_shall_stop_ongoing ) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -1057,7 +1074,7 @@ cleanup:
|
|||
* - For each file written on export, the function sends #MR_EVENT_IMEX_FILE_WRITTEN
|
||||
*
|
||||
* Only one import-/export-progress can run at the same time.
|
||||
* To cancel an import-/export-progress, use mrmailbox_imex_cancel().
|
||||
* To cancel an import-/export-progress, use mrmailbox_stop_ongoing_process().
|
||||
*
|
||||
* @memberof mrmailbox_t
|
||||
*
|
||||
|
@ -1077,19 +1094,15 @@ int mrmailbox_imex(mrmailbox_t* mailbox, int what, const char* param1, const cha
|
|||
return 0;
|
||||
}
|
||||
|
||||
if( !mrmailbox_alloc_ongoing(mailbox) ) {
|
||||
return 0; /* no cleanup as this would call mrmailbox_free_ongoing() */
|
||||
}
|
||||
|
||||
if( param1 == NULL ) {
|
||||
mrmailbox_log_error(mailbox, 0, "No Import/export dir/file given.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( s_imex_running || s_imex_do_exit==0 ) {
|
||||
mrmailbox_log_warning(mailbox, 0, "Already importing/exporting.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
s_imex_running = 1;
|
||||
s_imex_do_exit = 0;
|
||||
|
||||
mrmailbox_log_info(mailbox, 0, "Import/export process started.");
|
||||
mailbox->m_cb(mailbox, MR_EVENT_IMEX_PROGRESS, 0, 0);
|
||||
|
||||
|
@ -1143,50 +1156,11 @@ int mrmailbox_imex(mrmailbox_t* mailbox, int what, const char* param1, const cha
|
|||
|
||||
cleanup:
|
||||
mrmailbox_log_info(mailbox, 0, "Import/export process ended.");
|
||||
s_imex_do_exit = 1; /* avoids mrmailbox_imex_cancel() to stop the thread */
|
||||
s_imex_running = 0;
|
||||
mrmailbox_free_ongoing(mailbox);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Signal the import-/export-process to stop.
|
||||
*
|
||||
* After that, mrmailbox_imex_cancel() returns _without_ waiting
|
||||
* for mrmailbox_imex() to return.
|
||||
*
|
||||
* mrmailbox_imex() will return ASAP then, however, it may
|
||||
* still take a moment. If in doubt, the caller may also decide the kill the
|
||||
* thread after a few seconds; eg. the process may hang in a
|
||||
* function not under the control of the core (eg. #MR_EVENT_HTTP_GET). Another
|
||||
* reason for mrmailbox_imex_cancel() not to wait is that otherwise it
|
||||
* would be GUI-blocking and should be started in another thread then; this
|
||||
* would make things even more complicated.
|
||||
*
|
||||
* @memberof mrmailbox_t
|
||||
*
|
||||
* @param mailbox The mailbox object.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void mrmailbox_imex_cancel(mrmailbox_t* mailbox)
|
||||
{
|
||||
if( mailbox == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( s_imex_running && s_imex_do_exit==0 )
|
||||
{
|
||||
mrmailbox_log_info(mailbox, 0, "Signaling the import-/export-process to stop ASAP.");
|
||||
s_imex_do_exit = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mrmailbox_log_info(mailbox, 0, "No import-/export-process to stop.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if there is a backup file.
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue