fix for bug #168521. too much disk IO when logging filters.

fix for bug #168536.  assertions on shutting down due to filter changes.
r/sr=bienvenu
This commit is contained in:
sspitzer%netscape.com 2002-09-13 21:58:45 +00:00
Родитель a3a325b2e9
Коммит ccc130e09b
14 изменённых файлов: 72 добавлений и 44 удалений

Просмотреть файл

@ -100,7 +100,5 @@ interface nsIMsgFilter : nsISupports {
// [array, size_is(headerSize)] in string headers, // [array, size_is(headerSize)] in string headers,
in unsigned long headerSize, out boolean result); in unsigned long headerSize, out boolean result);
void logRuleHit(in nsIMsgDBHdr header); void logRuleHit(in nsIMsgDBHdr aHeader);
}; };

Просмотреть файл

@ -54,7 +54,6 @@ interface nsIMsgWindow;
[scriptable, uuid(c9f15174-1f3f-11d3-a51b-0060b0fc04b7)] [scriptable, uuid(c9f15174-1f3f-11d3-a51b-0060b0fc04b7)]
interface nsIMsgFilterHitNotify : nsISupports { interface nsIMsgFilterHitNotify : nsISupports {
boolean applyFilterHit(in nsIMsgFilter filter, in nsIMsgWindow msgWindow); boolean applyFilterHit(in nsIMsgFilter filter, in nsIMsgWindow msgWindow);
}; };

Просмотреть файл

@ -125,6 +125,7 @@ interface nsIMsgFilterList : nsISupports {
readonly attribute string logURL; readonly attribute string logURL;
void clearLog(); void clearLog();
void ensureLogFile(); void ensureLogFile();
void flushLogIfNecessary();
}; };

Просмотреть файл

