зеркало из https://github.com/mozilla/gecko-dev.git
fix memory leaks and problem with stale msf files after marking read via reading a msg
This commit is contained in:
Родитель
4672a0483f
Коммит
ba91ff4c95
|
@ -40,7 +40,7 @@ class nsMsgDatabase;
|
|||
class nsDBFolderInfo : public nsIDBFolderInfo
|
||||
{
|
||||
public:
|
||||
friend class nsMsgDatabase;
|
||||
// friend class nsMsgDatabase;
|
||||
|
||||
nsDBFolderInfo(nsMsgDatabase *mdb);
|
||||
virtual ~nsDBFolderInfo();
|
||||
|
@ -115,6 +115,7 @@ public:
|
|||
void ChangeImapTotalPendingMessages(PRInt32 delta);
|
||||
void ChangeImapUnreadPendingMessages(PRInt32 delta) ;
|
||||
|
||||
nsresult InitFromExistingDB();
|
||||
// get and set arbitrary property, aka row cell value.
|
||||
nsresult SetPropertyWithToken(mdb_token aProperty, nsString &propertyStr);
|
||||
nsresult SetUint32PropertyWithToken(mdb_token aProperty, PRUint32 propertyValue);
|
||||
|
@ -123,16 +124,33 @@ public:
|
|||
nsresult GetUint32PropertyWithToken(mdb_token aProperty, PRUint32 &propertyValue);
|
||||
nsresult GetInt32PropertyWithToken(mdb_token aProperty, PRInt32 &propertyValue);
|
||||
|
||||
|
||||
nsMsgKeyArray m_lateredKeys; // list of latered messages
|
||||
|
||||
protected:
|
||||
|
||||
// initialize from appropriate table and row in existing db.
|
||||
nsresult InitMDBInfo();
|
||||
nsresult LoadMemberVariables();
|
||||
|
||||
PRInt32 m_folderSize;
|
||||
PRInt32 m_expungedBytes; // sum of size of deleted messages in folder
|
||||
time_t m_folderDate;
|
||||
nsMsgKey m_highWaterMessageKey; // largest news article number or imap uid whose header we've seen
|
||||
|
||||
PRInt32 m_numVisibleMessages; // doesn't include expunged or ignored messages (but does include collapsed).
|
||||
PRInt32 m_numNewMessages;
|
||||
PRInt32 m_numMessages; // includes expunged and ignored messages
|
||||
PRInt32 m_flags; // folder specific flags. This holds things like re-use thread pane,
|
||||
// configured for off-line use, use default retrieval, purge article/header options
|
||||
nsMsgKey m_lastMessageLoaded; // set by the FE's to remember the last loaded message
|
||||
|
||||
PRUint16 m_version; // for upgrading...
|
||||
PRInt32 m_sortType; // the last sort type open on this db.
|
||||
PRInt16 m_csid; // default csid for these messages
|
||||
PRInt16 m_IMAPHierarchySeparator; // imap path separator
|
||||
PRInt8 m_sortOrder; // the last sort order (up or down
|
||||
// mail only (for now)
|
||||
PRInt32 m_folderSize;
|
||||
PRInt32 m_expungedBytes; // sum of size of deleted messages in folder
|
||||
time_t m_folderDate;
|
||||
nsMsgKey m_highWaterMessageKey; // largest news article number or imap uid whose header we've seen
|
||||
|
||||
// IMAP only
|
||||
PRInt32 m_ImapUidValidity;
|
||||
|
@ -142,23 +160,6 @@ public:
|
|||
// news only (for now)
|
||||
nsMsgKey m_expiredMark; // Highest invalid article number in group - for expiring
|
||||
PRInt32 m_viewType; // for news, the last view type open on this db.
|
||||
|
||||
nsMsgKeyArray m_lateredKeys; // list of latered messages
|
||||
|
||||
protected:
|
||||
|
||||
// initialize from appropriate table and row in existing db.
|
||||
nsresult InitFromExistingDB();
|
||||
nsresult InitMDBInfo();
|
||||
nsresult LoadMemberVariables();
|
||||
|
||||
PRInt32 m_numVisibleMessages; // doesn't include expunged or ignored messages (but does include collapsed).
|
||||
PRInt32 m_numNewMessages;
|
||||
PRInt32 m_numMessages; // includes expunged and ignored messages
|
||||
PRInt32 m_flags; // folder specific flags. This holds things like re-use thread pane,
|
||||
// configured for off-line use, use default retrieval, purge article/header options
|
||||
nsMsgKey m_lastMessageLoaded; // set by the FE's to remember the last loaded message
|
||||
|
||||
// the db folder info will have to know what db and row it belongs to, since it is really
|
||||
// just a wrapper around the singleton folder info row in the mdb.
|
||||
nsMsgDatabase *m_mdb;
|
||||
|
|
|
@ -42,7 +42,6 @@ NS_IMETHODIMP nsMailDatabase::Open(nsFileSpec &folderName, PRBool create, nsIMsg
|
|||
{
|
||||
nsMailDatabase *mailDB;
|
||||
PRBool summaryFileExists;
|
||||
struct stat st;
|
||||
PRBool newFile = PR_FALSE;
|
||||
nsLocalFolderSummarySpec summarySpec(folderName);
|
||||
|
||||
|
@ -76,14 +75,6 @@ NS_IMETHODIMP nsMailDatabase::Open(nsFileSpec &folderName, PRBool create, nsIMsg
|
|||
// folder file.
|
||||
summaryFileExists = summarySpec.Exists();
|
||||
|
||||
char *nativeFolderName = nsCRT::strdup((const char *) folderName);
|
||||
|
||||
#if defined(XP_PC) || defined(XP_MAC)
|
||||
UnixToNative(nativeFolderName);
|
||||
#endif
|
||||
stat (nativeFolderName, &st);
|
||||
PR_FREEIF(nativeFolderName);
|
||||
|
||||
nsresult err = NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE;
|
||||
|
||||
err = mailDB->OpenMDB((const char *) summarySpec, create);
|
||||
|
@ -105,12 +96,16 @@ NS_IMETHODIMP nsMailDatabase::Open(nsFileSpec &folderName, PRBool create, nsIMsg
|
|||
PRInt32 numNewMessages;
|
||||
PRUint32 folderSize;
|
||||
time_t folderDate;
|
||||
nsFileSpec::TimeStamp actualFolderTimeStamp;
|
||||
|
||||
mailDB->m_folderSpec->GetModDate(actualFolderTimeStamp) ;
|
||||
|
||||
|
||||
folderInfo->GetNumNewMessages(&numNewMessages);
|
||||
folderInfo->GetFolderSize(&folderSize);
|
||||
folderInfo->GetFolderDate(&folderDate);
|
||||
if (folderSize != st.st_size ||
|
||||
folderDate != st.st_mtime ||
|
||||
if (folderSize != mailDB->m_folderSpec->GetFileSize()||
|
||||
folderDate != actualFolderTimeStamp ||
|
||||
numNewMessages < 0)
|
||||
err = NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE;
|
||||
}
|
||||
|
@ -348,21 +343,20 @@ void nsMailDatabase::UpdateFolderFlag(nsIMsgDBHdr *mailHdr, PRBool bSet,
|
|||
/* static */ nsresult nsMailDatabase::SetSummaryValid(PRBool valid)
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
struct stat st;
|
||||
char *nativeFileName = nsCRT::strdup(*m_folderSpec);
|
||||
#if defined(XP_PC) || defined(XP_MAC)
|
||||
UnixToNative(nativeFileName);
|
||||
#endif
|
||||
|
||||
if (stat(nativeFileName, &st))
|
||||
if (!m_folderSpec->Exists())
|
||||
return NS_MSG_ERROR_FOLDER_MISSING;
|
||||
|
||||
if (m_dbFolderInfo)
|
||||
{
|
||||
if (valid)
|
||||
{
|
||||
m_dbFolderInfo->SetFolderSize(st.st_size);
|
||||
m_dbFolderInfo->SetFolderDate(st.st_mtime);
|
||||
nsFileSpec::TimeStamp actualFolderTimeStamp;
|
||||
m_folderSpec->GetModDate(actualFolderTimeStamp) ;
|
||||
|
||||
|
||||
m_dbFolderInfo->SetFolderSize(m_folderSpec->GetFileSize());
|
||||
m_dbFolderInfo->SetFolderDate(actualFolderTimeStamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -440,23 +434,13 @@ nsresult nsMailDatabase::GetIdsWithNoBodies (nsMsgKeyArray &bodylessIds)
|
|||
/* static */
|
||||
nsresult nsMailDatabase::SetFolderInfoValid(nsFileSpec *folderName, int num, int numunread)
|
||||
{
|
||||
struct stat st;
|
||||
nsLocalFolderSummarySpec summarySpec(*folderName);
|
||||
nsFileSpec summaryPath(summarySpec);
|
||||
nsresult err;
|
||||
|
||||
char *nativeFileName = nsCRT::strdup(*folderName);
|
||||
#if defined(XP_PC) || defined(XP_MAC)
|
||||
UnixToNative(nativeFileName);
|
||||
#endif
|
||||
|
||||
if (!folderName->Exists())
|
||||
return NS_MSG_ERROR_FOLDER_SUMMARY_MISSING;
|
||||
|
||||
stat(nativeFileName, &st);
|
||||
|
||||
PR_FREEIF(nativeFileName); // ### use file spec method for size and time stamp when they're written.
|
||||
|
||||
// should we have type safe downcast methods again?
|
||||
nsMailDatabase *pMessageDB = (nsMailDatabase *) nsMailDatabase::FindInCache(summaryPath);
|
||||
if (pMessageDB == NULL)
|
||||
|
@ -492,8 +476,11 @@ nsresult nsMailDatabase::SetFolderInfoValid(nsFileSpec *folderName, int num, int
|
|||
}
|
||||
|
||||
{
|
||||
pMessageDB->m_dbFolderInfo->m_folderSize = st.st_size;
|
||||
pMessageDB->m_dbFolderInfo->m_folderDate = st.st_mtime;
|
||||
nsFileSpec::TimeStamp actualFolderTimeStamp;
|
||||
folderName->GetModDate(actualFolderTimeStamp) ;
|
||||
|
||||
pMessageDB->m_dbFolderInfo->SetFolderSize(folderName->GetFileSize());
|
||||
pMessageDB->m_dbFolderInfo->SetFolderDate(actualFolderTimeStamp);
|
||||
pMessageDB->m_dbFolderInfo->ChangeNumVisibleMessages(num);
|
||||
pMessageDB->m_dbFolderInfo->ChangeNumNewMessages(numunread);
|
||||
pMessageDB->m_dbFolderInfo->ChangeNumMessages(num);
|
||||
|
|
|
@ -932,7 +932,7 @@ NS_IMETHODIMP nsMsgDatabase::DeleteHeader(nsIMsgDBHdr *msg, nsIDBChangeListener
|
|||
|
||||
PRUint32 size;
|
||||
(void)msg->GetMessageSize(&size);
|
||||
m_dbFolderInfo->m_expungedBytes += size;
|
||||
m_dbFolderInfo->ChangeExpungedBytes (size);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1971,6 +1971,7 @@ nsresult nsMsgDatabase::RowCellColumnTonsString(nsIMdbRow *hdrRow, mdb_token col
|
|||
struct mdbYarn yarn;
|
||||
hdrCell->AliasYarn(GetEnv(), &yarn);
|
||||
YarnTonsString(&yarn, &resultStr);
|
||||
hdrCell->CutStrongRef(GetEnv()); // always release ref
|
||||
}
|
||||
}
|
||||
return err;
|
||||
|
@ -2091,6 +2092,7 @@ nsresult nsMsgDatabase::RowCellColumnToUInt32(nsIMdbRow *hdrRow, mdb_token colum
|
|||
struct mdbYarn yarn;
|
||||
hdrCell->AliasYarn(GetEnv(), &yarn);
|
||||
YarnToUInt32(&yarn, uint32Result);
|
||||
hdrCell->CutStrongRef(GetEnv()); // always release ref
|
||||
}
|
||||
}
|
||||
return err;
|
||||
|
@ -2219,7 +2221,7 @@ nsMsgThread * nsMsgDatabase::GetThreadForSubject(const char * subject)
|
|||
nsresult nsMsgDatabase::ThreadNewHdr(nsMsgHdr* newHdr, PRBool &newThread)
|
||||
{
|
||||
nsresult result=NS_ERROR_UNEXPECTED;
|
||||
nsMsgThread *thread = nsnull;
|
||||
nsCOMPtr<nsMsgThread> thread;
|
||||
nsMsgKey threadId = nsMsgKey_None;
|
||||
|
||||
if (!newHdr)
|
||||
|
@ -2244,7 +2246,8 @@ nsresult nsMsgDatabase::ThreadNewHdr(nsMsgHdr* newHdr, PRBool &newThread)
|
|||
if (reference.Length() == 0)
|
||||
break;
|
||||
|
||||
if ((thread = GetThreadForReference(reference)) != NULL)
|
||||
thread = getter_AddRefs(GetThreadForReference(reference)) ;
|
||||
if (thread)
|
||||
{
|
||||
thread->GetThreadKey(&threadId);
|
||||
newHdr->SetThreadId(threadId);
|
||||
|
@ -2257,14 +2260,18 @@ nsresult nsMsgDatabase::ThreadNewHdr(nsMsgHdr* newHdr, PRBool &newThread)
|
|||
nsString subject;
|
||||
|
||||
newHdr->GetSubject(subject);
|
||||
if ((ThreadBySubjectWithoutRe() || (newHdrFlags & MSG_FLAG_HAS_RE)) && thread == NULL && (thread = GetThreadForSubject(nsAutoCString(subject))) != NULL)
|
||||
if ((ThreadBySubjectWithoutRe() || (newHdrFlags & MSG_FLAG_HAS_RE)) && !thread == NULL)
|
||||
{
|
||||
thread->GetThreadKey(&threadId);
|
||||
newHdr->SetThreadId(threadId);
|
||||
//TRACE("threading based on subject %s\n", (const char *) msgHdr->m_subject);
|
||||
// if we move this and do subject threading after, ref threading,
|
||||
// don't thread within children, since we know it won't work. But for now, pass TRUE.
|
||||
result = AddToThread(newHdr, thread, TRUE);
|
||||
thread = getter_AddRefs(GetThreadForSubject(nsAutoCString(subject)));
|
||||
if(thread)
|
||||
{
|
||||
thread->GetThreadKey(&threadId);
|
||||
newHdr->SetThreadId(threadId);
|
||||
//TRACE("threading based on subject %s\n", (const char *) msgHdr->m_subject);
|
||||
// if we move this and do subject threading after, ref threading,
|
||||
// don't thread within children, since we know it won't work. But for now, pass TRUE.
|
||||
result = AddToThread(newHdr, thread, TRUE);
|
||||
}
|
||||
}
|
||||
#endif // SUBJ_THREADING
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче