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,
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)]
interface nsIMsgFilterHitNotify : nsISupports {
boolean applyFilterHit(in nsIMsgFilter filter, in nsIMsgWindow msgWindow);
};

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

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

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

@ -268,7 +268,7 @@ nsMsgFilter::GetActionTargetFolderUri(char** aResult)
#define LOG_ENTRY_END_TAG "</pre>\n"
#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;
nsresult rv = m_filterList->GetLogStream(getter_AddRefs(logStream));
@ -285,17 +285,19 @@ NS_IMETHODIMP nsMsgFilter::LogRuleHit(nsIMsgDBHdr *msgHdr)
GetFilterName(getter_Copies(filterName));
GetAction(&actionType);
rv = msgHdr->GetDate(&date);
rv = aMsgHdr->GetDate(&date);
PRExplodedTime exploded;
PR_ExplodeTime(date, PR_LocalTimeParameters, &exploded);
PR_FormatTimeUSEnglish(dateStr, 100, "%m/%d/%Y %I:%M %p", &exploded);
msgHdr->GetAuthor(getter_Copies(author));
msgHdr->GetSubject(getter_Copies(subject));
aMsgHdr->GetAuthor(getter_Copies(author));
aMsgHdr->GetSubject(getter_Copies(subject));
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 += NS_ConvertUCS2toUTF8(filterName).get();
buffer += "\" to message from ";
@ -318,7 +320,7 @@ NS_IMETHODIMP nsMsgFilter::LogRuleHit(nsIMsgDBHdr *msgHdr)
buffer += "\n";
if (actionType == nsMsgFilterAction::MoveToFolder) {
nsXPIDLCString msgId;
msgHdr->GetMessageId(getter_Copies(msgId));
aMsgHdr->GetMessageId(getter_Copies(msgId));
buffer += (const char *) actionFolderUri;
buffer += " id = ";
buffer += (const char*)msgId;
@ -331,6 +333,9 @@ NS_IMETHODIMP nsMsgFilter::LogRuleHit(nsIMsgDBHdr *msgHdr)
NS_ENSURE_SUCCESS(rv,rv);
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());
if (!escapedBuffer)
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);
NS_ENSURE_SUCCESS(rv,rv);
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;
}

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

@ -56,8 +56,6 @@
#include "nsIFileStreams.h"
#include "nsISupportsObsolete.h"
static NS_DEFINE_CID(kMsgFilterServiceCID, NS_MSGFILTERSERVICE_CID);
// unicode "%s" format string
static const PRUnichar unicodeFormatter[] = {
(PRUnichar)'%',
@ -330,7 +328,7 @@ nsMsgFilterList::SaveToDefaultFile()
{
nsresult rv;
nsCOMPtr<nsIMsgFilterService> filterService =
do_GetService(kMsgFilterServiceCID, &rv);
do_GetService(NS_MSGFILTERSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return filterService->SaveFilterList(this, m_defaultFile);
@ -1027,7 +1025,24 @@ NS_IMETHODIMP nsMsgFilterList::GetArbitraryHeaders(char **aResult)
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
void nsMsgFilterList::Dump()

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

@ -21,6 +21,7 @@
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Seth Spitzer <sspitzer@netscape.com>
*
* 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
@ -59,6 +60,7 @@
#include "nsIRDFService.h"
#include "nsMsgBaseCID.h"
#include "nsIMsgCopyService.h"
#include "nsIOutputStream.h"
NS_IMPL_ISUPPORTS1(nsMsgFilterService, nsIMsgFilterService)
@ -360,14 +362,16 @@ nsMsgFilterAfterTheFact::~nsMsgFilterAfterTheFact()
}
// do what we have to do to cleanup.
nsresult nsMsgFilterAfterTheFact::OnEndExecution(nsresult executionStatus)
nsresult nsMsgFilterAfterTheFact::OnEndExecution(nsresult executionStatus)
{
if (m_searchSession)
m_searchSession->UnregisterListener(this);
if (m_filters)
(void)m_filters->FlushLogIfNecessary();
Release(); // release ourselves.
return executionStatus;
}
nsresult nsMsgFilterAfterTheFact::RunNextFilter()
@ -462,6 +466,7 @@ NS_IMETHODIMP nsMsgFilterAfterTheFact::OnSearchDone(nsresult status)
PRBool continueExecution = NS_SUCCEEDED(status);
if (!continueExecution)
continueExecution = ContinueExecutionPrompt();
if (continueExecution)
return (m_searchHits.GetSize() > 0) ? ApplyFilter() : RunNextFilter();
else
@ -477,7 +482,6 @@ NS_IMETHODIMP nsMsgFilterAfterTheFact::OnNewSearch()
nsresult nsMsgFilterAfterTheFact::ApplyFilter()
{
nsresult rv = NS_OK;
if (m_curFilter && m_curFolder)
{

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -240,6 +240,16 @@ nsPop3Sink::EndMailDelivery()
nsresult rv = ReleaseFolderLock();
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
printf("End mail message delivery.\n");
#endif

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

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