1
0
Fork 0
mirror of https://github.com/deltachat/deltachat-core.git synced 2025-10-05 19:42:04 +02:00

Set thread state.

This commit is contained in:
B. Petersen 2016-07-18 11:54:00 +02:00
parent 2e3831fed4
commit 6d84df0880
3 changed files with 48 additions and 24 deletions

View file

@ -26,7 +26,7 @@
*******************************************************************************
*
* TODO: On Android, I think, the thread must be marked using
* AttachCurrentThread(), see MailCore2 code
* AttachCurrentThread(), see MailCore2 code and https://developer.android.com/training/articles/perf-jni.html
*
******************************************************************************/
@ -242,6 +242,8 @@ static void fetch_messages(MrImapThreadVal& threadval)
void MrImap::WorkingThread()
{
// connect to server
m_threadState = MR_THREAD_CONNECT;
MrImapThreadVal threadval;
int r;
@ -261,18 +263,24 @@ void MrImap::WorkingThread()
{
// wait for condition
pthread_mutex_lock(&m_condmutex);
m_threadState = MR_THREAD_WAIT;
pthread_cond_wait(&m_cond, &m_condmutex); // wait unlocks the mutex and waits for signal, if it returns, the mutex is locked again
int dowhat = m_dowhat;
MrImapThreadCmd cmd = m_threadCmd;
m_threadState = cmd; // make sure state or cmd blocks eg. Fetch()
m_threadCmd = MR_THREAD_WAIT;
pthread_mutex_unlock(&m_condmutex);
switch( dowhat )
switch( cmd )
{
case DO_FETCH:
case MR_THREAD_FETCH:
fetch_messages(threadval);
break;
case DO_EXIT:
case MR_THREAD_EXIT:
goto WorkingThread_Exit;
default:
break; // bad command
}
}
@ -283,7 +291,7 @@ WorkingThread_Exit:
mailimap_free(threadval.m_imap);
threadval.m_imap = NULL;
}
m_threadRunning = false;
m_threadState = MR_THREAD_NOTALLOCATED;
}
@ -295,7 +303,8 @@ WorkingThread_Exit:
MrImap::MrImap(MrMailbox* mailbox)
{
m_mailbox = mailbox;
m_threadRunning = false;
m_threadState = MR_THREAD_NOTALLOCATED;
m_threadCmd = MR_THREAD_WAIT;
m_loginParam = NULL;
pthread_mutex_init(&m_condmutex, NULL);
@ -318,12 +327,12 @@ bool MrImap::Connect(const MrLoginParam* param)
return false; // error, bad parameters
}
if( m_threadRunning ) {
if( m_threadState!=MR_THREAD_NOTALLOCATED ) {
return true; // already trying to connect
}
m_loginParam = param;
m_threadRunning = true;
m_threadState = MR_THREAD_INIT;
pthread_create(&m_thread, NULL, (void * (*)(void *)) MrImap::StartupHelper, this);
// success, so far, the real connection takes place in the working thread
@ -333,26 +342,32 @@ bool MrImap::Connect(const MrLoginParam* param)
void MrImap::Disconnect()
{
if( !m_threadRunning ) {
if( m_threadState==MR_THREAD_NOTALLOCATED ) {
return; // already disconnected
}
pthread_mutex_lock(&m_condmutex);
m_dowhat = DO_EXIT;
pthread_mutex_unlock(&m_condmutex);
if( m_threadState==MR_THREAD_EXIT || m_threadCmd==MR_THREAD_EXIT ) {
return; // already exiting/about to exit
}
// raise exit signal
m_threadCmd = MR_THREAD_EXIT;
pthread_cond_signal(&m_cond);
}
bool MrImap::Fetch()
{
if( !m_threadRunning ) {
if( m_threadState==MR_THREAD_NOTALLOCATED ) {
return false; // not connected
}
pthread_mutex_lock(&m_condmutex); // if needed, we can use pthread_mutex_trylock() to avoid signalling if the thread is busy
m_dowhat = DO_FETCH;
pthread_mutex_unlock(&m_condmutex);
if( m_threadState==MR_THREAD_FETCH || m_threadCmd==MR_THREAD_FETCH ) {
return true; // already fetching/about to fetch
}
// raise fetch signal
m_threadCmd = MR_THREAD_FETCH;
pthread_cond_signal(&m_cond);
// signal successfully raised; when and if fetching is started cannot be determinated by the return value

View file

@ -34,13 +34,24 @@
class MrMailbox;
enum MrImapThreadCmd
{
MR_THREAD_NOTALLOCATED = 0
,MR_THREAD_INIT
,MR_THREAD_CONNECT
,MR_THREAD_WAIT
,MR_THREAD_FETCH
,MR_THREAD_EXIT
};
class MrImap
{
public:
MrImap (MrMailbox* mailbox);
~MrImap ();
bool IsConnected () { return m_threadRunning; }
bool IsConnected () { return (m_threadState!=MR_THREAD_NOTALLOCATED); }
bool Connect (const MrLoginParam*);
void Disconnect ();
bool Fetch ();
@ -50,13 +61,11 @@ private:
const MrLoginParam* m_loginParam;
pthread_t m_thread;
bool m_threadRunning;
pthread_cond_t m_cond;
pthread_mutex_t m_condmutex;
#define DO_FETCH 1
#define DO_EXIT 2
int m_dowhat;
MrImapThreadCmd m_threadState; // set by the working thread, the main thread can read this
MrImapThreadCmd m_threadCmd; // set by the main thread, read and reset by the working thread
static void StartupHelper (MrImap* imap) { imap->WorkingThread(); }
void WorkingThread ();

View file

@ -195,8 +195,8 @@ char* MrMailbox::GetInfo()
"SQLite version %s, threadsafe=%i\n"
"libEtPan version %i.%i\n"
"Database file %s\n"
"Chats/Messages %i/%i\n"
"Contacts %i\n"
"Chats/Messages %i/%i\n"
"mail_server %s\n"
"mail_port %s\n"
@ -214,8 +214,8 @@ char* MrMailbox::GetInfo()
, libetpan_get_version_major(), libetpan_get_version_minor()
, dbfile? dbfile : unset
, chats, messages
, contacts
, chats, messages
, mail_server? mail_server : unset
, mail_port? mail_port : unset