91731 r=bienvenu sr=mscott; Obtain the folder lock for compacting folders and for getiing pop3 messages

so that the operations do not write each other's data, only one operation should be able to write to
the folder at one time.
This commit is contained in:
naving%netscape.com 2001-08-01 05:31:31 +00:00
Родитель 4cc8c3da8d
Коммит 53ac08f6a9
8 изменённых файлов: 81 добавлений и 18 удалений

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

@ -291,6 +291,12 @@ void nsFolderCompactState::ShowCompactingStatusMsg()
NS_IMETHODIMP nsFolderCompactState::StartCompacting()
{
nsresult rv = NS_OK;
PRBool isLocked;
m_folder->GetLocked(&isLocked);
if(!isLocked)
m_folder->AcquireSemaphore(m_folder);
else
FinishCompact();
if (m_size > 0)
{
ShowCompactingStatusMsg();
@ -354,6 +360,9 @@ nsFolderCompactState::FinishCompact()
// database
m_fileSpec.Rename((const char*) idlName);
newSummarySpec.Rename(dbName);
rv = ReleaseFolderLock();
NS_ASSERTION(NS_SUCCEEDED(rv),"folder lock not released successfully");
// Make the front end reload the folder. Calling GetMsgDatabase on a folder whose
// db isn't open will cause the folder to open the db and
@ -363,10 +372,22 @@ nsFolderCompactState::FinishCompact()
db = nsnull;
if (m_compactAll)
rv = CompactNextFolder();
return rv;
}
nsresult
nsFolderCompactState::ReleaseFolderLock()
{
nsresult result = NS_OK;
if (!m_folder) return result;
PRBool haveSemaphore;
result = m_folder->TestSemaphore(m_folder, &haveSemaphore);
if(NS_SUCCEEDED(result) && haveSemaphore)
result = m_folder->ReleaseSemaphore(m_folder);
return result;
}
nsresult
nsFolderCompactState::CompactNextFolder()
{
@ -386,6 +407,7 @@ nsFolderCompactState::CompactNextFolder()
}
else
return rv;
}
nsCOMPtr<nsISupports> supports = getter_AddRefs(m_folderArray->ElementAt(m_folderIndex));
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports, &rv);
@ -436,6 +458,7 @@ nsFolderCompactState::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
if (NS_SUCCEEDED(status))
{
CleanupTempFilesAfterError();
ReleaseFolderLock();
Release();
}
}
@ -444,6 +467,7 @@ done:
if (NS_FAILED(rv)) {
m_status = rv; // set the status to rv so the destructor can remove the
// temp folder and database
ReleaseFolderLock();
Release(); // kill self
return rv;
}

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

@ -55,6 +55,7 @@ public:
nsresult BuildMessageURI(const char *baseURI, PRUint32 key, nsCString& uri);
nsresult GetStatusFromMsgName(const char *statusMsgName, PRUnichar ** retval);
nsresult ShowStatusMsg(const PRUnichar *aMsg);
nsresult ReleaseFolderLock();
void ShowCompactingStatusMsg();
nsresult CompactNextFolder();

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

@ -69,6 +69,11 @@
## @loc None
4006=Unable to write the email to the mailbox. Make sure the file system allows you write privileges, and you have enough disk space to copy the mailbox.
# Status - write error occurred
## @name POP3_MESSAGE_FOLDER_BUSY
## @loc None
4029=This folder is being processed. Please wait until processing is complete to get messages.
# Status - connecting to host
## @name POP3_CONNECT_HOST_CONTACTED_SENDING_LOGIN_INFORMATION
## @loc None
@ -187,3 +192,4 @@
## @name MOVING_MSGS_STATUS
## @loc None
4028=Moving %S of %S messages to %S

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

@ -71,5 +71,6 @@ private:
#define DELETING_MSGS_STATUS 4026
#define COPYING_MSGS_STATUS 4027
#define MOVING_MSGS_STATUS 4028
#define POP3_MESSAGE_FOLDER_BUSY 4029
#endif /* _nsImapStringBundle_H__ */

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