@ -268,7 +268,7 @@ nsMsgFilter::GetActionTargetFolderUri(char** aResult)
#define LOG_ENTRY_END_TAG "</pre>\n" #define LOG_ENTRY_END_TAG "</pre>\n"
#define LOG_ENTRY_END_TAG_LEN (strlen(LOG_ENTRY_END_TAG)) #define LOG_ENTRY_END_TAG_LEN (strlen(LOG_ENTRY_END_TAG))
NS_IMETHODIMP nsMsgFilter::LogRuleHit(nsIMsgDBHdr *msgHdr) NS_IMETHODIMP nsMsgFilter::LogRuleHit(nsIMsgDBHdr *aMsgHdr)
{ {
nsCOMPtr <nsIOutputStream> logStream; nsCOMPtr <nsIOutputStream> logStream;
nsresult rv = m_filterList->GetLogStream(getter_AddRefs(logStream)); nsresult rv = m_filterList->GetLogStream(getter_AddRefs(logStream));
@ -285,17 +285,19 @@ NS_IMETHODIMP nsMsgFilter::LogRuleHit(nsIMsgDBHdr *msgHdr)
GetFilterName(getter_Copies(filterName)); GetFilterName(getter_Copies(filterName));
GetAction(&actionType); GetAction(&actionType);
rv = msgHdr->GetDate(&date); rv = aMsgHdr->GetDate(&date);
PRExplodedTime exploded; PRExplodedTime exploded;
PR_ExplodeTime(date, PR_LocalTimeParameters, &exploded); PR_ExplodeTime(date, PR_LocalTimeParameters, &exploded);
PR_FormatTimeUSEnglish(dateStr, 100, "%m/%d/%Y %I:%M %p", &exploded); PR_FormatTimeUSEnglish(dateStr, 100, "%m/%d/%Y %I:%M %p", &exploded);
msgHdr->GetAuthor(getter_Copies(author)); aMsgHdr->GetAuthor(getter_Copies(author));
msgHdr->GetSubject(getter_Copies(subject)); aMsgHdr->GetSubject(getter_Copies(subject));
nsCString buffer; nsCString buffer;
buffer.SetCapacity(512); // this is big enough to hold a log entry.
// do this so we avoid growing and copying as we append to the log.
buffer.SetCapacity(512);
buffer = "Applied filter \""; buffer = "Applied filter \"";
buffer += NS_ConvertUCS2toUTF8(filterName).get(); buffer += NS_ConvertUCS2toUTF8(filterName).get();
buffer += "\" to message from "; buffer += "\" to message from ";
@ -318,7 +320,7 @@ NS_IMETHODIMP nsMsgFilter::LogRuleHit(nsIMsgDBHdr *msgHdr)
buffer += "\n"; buffer += "\n";
if (actionType == nsMsgFilterAction::MoveToFolder) { if (actionType == nsMsgFilterAction::MoveToFolder) {
nsXPIDLCString msgId; nsXPIDLCString msgId;
msgHdr->GetMessageId(getter_Copies(msgId)); aMsgHdr->GetMessageId(getter_Copies(msgId));
buffer += (const char *) actionFolderUri; buffer += (const char *) actionFolderUri;
buffer += " id = "; buffer += " id = ";
buffer += (const char*)msgId; buffer += (const char*)msgId;
@ -331,6 +333,9 @@ NS_IMETHODIMP nsMsgFilter::LogRuleHit(nsIMsgDBHdr *msgHdr)
NS_ENSURE_SUCCESS(rv,rv); NS_ENSURE_SUCCESS(rv,rv);
NS_ASSERTION(writeCount == LOG_ENTRY_START_TAG_LEN, "failed to write out start log tag"); NS_ASSERTION(writeCount == LOG_ENTRY_START_TAG_LEN, "failed to write out start log tag");
// html escape the log for security reasons.
// we don't want some to send us a message with a subject with
// html tags, especially <script>
char *escapedBuffer = nsEscapeHTML(buffer.get()); char *escapedBuffer = nsEscapeHTML(buffer.get());
if (!escapedBuffer) if (!escapedBuffer)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
@ -344,10 +349,6 @@ NS_IMETHODIMP nsMsgFilter::LogRuleHit(nsIMsgDBHdr *msgHdr)
rv = logStream->Write(LOG_ENTRY_END_TAG, LOG_ENTRY_END_TAG_LEN, &writeCount); rv = logStream->Write(LOG_ENTRY_END_TAG, LOG_ENTRY_END_TAG_LEN, &writeCount);
NS_ENSURE_SUCCESS(rv,rv); NS_ENSURE_SUCCESS(rv,rv);
NS_ASSERTION(writeCount == LOG_ENTRY_END_TAG_LEN, "failed to write out end log tag"); NS_ASSERTION(writeCount == LOG_ENTRY_END_TAG_LEN, "failed to write out end log tag");
// flush to disk after ever log hit
rv = logStream->Flush();
NS_ENSURE_SUCCESS(rv,rv);
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -56,8 +56,6 @@
#include "nsIFileStreams.h" #include "nsIFileStreams.h"
#include "nsISupportsObsolete.h" #include "nsISupportsObsolete.h"
static NS_DEFINE_CID(kMsgFilterServiceCID, NS_MSGFILTERSERVICE_CID);
// unicode "%s" format string // unicode "%s" format string
static const PRUnichar unicodeFormatter[] = { static const PRUnichar unicodeFormatter[] = {
(PRUnichar)'%', (PRUnichar)'%',
@ -330,7 +328,7 @@ nsMsgFilterList::SaveToDefaultFile()
{ {
nsresult rv; nsresult rv;
nsCOMPtr<nsIMsgFilterService> filterService = nsCOMPtr<nsIMsgFilterService> filterService =
do_GetService(kMsgFilterServiceCID, &rv); do_GetService(NS_MSGFILTERSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
return filterService->SaveFilterList(this, m_defaultFile); return filterService->SaveFilterList(this, m_defaultFile);
@ -1027,7 +1025,24 @@ NS_IMETHODIMP nsMsgFilterList::GetArbitraryHeaders(char **aResult)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsMsgFilterList::FlushLogIfNecessary()
{
// if we are logging, flush the log at the end of applying the filters
PRBool loggingEnabled = PR_FALSE;
nsresult rv = GetLoggingEnabled(&loggingEnabled);
NS_ENSURE_SUCCESS(rv,rv);
if (loggingEnabled)
{
nsCOMPtr <nsIOutputStream> logStream;
rv = GetLogStream(getter_AddRefs(logStream));
if (NS_SUCCEEDED(rv) && logStream) {
rv = logStream->Flush();
NS_ENSURE_SUCCESS(rv,rv);
}
}
return rv;
}
#ifdef DEBUG #ifdef DEBUG
void nsMsgFilterList::Dump() void nsMsgFilterList::Dump()

Просмотреть файл

@ -21,6 +21,7 @@
* *
* Contributor(s): * Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com> * Pierre Phaneuf <pp@ludusdesign.com>
* Seth Spitzer <sspitzer@netscape.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -59,6 +60,7 @@
#include "nsIRDFService.h" #include "nsIRDFService.h"
#include "nsMsgBaseCID.h" #include "nsMsgBaseCID.h"
#include "nsIMsgCopyService.h" #include "nsIMsgCopyService.h"
#include "nsIOutputStream.h"
NS_IMPL_ISUPPORTS1(nsMsgFilterService, nsIMsgFilterService) NS_IMPL_ISUPPORTS1(nsMsgFilterService, nsIMsgFilterService)
@ -360,14 +362,16 @@ nsMsgFilterAfterTheFact::~nsMsgFilterAfterTheFact()
} }
// do what we have to do to cleanup. // do what we have to do to cleanup.
nsresult nsMsgFilterAfterTheFact::OnEndExecution(nsresult executionStatus) nsresult nsMsgFilterAfterTheFact::OnEndExecution(nsresult executionStatus)
{ {
if (m_searchSession) if (m_searchSession)
m_searchSession->UnregisterListener(this); m_searchSession->UnregisterListener(this);
if (m_filters)
(void)m_filters->FlushLogIfNecessary();
Release(); // release ourselves. Release(); // release ourselves.
return executionStatus; return executionStatus;
} }
nsresult nsMsgFilterAfterTheFact::RunNextFilter() nsresult nsMsgFilterAfterTheFact::RunNextFilter()
@ -462,6 +466,7 @@ NS_IMETHODIMP nsMsgFilterAfterTheFact::OnSearchDone(nsresult status)
PRBool continueExecution = NS_SUCCEEDED(status); PRBool continueExecution = NS_SUCCEEDED(status);
if (!continueExecution) if (!continueExecution)
continueExecution = ContinueExecutionPrompt(); continueExecution = ContinueExecutionPrompt();
if (continueExecution) if (continueExecution)
return (m_searchHits.GetSize() > 0) ? ApplyFilter() : RunNextFilter(); return (m_searchHits.GetSize() > 0) ? ApplyFilter() : RunNextFilter();
else else
@ -477,7 +482,6 @@ NS_IMETHODIMP nsMsgFilterAfterTheFact::OnNewSearch()
nsresult nsMsgFilterAfterTheFact::ApplyFilter() nsresult nsMsgFilterAfterTheFact::ApplyFilter()
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
if (m_curFilter && m_curFolder) if (m_curFilter && m_curFolder)
{ {

Просмотреть файл

@ -82,7 +82,6 @@
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kMsgFilterServiceCID, NS_MSGFILTERSERVICE_CID);
#define PORT_NOT_SET -1 #define PORT_NOT_SET -1
@ -222,13 +221,13 @@ nsMsgIncomingServer::Shutdown()
nsresult rv = CloseCachedConnections(); nsresult rv = CloseCachedConnections();
NS_ENSURE_SUCCESS(rv,rv); NS_ENSURE_SUCCESS(rv,rv);
nsCOMPtr <nsIMsgFilterList> filterList; if (mFilterList)
rv = GetFilterList(nsnull, getter_AddRefs(filterList)); {
NS_ENSURE_SUCCESS(rv,rv); // close the filter log stream
rv = mFilterList->SetLogStream(nsnull);
// close the filter log stream NS_ENSURE_SUCCESS(rv,rv);
rv = filterList->SetLogStream(nsnull); mFilterList = nsnull;
NS_ENSURE_SUCCESS(rv,rv); }
return rv; return rv;
} }
@ -1069,11 +1068,9 @@ nsMsgIncomingServer::SetFilterList(nsIMsgFilterList *aFilterList)
nsresult nsresult
nsMsgIncomingServer::GetFilterList(nsIMsgWindow *aMsgWindow, nsIMsgFilterList **aResult) nsMsgIncomingServer::GetFilterList(nsIMsgWindow *aMsgWindow, nsIMsgFilterList **aResult)
{ {
nsresult rv;
if (!mFilterList) { if (!mFilterList) {
nsCOMPtr<nsIMsgFolder> msgFolder; nsCOMPtr<nsIMsgFolder> msgFolder;
rv = GetRootMsgFolder(getter_AddRefs(msgFolder)); nsresult rv = GetRootMsgFolder(getter_AddRefs(msgFolder));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFileSpec> thisFolder; nsCOMPtr<nsIFileSpec> thisFolder;
@ -1089,13 +1086,13 @@ nsMsgIncomingServer::GetFilterList(nsIMsgWindow *aMsgWindow, nsIMsgFilterList **
mFilterFile->AppendRelativeUnixPath("rules.dat"); mFilterFile->AppendRelativeUnixPath("rules.dat");
nsCOMPtr<nsIMsgFilterService> filterService = nsCOMPtr<nsIMsgFilterService> filterService =
do_GetService(kMsgFilterServiceCID, &rv); do_GetService(NS_MSGFILTERSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = filterService->OpenFilterList(mFilterFile, msgFolder, aMsgWindow, getter_AddRefs(mFilterList)); rv = filterService->OpenFilterList(mFilterFile, msgFolder, aMsgWindow, getter_AddRefs(mFilterList));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
NS_IF_ADDREF(*aResult = mFilterList); NS_IF_ADDREF(*aResult = mFilterList);
return NS_OK; return NS_OK;

Просмотреть файл

@ -4910,6 +4910,10 @@ nsImapMailFolder::HeaderFetchCompleted(nsIImapProtocol* aProtocol)
else else
aProtocol->NotifyBodysToDownload(nsnull, 0/*keysToFetch.GetSize() */); aProtocol->NotifyBodysToDownload(nsnull, 0/*keysToFetch.GetSize() */);
} }
if (m_filterList)
(void)m_filterList->FlushLogIfNecessary();
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -332,9 +332,10 @@ public:
NS_IMETHOD PercentProgress(nsIImapProtocol* aProtocol, NS_IMETHOD PercentProgress(nsIImapProtocol* aProtocol,
ProgressInfo* aInfo); ProgressInfo* aInfo);
NS_IMETHOD MatchName(nsString *name, PRBool *matches); NS_IMETHOD MatchName(nsString *name, PRBool *matches);
// nsIMsgFilterHitNotification method(s)
NS_IMETHOD ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWindow *msgWindow, PRBool *applyMore); NS_DECL_NSIMSGFILTERHITNOTIFY
NS_IMETHOD IsCommandEnabled(const char *command, PRBool *result);
NS_IMETHOD IsCommandEnabled(const char *command, PRBool *result);
NS_IMETHOD SetFilterList(nsIMsgFilterList *aMsgFilterList); NS_IMETHOD SetFilterList(nsIMsgFilterList *aMsgFilterList);
nsresult MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, nsresult MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr,

Просмотреть файл

@ -51,7 +51,7 @@ interface nsIPop3Sink : nsISupports {
attribute string baseMessageUri; attribute string baseMessageUri;
boolean BeginMailDelivery(in boolean uidlDownload, in nsIMsgWindow msgWindow); boolean BeginMailDelivery(in boolean uidlDownload, in nsIMsgWindow msgWindow);
void EndMailDelivery(); void endMailDelivery();
void AbortMailDelivery(); void AbortMailDelivery();
/* returns a closure ? */ /* returns a closure ? */

Просмотреть файл

@ -240,7 +240,6 @@ NS_IMETHODIMP nsNoIncomingServer::GetNewMail(nsIMsgWindow *aMsgWindow, nsIUrlLis
NS_IMETHODIMP NS_IMETHODIMP
nsNoIncomingServer::GetFilterList(nsIMsgWindow *aMsgWindow, nsIMsgFilterList **aResult) nsNoIncomingServer::GetFilterList(nsIMsgWindow *aMsgWindow, nsIMsgFilterList **aResult)
{ {
*aResult = nsnull;
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
} }

Просмотреть файл

@ -251,8 +251,7 @@ public:
nsIMsgFilter *filter, nsIMsgFilter *filter,
PRBool *pMoved); PRBool *pMoved);
#endif #endif
// nsIMsgFilterHitNotification method(s) NS_DECL_NSIMSGFILTERHITNOTIFY
NS_IMETHOD ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWindow *msgWindow, PRBool *applyMore);
nsOutputFileStream *GetLogFile(); nsOutputFileStream *GetLogFile();
virtual PRInt32 PublishMsgHeader(nsIMsgWindow *msgWindow); virtual PRInt32 PublishMsgHeader(nsIMsgWindow *msgWindow);
@ -267,7 +266,7 @@ protected:
nsIMsgFilter *filter, nsIMsgFilter *filter,
nsIMsgWindow *msgWindow); nsIMsgWindow *msgWindow);
virtual int MarkFilteredMessageRead(nsIMsgDBHdr *msgHdr); virtual int MarkFilteredMessageRead(nsIMsgDBHdr *msgHdr);
void LogRuleHit(nsIMsgFilter *filter, nsIMsgDBHdr *msgHdr); void LogRuleHit(nsIMsgFilter *filter, nsIMsgDBHdr *msgHdr);
nsCOMPtr <nsIMsgFilterList> m_filterList; nsCOMPtr <nsIMsgFilterList> m_filterList;
nsCOMPtr <nsIFolder> m_rootFolder; nsCOMPtr <nsIFolder> m_rootFolder;
nsIOFileStream *m_inboxFileStream; nsIOFileStream *m_inboxFileStream;

Просмотреть файл

@ -240,6 +240,16 @@ nsPop3Sink::EndMailDelivery()
nsresult rv = ReleaseFolderLock(); nsresult rv = ReleaseFolderLock();
NS_ASSERTION(NS_SUCCEEDED(rv),"folder lock not released successfully"); NS_ASSERTION(NS_SUCCEEDED(rv),"folder lock not released successfully");
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_popServer);
if (server) {
nsCOMPtr <nsIMsgFilterList> filterList;
rv = server->GetFilterList(nsnull, getter_AddRefs(filterList));
NS_ENSURE_SUCCESS(rv,rv);
if (filterList)
(void) filterList->FlushLogIfNecessary();
}
#ifdef DEBUG #ifdef DEBUG
printf("End mail message delivery.\n"); printf("End mail message delivery.\n");
#endif #endif

Просмотреть файл

@ -616,11 +616,11 @@ nsNntpIncomingServer::PerformExpand(nsIMsgWindow *aMsgWindow)
return NS_OK; return NS_OK;
} }
// remove this when news supports filters // fix this when news supports filters
NS_IMETHODIMP NS_IMETHODIMP
nsNntpIncomingServer::GetFilterList(nsIMsgWindow *aMsgWindow, nsIMsgFilterList **aResult) nsNntpIncomingServer::GetFilterList(nsIMsgWindow *aMsgWindow, nsIMsgFilterList **aResult)
{ {
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
} }
NS_IMETHODIMP NS_IMETHODIMP