Bug 44342 - hang on startup. Added back a lock to mutually exclude cancel/suspend/resume. Seems to work on Mac (i.e. can't reproduce the problem now). Also cleaned up file transport service, removing unused stuff.

git-svn-id: svn://10.0.0.236/trunk@73983 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
warren%netscape.com
2000-07-11 01:52:12 +00:00
parent f98b2a3b00
commit 43db39eeb6
5 changed files with 22 additions and 61 deletions

View File

@@ -49,8 +49,6 @@ interface nsIFileTransportService : nsISupports
nsIChannel createTransportFromStreamIO(in nsIStreamIO io);
void dispatchRequest(in nsIRunnable runnable);
void suspend(in nsIRunnable trans);
void resume(in nsIRunnable trans);
void processPendingRequests();
void shutdown();

View File

@@ -60,6 +60,7 @@ nsFileTransport::nsFileTransport()
mXferState(CLOSED),
mRunState(RUNNING),
mCancelStatus(NS_OK),
mMonitor(nsnull),
mStatus(NS_OK),
mLoadAttributes(LOAD_NORMAL),
mOffset(0),
@@ -108,6 +109,11 @@ nsresult
nsFileTransport::Init(nsFileTransportService *aService, nsIStreamIO* io)
{
nsresult rv = NS_OK;
if (mMonitor == nsnull) {
mMonitor = nsAutoMonitor::NewMonitor("nsFileTransport");
if (mMonitor == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
}
mStreamIO = io;
nsXPIDLCString name;
rv = mStreamIO->GetName(getter_Copies(name));
@@ -115,8 +121,7 @@ nsFileTransport::Init(nsFileTransportService *aService, nsIStreamIO* io)
NS_ASSERTION(NS_SUCCEEDED(rv), "GetName failed");
mService = aService;
if (mService)
PR_AtomicIncrement(&mService->mTotalTransports);
PR_AtomicIncrement(&mService->mTotalTransports);
return rv;
}
@@ -131,11 +136,12 @@ nsFileTransport::~nsFileTransport()
NS_ASSERTION(mBufferOutputStream == nsnull, "transport not closed");
NS_ASSERTION(mSink == nsnull, "transport not closed");
NS_ASSERTION(mBuffer == nsnull, "transport not closed");
if (mMonitor)
nsAutoMonitor::DestroyMonitor(mMonitor);
if (mContentType)
nsCRT::free(mContentType);
if (mService)
PR_AtomicDecrement(&mService->mTotalTransports);
PR_AtomicDecrement(&mService->mTotalTransports);
}
@@ -178,6 +184,7 @@ nsFileTransport::GetStatus(nsresult *status)
NS_IMETHODIMP
nsFileTransport::Cancel(nsresult status)
{
nsAutoMonitor mon(mMonitor);
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
nsresult rv = NS_OK;
@@ -198,12 +205,10 @@ nsFileTransport::Cancel(nsresult status)
NS_IMETHODIMP
nsFileTransport::Suspend()
{
nsAutoMonitor mon(mMonitor);
nsresult rv = NS_OK;
if (mRunState != SUSPENDED) {
// XXX close the stream here?
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
mStatus = fts->Suspend(this);
mRunState = SUSPENDED;
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
("nsFileTransport: Suspend [this=%x %s]",
@@ -215,13 +220,12 @@ nsFileTransport::Suspend()
NS_IMETHODIMP
nsFileTransport::Resume()
{
nsAutoMonitor mon(mMonitor);
nsresult rv = NS_OK;
if (mRunState == SUSPENDED) {
// XXX re-open the stream and seek here?
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
mRunState = RUNNING; // set this first before resuming!
mStatus = fts->Resume(this);
mStatus = mService->DispatchRequest(this);
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
("nsFileTransport: Resume [this=%x %s] status=%x",
this, mStreamName.GetBuffer(), mStatus));
@@ -290,9 +294,7 @@ nsFileTransport::AsyncRead(nsIStreamListener *listener, nsISupports *ctxt)
("nsFileTransport: AsyncRead [this=%x %s] mOffset=%d mTransferAmount=%d",
this, mStreamName.GetBuffer(), mOffset, mTransferAmount));
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = fts->DispatchRequest(this);
rv = mService->DispatchRequest(this);
if (NS_FAILED(rv)) return rv;
return NS_OK;
@@ -323,9 +325,7 @@ nsFileTransport::AsyncWrite(nsIInputStream *fromStream,
("nsFileTransport: AsyncWrite [this=%x %s]",
this, mStreamName.GetBuffer()));
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = fts->DispatchRequest(this);
rv = mService->DispatchRequest(this);
if (NS_FAILED(rv)) return rv;
return NS_OK;
@@ -391,8 +391,7 @@ nsFileTransport::Process(void)
("nsFileTransport: START_READ [this=%x %s]",
this, mStreamName.GetBuffer()));
if (mService)
PR_AtomicIncrement(&mService->mInUseTransports);
PR_AtomicIncrement(&mService->mInUseTransports);
mStatus = mStreamIO->GetInputStream(getter_AddRefs(mSource));
if (NS_FAILED(mStatus)) {
@@ -485,8 +484,7 @@ nsFileTransport::Process(void)
case END_READ: {
if (mService)
PR_AtomicDecrement(&mService->mInUseTransports);
PR_AtomicDecrement(&mService->mInUseTransports);
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
("nsFileTransport: END_READ [this=%x %s] status=%x",
@@ -546,8 +544,7 @@ nsFileTransport::Process(void)
("nsFileTransport: START_WRITE [this=%x %s]",
this, mStreamName.GetBuffer()));
if (mService)
PR_AtomicIncrement(&mService->mInUseTransports);
PR_AtomicIncrement(&mService->mInUseTransports);
mStatus = mStreamIO->GetOutputStream(getter_AddRefs(mSink));
if (NS_FAILED(mStatus)) {
@@ -642,8 +639,7 @@ nsFileTransport::Process(void)
("nsFileTransport: END_WRITE [this=%x %s] status=%x",
this, mStreamName.GetBuffer(), mStatus));
if (mService)
PR_AtomicDecrement(&mService->mInUseTransports);
PR_AtomicDecrement(&mService->mInUseTransports);
#if defined (DEBUG_dougt) || defined (DEBUG_warren)
NS_ASSERTION(mTransferAmount <= 0 || NS_FAILED(mStatus), "didn't transfer all the data");
@@ -714,8 +710,7 @@ nsFileTransport::DoClose(void)
}
mXferState = CLOSED;
if (mService)
PR_AtomicDecrement(&mService->mConnectedTransports);
PR_AtomicDecrement(&mService->mConnectedTransports);
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -109,6 +109,7 @@ protected:
// file transport thread:
RunState mRunState;
nsresult mCancelStatus;
PRMonitor* mMonitor;
// state variables:
nsresult mStatus;

View File

@@ -163,37 +163,6 @@ nsFileTransportService::DispatchRequest(nsIRunnable* runnable)
////////////////////////////////////////////////////////////////////////////////
nsresult
nsFileTransportService::Suspend(nsIRunnable* request)
{
nsresult rv;
nsAutoCMonitor mon(this); // protect mSuspended
if (mSuspended == nsnull) {
rv = NS_NewISupportsArray(getter_AddRefs(mSuspended));
if (NS_FAILED(rv)) return rv;
}
return mSuspended->AppendElement(request) ? NS_OK : NS_ERROR_FAILURE; // XXX this method incorrectly returns a bool
}
nsresult
nsFileTransportService::Resume(nsIRunnable* request)
{
nsresult rv;
nsAutoCMonitor mon(this); // protect mSuspended
if (mSuspended == nsnull)
return NS_ERROR_FAILURE;
// XXX RemoveElement returns a bool instead of nsresult!
PRBool removed = mSuspended->RemoveElement(request);
rv = removed ? NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
// restart the request
rv = mPool->DispatchRequest(request);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsFileTransportService::GetTotalTransportCount (PRUint32 * o_TransCount)
{

View File

@@ -51,8 +51,6 @@ public:
protected:
nsCOMPtr<nsIThreadPool> mPool;
nsCOMPtr<nsISupportsArray> mOpened;
nsCOMPtr<nsISupportsArray> mSuspended;
};
#endif /* nsFileTransportService_h___ */