@ -539,7 +539,7 @@ PRInt32 nsMailboxProtocol::ReadMessageResponse(nsIInputStream * inputStream, PRU
if (m_channelListener)
{
// just forward the data we read in to the listener...
m_channelListener->OnDataAvailable(this, m_channelContext, inputStream, sourceOffset, length);
rv = m_channelListener->OnDataAvailable(this, m_channelContext, inputStream, sourceOffset, length);
}
else
{

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

@ -1168,10 +1168,14 @@ nsPop3Protocol::GetStat()
// write to somewhere we dont have write access error to (See bug 62480)
// (Note: This is only a temp hack until the underlying XPCOM is fixed
// to return errors)
if(NS_FAILED(m_nsIPop3Sink->BeginMailDelivery(m_pop3ConData->only_uidl != nsnull,
&m_pop3ConData->msg_del_started)))
nsresult rv;
rv = m_nsIPop3Sink->BeginMailDelivery(m_pop3ConData->only_uidl != nsnull,
&m_pop3ConData->msg_del_started);
if (NS_FAILED(rv))
if (rv == NS_MSG_FOLDER_BUSY)
return(Error(POP3_MESSAGE_FOLDER_BUSY));
else
return(Error(POP3_MESSAGE_WRITE_ERROR));
if(!m_pop3ConData->msg_del_started)
{
return(Error(POP3_MESSAGE_WRITE_ERROR));

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

@ -141,6 +141,15 @@ nsPop3Sink::BeginMailDelivery(PRBool uidlDownload, PRBool* aBool)
nsFileSpec fileSpec;
// ### if we're doing a UIDL, then the fileSpec needs to be for the current folder
PRBool isLocked;
m_folder->GetLocked(&isLocked);
if(!isLocked)
m_folder->AcquireSemaphore(m_folder);
else
return NS_MSG_FOLDER_BUSY;
if (uidlDownload)
{
nsCOMPtr<nsIFileSpec> path;
@ -202,20 +211,23 @@ nsPop3Sink::BeginMailDelivery(PRBool uidlDownload, PRBool* aBool)
nsresult
nsPop3Sink::EndMailDelivery()
{
if (m_newMailParser)
{
if (m_outFileStream)
m_outFileStream->flush(); // try this.
m_newMailParser->OnStopRequest(nsnull, nsnull, NS_OK);
delete m_newMailParser;
m_newMailParser = NULL;
}
if (m_newMailParser)
{
if (m_outFileStream)
{
m_outFileStream->close();
delete m_outFileStream;
m_outFileStream = 0;
}
m_outFileStream->flush(); // try this.
m_newMailParser->OnStopRequest(nsnull, nsnull, NS_OK);
delete m_newMailParser;
m_newMailParser = NULL;
}
if (m_outFileStream)
{
m_outFileStream->close();
delete m_outFileStream;
m_outFileStream = 0;
}
nsresult rv = ReleaseFolderLock();
NS_ASSERTION(NS_SUCCEEDED(rv),"folder lock not released successfully");
#ifdef DEBUG
printf("End mail message delivery.\n");
@ -223,6 +235,18 @@ nsPop3Sink::EndMailDelivery()
return NS_OK;
}
nsresult
nsPop3Sink::ReleaseFolderLock()
{
nsresult result = NS_OK;
if (!m_folder) return result;
PRBool haveSemaphore;
result = m_folder->TestSemaphore(m_folder, &haveSemaphore);
if(NS_SUCCEEDED(result) && haveSemaphore)
result = m_folder->ReleaseSemaphore(m_folder);
return result;
}
nsresult
nsPop3Sink::AbortMailDelivery()
{
@ -233,6 +257,8 @@ nsPop3Sink::AbortMailDelivery()
delete m_outFileStream;
m_outFileStream = 0;
}
nsresult rv = ReleaseFolderLock();
NS_ASSERTION(NS_SUCCEEDED(rv),"folder lock not released successfully");
#ifdef DEBUG
printf("Abort mail message delivery.\n");
#endif

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

@ -52,6 +52,7 @@ public:
protected:
nsresult WriteLineToMailbox(char *buffer);
nsresult ReleaseFolderLock();
PRBool m_authed;
PRInt32 m_msgOffset;