aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2013-06-18 21:18:27 -0700
committerGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2013-06-18 21:18:27 -0700
commit35b72c7cf7c13d9ea63f75796b3906ca611f0196 (patch)
tree4696bff1b2750845729fd42d2512b44ec37f85d5 /src
parent74aaa9972b440891339e6ee06aeff4a13af65ebb (diff)
Fixed race conditions in IDLE (#101)
Diffstat (limited to 'src')
-rw-r--r--src/async/imap/MCIMAPIdleOperation.cc15
-rw-r--r--src/async/imap/MCIMAPIdleOperation.h2
-rw-r--r--src/core/imap/MCIMAPSession.cc23
-rw-r--r--src/core/imap/MCIMAPSession.h3
4 files changed, 34 insertions, 9 deletions
diff --git a/src/async/imap/MCIMAPIdleOperation.cc b/src/async/imap/MCIMAPIdleOperation.cc
index 9006b570..42c58f90 100644
--- a/src/async/imap/MCIMAPIdleOperation.cc
+++ b/src/async/imap/MCIMAPIdleOperation.cc
@@ -16,6 +16,7 @@ using namespace mailcore;
IMAPIdleOperation::IMAPIdleOperation()
{
mLastKnownUid = 0;
+ mSetupSuccess = false;
}
IMAPIdleOperation::~IMAPIdleOperation()
@@ -34,18 +35,24 @@ uint32_t IMAPIdleOperation::lastKnownUID()
void IMAPIdleOperation::prepare()
{
- session()->session()->setupIdle();
+ mSetupSuccess = session()->session()->setupIdle();
}
void IMAPIdleOperation::unprepare()
{
- session()->session()->unsetupIdle();
+ if (mSetupSuccess) {
+ session()->session()->unsetupIdle();
+ }
}
void IMAPIdleOperation::main()
{
performMethodOnMainThread((Object::Method) &IMAPIdleOperation::prepare, NULL);
+ if (!mSetupSuccess) {
+ return;
+ }
+
ErrorCode error;
session()->session()->idle(folder(), mLastKnownUid, &error);
setError(error);
@@ -55,6 +62,8 @@ void IMAPIdleOperation::main()
void IMAPIdleOperation::interruptIdle()
{
- session()->session()->interruptIdle();
+ if (mSetupSuccess) {
+ session()->session()->interruptIdle();
+ }
}
diff --git a/src/async/imap/MCIMAPIdleOperation.h b/src/async/imap/MCIMAPIdleOperation.h
index 377014dd..de19469a 100644
--- a/src/async/imap/MCIMAPIdleOperation.h
+++ b/src/async/imap/MCIMAPIdleOperation.h
@@ -31,9 +31,9 @@ namespace mailcore {
private:
uint32_t mLastKnownUid;
+ bool mSetupSuccess;
void prepare();
void unprepare();
-
};
}
diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc
index 9fc8aa21..cdbe6004 100644
--- a/src/core/imap/MCIMAPSession.cc
+++ b/src/core/imap/MCIMAPSession.cc
@@ -335,6 +335,7 @@ void IMAPSession::init()
mLastFetchedSequenceNumber = 0;
mCurrentFolder = NULL;
pthread_mutex_init(&mIdleLock, NULL);
+ mCanIdle = false;
mState = STATE_DISCONNECTED;
mImap = NULL;
mProgressCallback = NULL;
@@ -499,8 +500,11 @@ void IMAPSession::unsetup()
{
mailimap * imap;
+ LOCK();
imap = mImap;
mImap = NULL;
+ mCanIdle = false;
+ UNLOCK();
if (imap != NULL) {
if (imap->imap_stream != NULL) {
@@ -588,6 +592,9 @@ void IMAPSession::connect(ErrorCode * pError)
* pError = ErrorNone;
mState = STATE_CONNECTED;
MCLog("connect ok");
+ LOCK();
+ mCanIdle = true;
+ UNLOCK();
}
void IMAPSession::connectIfNeeded(ErrorCode * pError)
@@ -2316,12 +2323,16 @@ IndexSet * IMAPSession::search(String * folder, IMAPSearchExpression * expressio
return result;
}
-void IMAPSession::setupIdle()
+bool IMAPSession::setupIdle()
{
// main thread
LOCK();
- mailstream_setup_idle(mImap->imap_stream);
+ bool canIdle = mCanIdle;
+ if (mCanIdle) {
+ mailstream_setup_idle(mImap->imap_stream);
+ }
UNLOCK();
+ return canIdle;
}
void IMAPSession::idle(String * folder, uint32_t lastKnownUID, ErrorCode * pError)
@@ -2411,7 +2422,9 @@ void IMAPSession::interruptIdle()
{
// main thread
LOCK();
- mailstream_interrupt_idle(mImap->imap_stream);
+ if (mCanIdle) {
+ mailstream_interrupt_idle(mImap->imap_stream);
+ }
UNLOCK();
}
@@ -2419,7 +2432,9 @@ void IMAPSession::unsetupIdle()
{
// main thread
LOCK();
- mailstream_unsetup_idle(mImap->imap_stream);
+ if (mCanIdle) {
+ mailstream_unsetup_idle(mImap->imap_stream);
+ }
UNLOCK();
}
diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h
index 40e3a1da..8531b050 100644
--- a/src/core/imap/MCIMAPSession.h
+++ b/src/core/imap/MCIMAPSession.h
@@ -106,7 +106,7 @@ namespace mailcore {
virtual IndexSet * search(String * folder, IMAPSearchKind kind, String * searchString, ErrorCode * pError);
virtual IndexSet * search(String * folder, IMAPSearchExpression * expression, ErrorCode * pError);
- virtual void setupIdle();
+ virtual bool setupIdle();
virtual void idle(String * folder, uint32_t lastKnownUID, ErrorCode * pError);
virtual void interruptIdle();
virtual void unsetupIdle();
@@ -168,6 +168,7 @@ namespace mailcore {
unsigned int mLastFetchedSequenceNumber;
String * mCurrentFolder;
pthread_mutex_t mIdleLock;
+ bool mCanIdle;
int mState;
mailimap * mImap;
IMAPProgressCallback * mProgressCallback;