Fixed some file channel problems. Works better now. Upped buffer size to avoid buffer full problems.

This commit is contained in:
warren%netscape.com 1999-07-10 11:26:51 +00:00
Родитель 7c731d4888
Коммит 4cc4f7d94f
2 изменённых файлов: 85 добавлений и 23 удалений

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

@ -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__