зеркало из https://github.com/mozilla/pjs.git
Fixed some file channel problems. Works better now. Upped buffer size to avoid buffer full problems.
This commit is contained in:
Родитель
7c731d4888
Коммит
4cc4f7d94f
|
@ -25,7 +25,6 @@
|
||||||
#include "nsIIOService.h"
|
#include "nsIIOService.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
#include "nsFileProtocolHandler.h"
|
#include "nsFileProtocolHandler.h"
|
||||||
#include "nsIBuffer.h"
|
|
||||||
#include "nsIBufferInputStream.h"
|
#include "nsIBufferInputStream.h"
|
||||||
#include "nsIBufferOutputStream.h"
|
#include "nsIBufferOutputStream.h"
|
||||||
#include "nsAutoLock.h"
|
#include "nsAutoLock.h"
|
||||||
|
@ -69,8 +68,8 @@ nsFileChannel::Init(nsFileProtocolHandler* handler,
|
||||||
mGetter = getter;
|
mGetter = getter;
|
||||||
NS_IF_ADDREF(mGetter);
|
NS_IF_ADDREF(mGetter);
|
||||||
|
|
||||||
mLock = PR_NewLock();
|
mMonitor = PR_NewMonitor();
|
||||||
if (mLock == nsnull)
|
if (mMonitor == nsnull)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
if (getter) {
|
if (getter) {
|
||||||
|
@ -106,8 +105,8 @@ nsFileChannel::~nsFileChannel()
|
||||||
NS_ASSERTION(mFileStream == nsnull, "channel not closed");
|
NS_ASSERTION(mFileStream == nsnull, "channel not closed");
|
||||||
NS_ASSERTION(mBufferInputStream == nsnull, "channel not closed");
|
NS_ASSERTION(mBufferInputStream == nsnull, "channel not closed");
|
||||||
NS_ASSERTION(mBufferOutputStream == nsnull, "channel not closed");
|
NS_ASSERTION(mBufferOutputStream == nsnull, "channel not closed");
|
||||||
if (mLock)
|
if (mMonitor)
|
||||||
PR_DestroyLock(mLock);
|
PR_DestroyMonitor(mMonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -153,7 +152,7 @@ nsFileChannel::IsPending(PRBool *result)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFileChannel::Cancel()
|
nsFileChannel::Cancel()
|
||||||
{
|
{
|
||||||
nsAutoLock lock(mLock);
|
nsAutoMonitor mon(mMonitor);
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
mStatus = NS_BINDING_ABORTED;
|
mStatus = NS_BINDING_ABORTED;
|
||||||
|
@ -167,7 +166,7 @@ nsFileChannel::Cancel()
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFileChannel::Suspend()
|
nsFileChannel::Suspend()
|
||||||
{
|
{
|
||||||
nsAutoLock lock(mLock);
|
nsAutoMonitor mon(mMonitor);
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
if (!mSuspended) {
|
if (!mSuspended) {
|
||||||
|
@ -181,7 +180,7 @@ nsFileChannel::Suspend()
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFileChannel::Resume()
|
nsFileChannel::Resume()
|
||||||
{
|
{
|
||||||
nsAutoLock lock(mLock);
|
nsAutoMonitor mon(mMonitor);
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
if (!mSuspended) {
|
if (!mSuspended) {
|
||||||
|
@ -193,7 +192,7 @@ nsFileChannel::Resume()
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if 0
|
||||||
class nsAsyncOutputStream : public nsIBufferOutputStream {
|
class nsAsyncOutputStream : public nsIBufferOutputStream {
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
@ -216,7 +215,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD Flush() {
|
NS_IMETHOD Flush() {
|
||||||
return mOutputStream->Flush();
|
nsresult rv;
|
||||||
|
rv = mOutputStream->Flush();
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
rv = mListener->OnStopRequest(mChannel, mContext, /*mStatus*/rv, nsnull);
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsIBufferOutputStream methods:
|
// nsIBufferOutputStream methods:
|
||||||
|
@ -234,6 +237,14 @@ public:
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHOD GetNonBlocking(PRBool *aNonBlocking) {
|
||||||
|
return mOutputStream->GetNonBlocking(aNonBlocking);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHOD SetNonBlocking(PRBool aNonBlocking) {
|
||||||
|
return mOutputStream->SetNonBlocking(aNonBlocking);
|
||||||
|
}
|
||||||
|
|
||||||
nsAsyncOutputStream()
|
nsAsyncOutputStream()
|
||||||
: mContext(nsnull), mListener(nsnull), mInputStream(nsnull),
|
: mContext(nsnull), mListener(nsnull), mInputStream(nsnull),
|
||||||
mOutputStream(nsnull), mOffset(0)
|
mOutputStream(nsnull), mOffset(0)
|
||||||
|
@ -295,7 +306,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(nsAsyncOutputStream, nsCOMTypeInfo<nsIBufferOutputStream>::GetIID());
|
NS_IMPL_ISUPPORTS(nsAsyncOutputStream, nsCOMTypeInfo<nsIBufferOutputStream>::GetIID());
|
||||||
|
#endif
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// From nsIChannel
|
// From nsIChannel
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -312,20 +323,26 @@ NS_IMETHODIMP
|
||||||
nsFileChannel::OpenInputStream(PRUint32 startPosition, PRInt32 readCount,
|
nsFileChannel::OpenInputStream(PRUint32 startPosition, PRInt32 readCount,
|
||||||
nsIInputStream **result)
|
nsIInputStream **result)
|
||||||
{
|
{
|
||||||
nsAutoLock lock(mLock);
|
nsAutoMonitor mon(mMonitor);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
if (mState != QUIESCENT)
|
if (mState != QUIESCENT)
|
||||||
return NS_ERROR_IN_PROGRESS;
|
return NS_ERROR_IN_PROGRESS;
|
||||||
|
|
||||||
|
rv = NS_NewPipe(&mBufferInputStream, &mBufferOutputStream,
|
||||||
|
NS_FILE_TRANSPORT_SEGMENT_SIZE,
|
||||||
|
NS_FILE_TRANSPORT_BUFFER_SIZE, PR_TRUE, this);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
#if 0
|
||||||
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
|
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = NS_NewPipe(&mBufferInputStream, &mBufferOutputStream,
|
rv = serv->NewSyncStreamListener(&mBufferInputStream, &mBufferOutputStream, &mListener);
|
||||||
NS_FILE_TRANSPORT_SEGMENT_SIZE,
|
if (NS_FAILED(rv)) return rv;
|
||||||
NS_FILE_TRANSPORT_BUFFER_SIZE, PR_TRUE, nsnull);
|
#endif
|
||||||
// rv = serv->NewSyncStreamListener(&mBufferInputStream, &mBufferOutputStream, &mListener);
|
|
||||||
|
rv = mBufferOutputStream->SetNonBlocking(PR_TRUE);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
mState = START_READ;
|
mState = START_READ;
|
||||||
|
@ -344,7 +361,7 @@ nsFileChannel::OpenInputStream(PRUint32 startPosition, PRInt32 readCount,
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFileChannel::OpenOutputStream(PRUint32 startPosition, nsIOutputStream **result)
|
nsFileChannel::OpenOutputStream(PRUint32 startPosition, nsIOutputStream **result)
|
||||||
{
|
{
|
||||||
nsAutoLock lock(mLock);
|
nsAutoMonitor mon(mMonitor);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
|
@ -392,7 +409,7 @@ nsFileChannel::AsyncRead(PRUint32 startPosition, PRInt32 readCount,
|
||||||
nsISupports *ctxt,
|
nsISupports *ctxt,
|
||||||
nsIStreamListener *listener)
|
nsIStreamListener *listener)
|
||||||
{
|
{
|
||||||
nsAutoLock lock(mLock);
|
nsAutoMonitor mon(mMonitor);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
|
@ -409,13 +426,24 @@ nsFileChannel::AsyncRead(PRUint32 startPosition, PRInt32 readCount,
|
||||||
rv = serv->NewAsyncStreamListener(listener, mEventQueue, &mListener);
|
rv = serv->NewAsyncStreamListener(listener, mEventQueue, &mListener);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
#if 0
|
||||||
rv = nsAsyncOutputStream::Create(&mBufferInputStream,
|
rv = nsAsyncOutputStream::Create(&mBufferInputStream,
|
||||||
&mBufferOutputStream,
|
&mBufferOutputStream,
|
||||||
this, ctxt, mListener,
|
this, ctxt, mListener,
|
||||||
NS_FILE_TRANSPORT_SEGMENT_SIZE,
|
NS_FILE_TRANSPORT_SEGMENT_SIZE,
|
||||||
NS_FILE_TRANSPORT_BUFFER_SIZE);
|
NS_FILE_TRANSPORT_BUFFER_SIZE);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
#else
|
||||||
|
rv = NS_NewPipe(&mBufferInputStream, &mBufferOutputStream,
|
||||||
|
NS_FILE_TRANSPORT_SEGMENT_SIZE,
|
||||||
|
NS_FILE_TRANSPORT_BUFFER_SIZE, PR_TRUE, this);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rv = mBufferOutputStream->SetNonBlocking(PR_TRUE);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
NS_ASSERTION(mContext == nsnull, "context not released");
|
||||||
mContext = ctxt;
|
mContext = ctxt;
|
||||||
NS_IF_ADDREF(mContext);
|
NS_IF_ADDREF(mContext);
|
||||||
|
|
||||||
|
@ -435,7 +463,7 @@ nsFileChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||||
nsISupports *ctxt,
|
nsISupports *ctxt,
|
||||||
nsIStreamObserver *observer)
|
nsIStreamObserver *observer)
|
||||||
{
|
{
|
||||||
nsAutoLock lock(mLock);
|
nsAutoMonitor mon(mMonitor);
|
||||||
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
@ -524,7 +552,7 @@ nsWriteToFile(void* closure,
|
||||||
void
|
void
|
||||||
nsFileChannel::Process(void)
|
nsFileChannel::Process(void)
|
||||||
{
|
{
|
||||||
nsAutoLock lock(mLock);
|
nsAutoMonitor mon(mMonitor);
|
||||||
|
|
||||||
switch (mState) {
|
switch (mState) {
|
||||||
case START_READ: {
|
case START_READ: {
|
||||||
|
@ -558,6 +586,13 @@ nsFileChannel::Process(void)
|
||||||
PRUint32 amt;
|
PRUint32 amt;
|
||||||
mStatus = mBufferOutputStream->WriteFrom(fileStr, inLen, &amt);
|
mStatus = mBufferOutputStream->WriteFrom(fileStr, inLen, &amt);
|
||||||
if (NS_FAILED(mStatus)) goto error;
|
if (NS_FAILED(mStatus)) goto error;
|
||||||
|
if (mStatus == NS_BASE_STREAM_WOULD_BLOCK || amt == 0) {
|
||||||
|
// Our nsIBufferObserver will have been called from WriteFrom
|
||||||
|
// which in turn calls Suspend, so we should end up suspending
|
||||||
|
// this file channel.
|
||||||
|
Suspend();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// and feed the buffer to the application via the buffer stream:
|
// and feed the buffer to the application via the buffer stream:
|
||||||
if (mListener) {
|
if (mListener) {
|
||||||
|
@ -639,6 +674,22 @@ nsFileChannel::Process(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// nsIBufferObserver methods:
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsFileChannel::OnFull(nsIBuffer* buffer)
|
||||||
|
{
|
||||||
|
return Suspend();
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsFileChannel::OnEmpty(nsIBuffer* buffer)
|
||||||
|
{
|
||||||
|
return Resume();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// From nsIFileChannel
|
// From nsIFileChannel
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "nsFileSpec.h"
|
#include "nsFileSpec.h"
|
||||||
#include "prlock.h"
|
#include "prlock.h"
|
||||||
#include "nsIEventQueueService.h"
|
#include "nsIEventQueueService.h"
|
||||||
|
#include "nsIBuffer.h"
|
||||||
|
|
||||||
class nsIEventSinkGetter;
|
class nsIEventSinkGetter;
|
||||||
class nsIStreamListener;
|
class nsIStreamListener;
|
||||||
|
@ -33,7 +34,10 @@ class nsIBuffer;
|
||||||
class nsIBufferInputStream;
|
class nsIBufferInputStream;
|
||||||
class nsIBufferOutputStream;
|
class nsIBufferOutputStream;
|
||||||
|
|
||||||
class nsFileChannel : public nsIFileChannel, public nsIRunnable {
|
class nsFileChannel : public nsIFileChannel,
|
||||||
|
public nsIRunnable,
|
||||||
|
public nsIBufferObserver
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
@ -137,6 +141,13 @@ public:
|
||||||
|
|
||||||
NS_IMETHOD Run(void);
|
NS_IMETHOD Run(void);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// nsIBufferObserver:
|
||||||
|
|
||||||
|
NS_IMETHOD OnFull(nsIBuffer* buffer);
|
||||||
|
|
||||||
|
NS_IMETHOD OnEmpty(nsIBuffer* buffer);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// nsFileChannel:
|
// nsFileChannel:
|
||||||
|
|
||||||
|
@ -184,11 +195,11 @@ protected:
|
||||||
PRUint32 mSourceOffset;
|
PRUint32 mSourceOffset;
|
||||||
PRInt32 mAmount;
|
PRInt32 mAmount;
|
||||||
|
|
||||||
PRLock* mLock;
|
PRMonitor* mMonitor;
|
||||||
PRUint32 mLoadAttributes;
|
PRUint32 mLoadAttributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NS_FILE_TRANSPORT_SEGMENT_SIZE (4*1024)
|
#define NS_FILE_TRANSPORT_SEGMENT_SIZE (4*1024)
|
||||||
#define NS_FILE_TRANSPORT_BUFFER_SIZE (32*1024)
|
#define NS_FILE_TRANSPORT_BUFFER_SIZE (1024*1024)//(32*1024)
|
||||||
|
|
||||||
#endif // nsFileChannel_h__
|
#endif // nsFileChannel_h__
|
||||||
|
|
Загрузка…
Ссылка в новой задаче