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:
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -109,6 +109,7 @@ protected:
|
||||
// file transport thread:
|
||||
RunState mRunState;
|
||||
nsresult mCancelStatus;
|
||||
PRMonitor* mMonitor;
|
||||
|
||||
// state variables:
|
||||
nsresult mStatus;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -51,8 +51,6 @@ public:
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIThreadPool> mPool;
|
||||
nsCOMPtr<nsISupportsArray> mOpened;
|
||||
nsCOMPtr<nsISupportsArray> mSuspended;
|
||||
};
|
||||
|
||||
#endif /* nsFileTransportService_h___ */
|
||||
|
||||
Reference in New Issue
Block a user