big-ass leak fix - stop leaking mail datasources by clearing ourselves out when the last
RDF observer goes away, and re-initializing if new RDF observers arrive on the scene. r=putterman fixes #45176, among other leaks git-svn-id: svn://10.0.0.236/trunk@75828 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
ed5414a7fa
commit
e385002b0a
@ -117,20 +117,39 @@ nsCOMPtr<nsISupportsArray> nsMsgAccountManagerDataSource::mAccountRootArcsOut;
|
||||
|
||||
nsMsgAccountManagerDataSource::nsMsgAccountManagerDataSource()
|
||||
{
|
||||
|
||||
#ifdef DEBUG_amds
|
||||
printf("nsMsgAccountManagerDataSource() being created\n");
|
||||
#endif
|
||||
|
||||
// do per-class initialization here
|
||||
if (gAccountManagerResourceRefCnt++ == 0) {
|
||||
getRDFService()->GetResource(NC_RDF_CHILD, &kNC_Child);
|
||||
getRDFService()->GetResource(NC_RDF_NAME, &kNC_Name);
|
||||
getRDFService()->GetResource(NC_RDF_FOLDERTREENAME, &kNC_FolderTreeName);
|
||||
getRDFService()->GetResource(NC_RDF_NAME_SORT, &kNC_NameSort);
|
||||
getRDFService()->GetResource(NC_RDF_FOLDERTREENAME_SORT, &kNC_FolderTreeNameSort);
|
||||
getRDFService()->GetResource(NC_RDF_PAGETAG, &kNC_PageTag);
|
||||
getRDFService()->GetResource(NC_RDF_ISDEFAULTSERVER, &kNC_IsDefaultServer);
|
||||
getRDFService()->GetResource(NC_RDF_ACCOUNT, &kNC_Account);
|
||||
getRDFService()->GetResource(NC_RDF_SERVER, &kNC_Server);
|
||||
getRDFService()->GetResource(NC_RDF_IDENTITY, &kNC_Identity);
|
||||
getRDFService()->GetResource(NC_RDF_PAGETITLE_MAIN, &kNC_PageTitleMain);
|
||||
getRDFService()->GetResource(NC_RDF_PAGETITLE_SERVER, &kNC_PageTitleServer);
|
||||
getRDFService()->GetResource(NC_RDF_PAGETITLE_COPIES, &kNC_PageTitleCopies);
|
||||
getRDFService()->GetResource(NC_RDF_PAGETITLE_ADVANCED, &kNC_PageTitleAdvanced);
|
||||
getRDFService()->GetResource(NC_RDF_PAGETITLE_SMTP, &kNC_PageTitleSMTP);
|
||||
|
||||
getRDFService()->GetResource(NC_RDF_ACCOUNTROOT, &kNC_AccountRoot);
|
||||
|
||||
// XXX This call should be moved to a NS_NewMsgFooDataSource()
|
||||
// method that the factory calls, so that failure to construct
|
||||
// will return an error code instead of returning a partially
|
||||
// initialized object.
|
||||
nsresult rv = Init();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "uh oh, initialization failed");
|
||||
if (NS_FAILED(rv)) return /* rv */;
|
||||
|
||||
return /* NS_OK */;
|
||||
getRDFService()->GetLiteral(NS_ConvertASCIItoUCS2("true").GetUnicode(),
|
||||
&kTrueLiteral);
|
||||
|
||||
// eventually these need to exist in some kind of array
|
||||
// that's easily extensible
|
||||
getRDFService()->GetResource(NC_RDF_SETTINGS, &kNC_Settings);
|
||||
|
||||
kDefaultServerAtom = NS_NewAtom("DefaultServer");
|
||||
}
|
||||
}
|
||||
|
||||
nsMsgAccountManagerDataSource::~nsMsgAccountManagerDataSource()
|
||||
@ -182,54 +201,32 @@ NS_INTERFACE_MAP_END_INHERITING(nsMsgRDFDataSource)
|
||||
nsresult
|
||||
nsMsgAccountManagerDataSource::Init()
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
|
||||
if (!mAccountManager) {
|
||||
nsCOMPtr<nsIMsgAccountManager> am =
|
||||
do_GetService(NS_MSGACCOUNTMANAGER_PROGID, &rv);
|
||||
nsresult rv;
|
||||
|
||||
mAccountManager = getter_AddRefs(NS_GetWeakReference(am));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = nsMsgRDFDataSource::Init();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIMsgAccountManager> am;
|
||||
|
||||
// get a weak ref to the account manager
|
||||
if (!mAccountManager) {
|
||||
am = do_GetService(NS_MSGACCOUNTMANAGER_PROGID, &rv);
|
||||
mAccountManager = getter_AddRefs(NS_GetWeakReference(am));
|
||||
} else
|
||||
am = do_QueryReferent(mAccountManager);
|
||||
|
||||
if (am) {
|
||||
am->AddIncomingServerListener(this);
|
||||
am->AddRootFolderListener(this);
|
||||
}
|
||||
|
||||
if (gAccountManagerResourceRefCnt++ == 0) {
|
||||
getRDFService()->GetResource(NC_RDF_CHILD, &kNC_Child);
|
||||
getRDFService()->GetResource(NC_RDF_NAME, &kNC_Name);
|
||||
getRDFService()->GetResource(NC_RDF_FOLDERTREENAME, &kNC_FolderTreeName);
|
||||
getRDFService()->GetResource(NC_RDF_NAME_SORT, &kNC_NameSort);
|
||||
getRDFService()->GetResource(NC_RDF_FOLDERTREENAME_SORT, &kNC_FolderTreeNameSort);
|
||||
getRDFService()->GetResource(NC_RDF_PAGETAG, &kNC_PageTag);
|
||||
getRDFService()->GetResource(NC_RDF_ISDEFAULTSERVER, &kNC_IsDefaultServer);
|
||||
getRDFService()->GetResource(NC_RDF_ACCOUNT, &kNC_Account);
|
||||
getRDFService()->GetResource(NC_RDF_SERVER, &kNC_Server);
|
||||
getRDFService()->GetResource(NC_RDF_IDENTITY, &kNC_Identity);
|
||||
getRDFService()->GetResource(NC_RDF_PAGETITLE_MAIN, &kNC_PageTitleMain);
|
||||
getRDFService()->GetResource(NC_RDF_PAGETITLE_SERVER, &kNC_PageTitleServer);
|
||||
getRDFService()->GetResource(NC_RDF_PAGETITLE_COPIES, &kNC_PageTitleCopies);
|
||||
getRDFService()->GetResource(NC_RDF_PAGETITLE_ADVANCED, &kNC_PageTitleAdvanced);
|
||||
getRDFService()->GetResource(NC_RDF_PAGETITLE_SMTP, &kNC_PageTitleSMTP);
|
||||
|
||||
getRDFService()->GetResource(NC_RDF_ACCOUNTROOT, &kNC_AccountRoot);
|
||||
|
||||
getRDFService()->GetLiteral(NS_ConvertASCIItoUCS2("true").GetUnicode(),
|
||||
&kTrueLiteral);
|
||||
|
||||
// eventually these need to exist in some kind of array
|
||||
// that's easily extensible
|
||||
getRDFService()->GetResource(NC_RDF_SETTINGS, &kNC_Settings);
|
||||
|
||||
|
||||
kDefaultServerAtom = NS_NewAtom("DefaultServer");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsMsgAccountManagerDataSource::Close()
|
||||
void nsMsgAccountManagerDataSource::Cleanup()
|
||||
{
|
||||
printf("*** AccountManager Datasource cleanup\n");
|
||||
nsCOMPtr<nsIMsgAccountManager> am =
|
||||
do_QueryReferent(mAccountManager);
|
||||
|
||||
@ -238,7 +235,7 @@ void nsMsgAccountManagerDataSource::Close()
|
||||
am->RemoveRootFolderListener(this);
|
||||
}
|
||||
|
||||
nsMsgRDFDataSource::Close();
|
||||
nsMsgRDFDataSource::Cleanup();
|
||||
}
|
||||
|
||||
/* nsIRDFNode GetTarget (in nsIRDFResource aSource, in nsIRDFResource property, in boolean aTruthValue); */
|
||||
|
||||
@ -50,7 +50,7 @@ public:
|
||||
virtual ~nsMsgAccountManagerDataSource();
|
||||
virtual nsresult Init();
|
||||
|
||||
virtual void Close();
|
||||
virtual void Cleanup();
|
||||
// service manager shutdown method
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
@ -98,21 +98,62 @@ nsIAtom * nsMsgFolderDataSource::kTotalMessagesAtom = nsnull;
|
||||
nsIAtom * nsMsgFolderDataSource::kTotalUnreadMessagesAtom = nsnull;
|
||||
nsIAtom * nsMsgFolderDataSource::kNameAtom = nsnull;
|
||||
|
||||
nsMsgFolderDataSource::nsMsgFolderDataSource():
|
||||
mInitialized(PR_FALSE)
|
||||
nsMsgFolderDataSource::nsMsgFolderDataSource()
|
||||
{
|
||||
// one-time initialization here
|
||||
nsIRDFService* rdf = getRDFService();
|
||||
|
||||
if (gFolderResourceRefCnt++ == 0) {
|
||||
rdf->GetResource(NC_RDF_CHILD, &kNC_Child);
|
||||
rdf->GetResource(NC_RDF_MESSAGECHILD, &kNC_MessageChild);
|
||||
rdf->GetResource(NC_RDF_FOLDER, &kNC_Folder);
|
||||
rdf->GetResource(NC_RDF_NAME, &kNC_Name);
|
||||
rdf->GetResource(NC_RDF_FOLDERTREENAME, &kNC_FolderTreeName);
|
||||
rdf->GetResource(NC_RDF_NAME_SORT, &kNC_NameSort);
|
||||
rdf->GetResource(NC_RDF_FOLDERTREENAME_SORT, &kNC_FolderTreeNameSort);
|
||||
rdf->GetResource(NC_RDF_SPECIALFOLDER, &kNC_SpecialFolder);
|
||||
rdf->GetResource(NC_RDF_SERVERTYPE, &kNC_ServerType);
|
||||
rdf->GetResource(NC_RDF_ISSERVER, &kNC_IsServer);
|
||||
rdf->GetResource(NC_RDF_ISSECURE, &kNC_IsSecure);
|
||||
rdf->GetResource(NC_RDF_CANSUBSCRIBE, &kNC_CanSubscribe);
|
||||
rdf->GetResource(NC_RDF_CANFILEMESSAGES, &kNC_CanFileMessages);
|
||||
rdf->GetResource(NC_RDF_CANCREATESUBFOLDERS, &kNC_CanCreateSubfolders);
|
||||
rdf->GetResource(NC_RDF_CANRENAME, &kNC_CanRename);
|
||||
rdf->GetResource(NC_RDF_TOTALMESSAGES, &kNC_TotalMessages);
|
||||
rdf->GetResource(NC_RDF_TOTALUNREADMESSAGES, &kNC_TotalUnreadMessages);
|
||||
rdf->GetResource(NC_RDF_CHARSET, &kNC_Charset);
|
||||
rdf->GetResource(NC_RDF_BIFFSTATE, &kNC_BiffState);
|
||||
rdf->GetResource(NC_RDF_HASUNREADMESSAGES, &kNC_HasUnreadMessages);
|
||||
rdf->GetResource(NC_RDF_NEWMESSAGES, &kNC_NewMessages);
|
||||
rdf->GetResource(NC_RDF_SUBFOLDERSHAVEUNREADMESSAGES, &kNC_SubfoldersHaveUnreadMessages);
|
||||
rdf->GetResource(NC_RDF_NOSELECT, &kNC_NoSelect);
|
||||
|
||||
rdf->GetResource(NC_RDF_DELETE, &kNC_Delete);
|
||||
rdf->GetResource(NC_RDF_REALLY_DELETE, &kNC_ReallyDelete);
|
||||
rdf->GetResource(NC_RDF_NEWFOLDER, &kNC_NewFolder);
|
||||
rdf->GetResource(NC_RDF_GETNEWMESSAGES, &kNC_GetNewMessages);
|
||||
rdf->GetResource(NC_RDF_COPY, &kNC_Copy);
|
||||
rdf->GetResource(NC_RDF_MOVE, &kNC_Move);
|
||||
rdf->GetResource(NC_RDF_MARKALLMESSAGESREAD,
|
||||
&kNC_MarkAllMessagesRead);
|
||||
rdf->GetResource(NC_RDF_COMPACT, &kNC_Compact);
|
||||
rdf->GetResource(NC_RDF_RENAME, &kNC_Rename);
|
||||
rdf->GetResource(NC_RDF_EMPTYTRASH, &kNC_EmptyTrash);
|
||||
|
||||
kTotalMessagesAtom = NS_NewAtom("TotalMessages");
|
||||
kTotalUnreadMessagesAtom = NS_NewAtom("TotalUnreadMessages");
|
||||
kBiffStateAtom = NS_NewAtom("BiffState");
|
||||
kNewMessagesAtom = NS_NewAtom("NewMessages");
|
||||
kNameAtom = NS_NewAtom("Name");
|
||||
}
|
||||
|
||||
CreateLiterals(rdf);
|
||||
CreateArcsOutEnumerator();
|
||||
}
|
||||
|
||||
nsMsgFolderDataSource::~nsMsgFolderDataSource (void)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!m_shuttingDown)
|
||||
{
|
||||
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
|
||||
if(NS_SUCCEEDED(rv))
|
||||
mailSession->RemoveFolderListener(this);
|
||||
}
|
||||
if (--gFolderResourceRefCnt == 0)
|
||||
{
|
||||
nsrefcnt refcnt;
|
||||
@ -154,99 +195,54 @@ nsMsgFolderDataSource::~nsMsgFolderDataSource (void)
|
||||
NS_RELEASE(kTotalMessagesAtom);
|
||||
NS_RELEASE(kTotalUnreadMessagesAtom);
|
||||
NS_RELEASE(kBiffStateAtom);
|
||||
NS_RELEASE(kNewMessagesAtom);
|
||||
NS_RELEASE(kNewMessagesAtom);
|
||||
NS_RELEASE(kNameAtom);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nsresult nsMsgFolderDataSource::CreateLiterals(nsIRDFService *rdf)
|
||||
{
|
||||
createNode((const PRUnichar*)NS_LITERAL_STRING("true"),
|
||||
getter_AddRefs(kTrueLiteral), rdf);
|
||||
createNode((const PRUnichar*)NS_LITERAL_STRING("false"),
|
||||
getter_AddRefs(kFalseLiteral), rdf);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgFolderDataSource::Init()
|
||||
{
|
||||
if (mInitialized)
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
rv = nsMsgRDFDataSource::Init();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
|
||||
if(NS_SUCCEEDED(rv))
|
||||
mailSession->AddFolderListener(this);
|
||||
|
||||
nsIRDFService *rdf = getRDFService();
|
||||
if(!rdf)
|
||||
return NS_ERROR_FAILURE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (gFolderResourceRefCnt++ == 0) {
|
||||
rdf->GetResource(NC_RDF_CHILD, &kNC_Child);
|
||||
rdf->GetResource(NC_RDF_MESSAGECHILD, &kNC_MessageChild);
|
||||
rdf->GetResource(NC_RDF_FOLDER, &kNC_Folder);
|
||||
rdf->GetResource(NC_RDF_NAME, &kNC_Name);
|
||||
rdf->GetResource(NC_RDF_FOLDERTREENAME, &kNC_FolderTreeName);
|
||||
rdf->GetResource(NC_RDF_NAME_SORT, &kNC_NameSort);
|
||||
rdf->GetResource(NC_RDF_FOLDERTREENAME_SORT, &kNC_FolderTreeNameSort);
|
||||
rdf->GetResource(NC_RDF_SPECIALFOLDER, &kNC_SpecialFolder);
|
||||
rdf->GetResource(NC_RDF_SERVERTYPE, &kNC_ServerType);
|
||||
rdf->GetResource(NC_RDF_ISSERVER, &kNC_IsServer);
|
||||
rdf->GetResource(NC_RDF_ISSECURE, &kNC_IsSecure);
|
||||
rdf->GetResource(NC_RDF_CANSUBSCRIBE, &kNC_CanSubscribe);
|
||||
rdf->GetResource(NC_RDF_CANFILEMESSAGES, &kNC_CanFileMessages);
|
||||
rdf->GetResource(NC_RDF_CANCREATESUBFOLDERS, &kNC_CanCreateSubfolders);
|
||||
rdf->GetResource(NC_RDF_CANRENAME, &kNC_CanRename);
|
||||
rdf->GetResource(NC_RDF_TOTALMESSAGES, &kNC_TotalMessages);
|
||||
rdf->GetResource(NC_RDF_TOTALUNREADMESSAGES, &kNC_TotalUnreadMessages);
|
||||
rdf->GetResource(NC_RDF_CHARSET, &kNC_Charset);
|
||||
rdf->GetResource(NC_RDF_BIFFSTATE, &kNC_BiffState);
|
||||
rdf->GetResource(NC_RDF_HASUNREADMESSAGES, &kNC_HasUnreadMessages);
|
||||
rdf->GetResource(NC_RDF_NEWMESSAGES, &kNC_NewMessages);
|
||||
rdf->GetResource(NC_RDF_SUBFOLDERSHAVEUNREADMESSAGES, &kNC_SubfoldersHaveUnreadMessages);
|
||||
rdf->GetResource(NC_RDF_NOSELECT, &kNC_NoSelect);
|
||||
void nsMsgFolderDataSource::Cleanup()
|
||||
{
|
||||
nsresult rv;
|
||||
if (!m_shuttingDown)
|
||||
{
|
||||
nsCOMPtr<nsIMsgMailSession> mailSession =
|
||||
do_GetService(kMsgMailSessionCID, &rv);
|
||||
|
||||
rdf->GetResource(NC_RDF_DELETE, &kNC_Delete);
|
||||
rdf->GetResource(NC_RDF_REALLY_DELETE, &kNC_ReallyDelete);
|
||||
rdf->GetResource(NC_RDF_NEWFOLDER, &kNC_NewFolder);
|
||||
rdf->GetResource(NC_RDF_GETNEWMESSAGES, &kNC_GetNewMessages);
|
||||
rdf->GetResource(NC_RDF_COPY, &kNC_Copy);
|
||||
rdf->GetResource(NC_RDF_MOVE, &kNC_Move);
|
||||
rdf->GetResource(NC_RDF_MARKALLMESSAGESREAD,
|
||||
&kNC_MarkAllMessagesRead);
|
||||
rdf->GetResource(NC_RDF_COMPACT, &kNC_Compact);
|
||||
rdf->GetResource(NC_RDF_RENAME, &kNC_Rename);
|
||||
rdf->GetResource(NC_RDF_EMPTYTRASH, &kNC_EmptyTrash);
|
||||
|
||||
kTotalMessagesAtom = NS_NewAtom("TotalMessages");
|
||||
kTotalUnreadMessagesAtom = NS_NewAtom("TotalUnreadMessages");
|
||||
kBiffStateAtom = NS_NewAtom("BiffState");
|
||||
kNewMessagesAtom = NS_NewAtom("NewMessages");
|
||||
kNameAtom = NS_NewAtom("Name");
|
||||
if(NS_SUCCEEDED(rv))
|
||||
mailSession->RemoveFolderListener(this);
|
||||
}
|
||||
CreateLiterals(rdf);
|
||||
rv = CreateArcsOutEnumerator();
|
||||
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
|
||||
mInitialized = PR_TRUE;
|
||||
return nsMsgRDFDataSource::Init();
|
||||
}
|
||||
|
||||
nsresult nsMsgFolderDataSource::CreateLiterals(nsIRDFService *rdf)
|
||||
{
|
||||
|
||||
nsAutoString str; str.AssignWithConversion("true");
|
||||
createNode(str, getter_AddRefs(kTrueLiteral), rdf);
|
||||
str.AssignWithConversion("false");
|
||||
createNode(str, getter_AddRefs(kFalseLiteral), rdf);
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
void nsMsgFolderDataSource::Close()
|
||||
{
|
||||
kFolderArcsOutArray = null_nsCOMPtr();
|
||||
nsMsgRDFDataSource::Close();
|
||||
|
||||
nsMsgRDFDataSource::Cleanup();
|
||||
}
|
||||
|
||||
nsresult nsMsgFolderDataSource::CreateArcsOutEnumerator()
|
||||
{
|
||||
nsCOMPtr<nsISupportsArray> folderArcsOut;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
rv = getFolderArcLabelsOut(getter_AddRefs(kFolderArcsOutArray));
|
||||
@ -503,14 +499,13 @@ NS_IMETHODIMP nsMsgFolderDataSource::ArcLabelsOut(nsIRDFResource* source,
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
arcsArray = kFolderArcsOutArray;
|
||||
|
||||
rv = NS_NewArrayEnumerator(labels, arcsArray);
|
||||
}
|
||||
else {
|
||||
arcsArray = kEmptyArray;
|
||||
rv = NS_NewEmptyEnumerator(labels);
|
||||
}
|
||||
rv = NS_NewArrayEnumerator(labels, arcsArray);
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
||||
@ -34,10 +34,6 @@
|
||||
class nsMsgFolderDataSource : public nsMsgRDFDataSource,
|
||||
public nsIFolderListener
|
||||
{
|
||||
private:
|
||||
PRBool mInitialized;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
@ -46,7 +42,7 @@ public:
|
||||
nsMsgFolderDataSource(void);
|
||||
virtual ~nsMsgFolderDataSource (void);
|
||||
virtual nsresult Init();
|
||||
virtual void Close();
|
||||
virtual void Cleanup();
|
||||
|
||||
// nsIRDFDataSource methods
|
||||
NS_IMETHOD GetURI(char* *uri);
|
||||
|
||||
@ -90,25 +90,58 @@ nsIAtom * nsMsgMessageDataSource::kStatusAtom = nsnull;
|
||||
|
||||
|
||||
|
||||
nsMsgMessageDataSource::nsMsgMessageDataSource():
|
||||
mInitialized(PR_FALSE),
|
||||
mHeaderParser(nsnull)
|
||||
nsMsgMessageDataSource::nsMsgMessageDataSource()
|
||||
{
|
||||
mStringBundle = nsnull;
|
||||
|
||||
mHeaderParser = do_CreateInstance(kMsgHeaderParserCID);
|
||||
nsIRDFService *rdf = getRDFService();
|
||||
|
||||
if (gMessageResourceRefCnt++ == 0) {
|
||||
|
||||
rdf->GetResource(NC_RDF_SUBJECT, &kNC_Subject);
|
||||
rdf->GetResource(NC_RDF_SUBJECT_COLLATION_SORT, &kNC_SubjectCollation);
|
||||
rdf->GetResource(NC_RDF_SENDER, &kNC_Sender);
|
||||
rdf->GetResource(NC_RDF_SENDER_COLLATION_SORT, &kNC_SenderCollation);
|
||||
rdf->GetResource(NC_RDF_RECIPIENT, &kNC_Recipient);
|
||||
rdf->GetResource(NC_RDF_RECIPIENT_COLLATION_SORT, &kNC_RecipientCollation);
|
||||
rdf->GetResource(NC_RDF_DATE, &kNC_Date);
|
||||
rdf->GetResource(NC_RDF_STATUS, &kNC_Status);
|
||||
rdf->GetResource(NC_RDF_STATUS_STRING, &kNC_StatusString);
|
||||
rdf->GetResource(NC_RDF_FLAGGED, &kNC_Flagged);
|
||||
rdf->GetResource(NC_RDF_PRIORITY, &kNC_Priority);
|
||||
rdf->GetResource(NC_RDF_PRIORITY_STRING, &kNC_PriorityString);
|
||||
rdf->GetResource(NC_RDF_PRIORITY_SORT, &kNC_PrioritySort);
|
||||
rdf->GetResource(NC_RDF_SIZE, &kNC_Size);
|
||||
rdf->GetResource(NC_RDF_SIZE_SORT, &kNC_SizeSort);
|
||||
rdf->GetResource(NC_RDF_TOTALMESSAGES, &kNC_Total);
|
||||
rdf->GetResource(NC_RDF_TOTALUNREADMESSAGES, &kNC_Unread);
|
||||
rdf->GetResource(NC_RDF_MESSAGECHILD, &kNC_MessageChild);
|
||||
rdf->GetResource(NC_RDF_ISUNREAD, &kNC_IsUnread);
|
||||
rdf->GetResource(NC_RDF_HASATTACHMENT, &kNC_HasAttachment);
|
||||
rdf->GetResource(NC_RDF_ISIMAPDELETED, &kNC_IsImapDeleted);
|
||||
rdf->GetResource(NC_RDF_MESSAGETYPE, &kNC_MessageType);
|
||||
rdf->GetResource(NC_RDF_ORDERRECEIVED, &kNC_OrderReceived);
|
||||
rdf->GetResource(NC_RDF_ORDERRECEIVED_SORT, &kNC_OrderReceivedSort);
|
||||
|
||||
rdf->GetResource(NC_RDF_MARKREAD, &kNC_MarkRead);
|
||||
rdf->GetResource(NC_RDF_MARKUNREAD, &kNC_MarkUnread);
|
||||
rdf->GetResource(NC_RDF_TOGGLEREAD, &kNC_ToggleRead);
|
||||
rdf->GetResource(NC_RDF_MARKFLAGGED, &kNC_MarkFlagged);
|
||||
rdf->GetResource(NC_RDF_MARKUNFLAGGED, &kNC_MarkUnflagged);
|
||||
rdf->GetResource(NC_RDF_MARKTHREADREAD, &kNC_MarkThreadRead);
|
||||
|
||||
kStatusAtom = NS_NewAtom("Status");
|
||||
kFlaggedAtom = NS_NewAtom("Flagged");
|
||||
}
|
||||
|
||||
CreateLiterals(rdf);
|
||||
CreateArcsOutEnumerators();
|
||||
}
|
||||
|
||||
nsMsgMessageDataSource::~nsMsgMessageDataSource (void)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!m_shuttingDown)
|
||||
{
|
||||
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
|
||||
|
||||
if(NS_SUCCEEDED(rv))
|
||||
mailSession->RemoveFolderListener(this);
|
||||
}
|
||||
if (--gMessageResourceRefCnt == 0)
|
||||
{
|
||||
nsrefcnt refcnt;
|
||||
@ -149,77 +182,35 @@ nsMsgMessageDataSource::~nsMsgMessageDataSource (void)
|
||||
NS_RELEASE(kFlaggedAtom);
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(mHeaderParser);
|
||||
}
|
||||
|
||||
void nsMsgMessageDataSource::Cleanup()
|
||||
{
|
||||
nsresult rv;
|
||||
if (!m_shuttingDown) {
|
||||
|
||||
nsCOMPtr<nsIMsgMailSession> mailSession =
|
||||
do_GetService(kMsgMailSessionCID, &rv);
|
||||
|
||||
if(NS_SUCCEEDED(rv))
|
||||
mailSession->RemoveFolderListener(this);
|
||||
}
|
||||
|
||||
nsMsgRDFDataSource::Cleanup();
|
||||
}
|
||||
|
||||
nsresult nsMsgMessageDataSource::Init()
|
||||
{
|
||||
if (mInitialized)
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
|
||||
|
||||
nsresult rv;
|
||||
nsIRDFService *rdf = getRDFService();
|
||||
if(!rdf)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv = nsMsgRDFDataSource::Init();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = nsComponentManager::CreateInstance(kMsgHeaderParserCID,
|
||||
NULL,
|
||||
NS_GET_IID(nsIMsgHeaderParser),
|
||||
(void **) &mHeaderParser);
|
||||
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
|
||||
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
|
||||
if(NS_SUCCEEDED(rv))
|
||||
mailSession->AddFolderListener(this);
|
||||
PR_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (gMessageResourceRefCnt++ == 0) {
|
||||
|
||||
rdf->GetResource(NC_RDF_SUBJECT, &kNC_Subject);
|
||||
rdf->GetResource(NC_RDF_SUBJECT_COLLATION_SORT, &kNC_SubjectCollation);
|
||||
rdf->GetResource(NC_RDF_SENDER, &kNC_Sender);
|
||||
rdf->GetResource(NC_RDF_SENDER_COLLATION_SORT, &kNC_SenderCollation);
|
||||
rdf->GetResource(NC_RDF_RECIPIENT, &kNC_Recipient);
|
||||
rdf->GetResource(NC_RDF_RECIPIENT_COLLATION_SORT, &kNC_RecipientCollation);
|
||||
rdf->GetResource(NC_RDF_DATE, &kNC_Date);
|
||||
rdf->GetResource(NC_RDF_STATUS, &kNC_Status);
|
||||
rdf->GetResource(NC_RDF_STATUS_STRING, &kNC_StatusString);
|
||||
rdf->GetResource(NC_RDF_FLAGGED, &kNC_Flagged);
|
||||
rdf->GetResource(NC_RDF_PRIORITY, &kNC_Priority);
|
||||
rdf->GetResource(NC_RDF_PRIORITY_STRING, &kNC_PriorityString);
|
||||
rdf->GetResource(NC_RDF_PRIORITY_SORT, &kNC_PrioritySort);
|
||||
rdf->GetResource(NC_RDF_SIZE, &kNC_Size);
|
||||
rdf->GetResource(NC_RDF_SIZE_SORT, &kNC_SizeSort);
|
||||
rdf->GetResource(NC_RDF_TOTALMESSAGES, &kNC_Total);
|
||||
rdf->GetResource(NC_RDF_TOTALUNREADMESSAGES, &kNC_Unread);
|
||||
rdf->GetResource(NC_RDF_MESSAGECHILD, &kNC_MessageChild);
|
||||
rdf->GetResource(NC_RDF_ISUNREAD, &kNC_IsUnread);
|
||||
rdf->GetResource(NC_RDF_HASATTACHMENT, &kNC_HasAttachment);
|
||||
rdf->GetResource(NC_RDF_ISIMAPDELETED, &kNC_IsImapDeleted);
|
||||
rdf->GetResource(NC_RDF_MESSAGETYPE, &kNC_MessageType);
|
||||
rdf->GetResource(NC_RDF_ORDERRECEIVED, &kNC_OrderReceived);
|
||||
rdf->GetResource(NC_RDF_ORDERRECEIVED_SORT, &kNC_OrderReceivedSort);
|
||||
|
||||
rdf->GetResource(NC_RDF_MARKREAD, &kNC_MarkRead);
|
||||
rdf->GetResource(NC_RDF_MARKUNREAD, &kNC_MarkUnread);
|
||||
rdf->GetResource(NC_RDF_TOGGLEREAD, &kNC_ToggleRead);
|
||||
rdf->GetResource(NC_RDF_MARKFLAGGED, &kNC_MarkFlagged);
|
||||
rdf->GetResource(NC_RDF_MARKUNFLAGGED, &kNC_MarkUnflagged);
|
||||
rdf->GetResource(NC_RDF_MARKTHREADREAD, &kNC_MarkThreadRead);
|
||||
|
||||
kStatusAtom = NS_NewAtom("Status");
|
||||
kFlaggedAtom = NS_NewAtom("Flagged");
|
||||
}
|
||||
|
||||
CreateLiterals(rdf);
|
||||
rv = CreateArcsOutEnumerators();
|
||||
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
|
||||
mInitialized = PR_TRUE;
|
||||
return nsMsgRDFDataSource::Init();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgMessageDataSource::CreateLiterals(nsIRDFService *rdf)
|
||||
@ -569,13 +560,13 @@ NS_IMETHODIMP nsMsgMessageDataSource::ArcLabelsOut(nsIRDFResource* source,
|
||||
{
|
||||
arcsArray = kNoThreadsArcsOutArray;
|
||||
}
|
||||
rv = NS_NewArrayEnumerator(labels, arcsArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
arcsArray = kEmptyArray;
|
||||
rv = NS_NewEmptyEnumerator(labels);
|
||||
}
|
||||
|
||||
rv = NS_NewArrayEnumerator(labels, arcsArray);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
||||
@ -45,7 +45,7 @@ private:
|
||||
PRBool mInitialized;
|
||||
|
||||
// The cached service managers
|
||||
nsIMsgHeaderParser *mHeaderParser;
|
||||
nsCOMPtr<nsIMsgHeaderParser> mHeaderParser;
|
||||
|
||||
public:
|
||||
|
||||
@ -216,6 +216,8 @@ protected:
|
||||
nsresult GetUnreadChildrenNode(nsIMsgThread *thread, nsIRDFNode **target);
|
||||
nsresult GetTotalChildrenNode(nsIMsgThread *thread, nsIRDFNode **target);
|
||||
|
||||
virtual void Cleanup();
|
||||
|
||||
static nsIRDFResource* kNC_Subject;
|
||||
static nsIRDFResource* kNC_SubjectCollation;
|
||||
static nsIRDFResource* kNC_Sender;
|
||||
|
||||
@ -32,47 +32,68 @@
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
|
||||
nsMsgRDFDataSource::nsMsgRDFDataSource():
|
||||
mInitialized(PR_FALSE),
|
||||
m_shuttingDown(PR_FALSE),
|
||||
mRDFService(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
m_shuttingDown = PR_FALSE;
|
||||
|
||||
// do one-time initialization here
|
||||
|
||||
NS_NewISupportsArray(getter_AddRefs(mObservers));
|
||||
}
|
||||
|
||||
nsMsgRDFDataSource::~nsMsgRDFDataSource()
|
||||
{
|
||||
// final shutdown happens here
|
||||
NS_ASSERTION(!mInitialized, "Object going away without cleanup, possibly dangerous!");
|
||||
if (mInitialized) Cleanup();
|
||||
}
|
||||
|
||||
/* void Init (); */
|
||||
/* initialization happens here - object is constructed,
|
||||
but possibly partially shut down
|
||||
*/
|
||||
nsresult
|
||||
nsMsgRDFDataSource::Init()
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
|
||||
if (mInitialized)
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
|
||||
/* Add an observer to XPCOM shutdown */
|
||||
nsCOMPtr<nsIObserverService> obs = do_GetService(NS_OBSERVERSERVICE_PROGID,
|
||||
&rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsAutoString topic; topic.AssignWithConversion(NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
nsAutoString topic = NS_LITERAL_STRING(NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
rv = obs->AddObserver(NS_STATIC_CAST(nsIObserver*, this), topic.GetUnicode());
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
/* Get and keep the rdf service. Will be released by the observer */
|
||||
getRDFService();
|
||||
|
||||
//Create Empty Enumerator
|
||||
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(kEmptyArray));
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
mInitialized=PR_TRUE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
void nsMsgRDFDataSource::Close()
|
||||
// clean yourself up - undo anything you did in Init()
|
||||
void nsMsgRDFDataSource::Cleanup()
|
||||
{
|
||||
mWindow = null_nsCOMPtr();
|
||||
kEmptyArray = null_nsCOMPtr();
|
||||
nsresult rv;
|
||||
mRDFService = nsnull;
|
||||
|
||||
// release ourselves from the observer service
|
||||
nsCOMPtr<nsIObserverService> obs = do_GetService(NS_OBSERVERSERVICE_PROGID,
|
||||
&rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = obs->RemoveObserver(NS_STATIC_CAST(nsIObserver*, this),
|
||||
(const PRUnichar*)NS_LITERAL_STRING(NS_XPCOM_SHUTDOWN_OBSERVER_ID));
|
||||
}
|
||||
|
||||
// release the window
|
||||
mWindow = nsnull;
|
||||
|
||||
mInitialized = PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsMsgRDFDataSource)
|
||||
@ -176,15 +197,15 @@ nsMsgRDFDataSource::HasAssertion(nsIRDFResource *aSource, nsIRDFResource *aPrope
|
||||
NS_IMETHODIMP
|
||||
nsMsgRDFDataSource::AddObserver(nsIRDFObserver *aObserver)
|
||||
{
|
||||
if (! mObservers) {
|
||||
nsresult rv;
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(mObservers));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
NS_ASSERTION(mObservers->IndexOf(aObserver) == -1, "better not already be observing this");
|
||||
// make sure we're initialized
|
||||
if (!mInitialized)
|
||||
Init();
|
||||
|
||||
NS_ASSERTION(mObservers->IndexOf(aObserver) == -1,
|
||||
"better not already be observing this");
|
||||
|
||||
mObservers->AppendElement(aObserver);
|
||||
return NS_OK;
|
||||
mObservers->AppendElement(aObserver);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -195,6 +216,14 @@ nsMsgRDFDataSource::RemoveObserver(nsIRDFObserver *aObserver)
|
||||
if (! mObservers)
|
||||
return NS_OK;
|
||||
mObservers->RemoveElement(aObserver);
|
||||
|
||||
// when we hit 0 observers, then it's probably time
|
||||
// to go away - clean ourselves up now
|
||||
PRUint32 count;
|
||||
mObservers->Count(&count);
|
||||
if (count == 0)
|
||||
Cleanup();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -280,9 +309,8 @@ nsMsgRDFDataSource::DoCommand(nsISupportsArray *aSources, nsIRDFResource *aComma
|
||||
NS_IMETHODIMP
|
||||
nsMsgRDFDataSource::Observe(nsISupports *aSubject, const PRUnichar *aTopic, const PRUnichar *someData )
|
||||
{
|
||||
mRDFService = nsnull;
|
||||
m_shuttingDown = PR_TRUE;
|
||||
Close();
|
||||
Cleanup();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -50,7 +50,9 @@ class nsMsgRDFDataSource : public nsIRDFDataSource,
|
||||
NS_DECL_NSIRDFDATASOURCE
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
virtual void Close();
|
||||
// called to reset the datasource to an empty state
|
||||
// if you need to release yourself as an observer/listener, do it here
|
||||
virtual void Cleanup();
|
||||
|
||||
protected:
|
||||
nsIRDFService *getRDFService();
|
||||
@ -69,8 +71,8 @@ class nsMsgRDFDataSource : public nsIRDFDataSource,
|
||||
|
||||
nsCOMPtr<nsIMsgWindow> mWindow;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> kEmptyArray;
|
||||
PRBool m_shuttingDown;
|
||||
PRBool mInitialized;
|
||||
nsresult GetIsThreaded(PRBool *threaded);
|
||||
nsresult GetViewType(PRUint32 *viewType);
|
||||
nsresult GetMessageView(nsIMessageView **messageView);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user