mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-09 14:28:25 +00:00
Added PR_LOG stuff.
This commit is contained in:
parent
847f7d87f9
commit
d1a7f6e578
@ -49,8 +49,7 @@ void XXXNeverCalled()
|
||||
nsVoidArray();
|
||||
NS_GetNumberOfAtoms();
|
||||
nsFileURL(NULL);
|
||||
// NS_NewPipe(NULL, NULL);
|
||||
NS_NewPipe2(NULL, NULL, 0, 0);
|
||||
NS_NewPipe(NULL, NULL, 0, 0, 0, NULL);
|
||||
nsFileSpec s;
|
||||
NS_NewIOFileStream(NULL, s, 0, 0);
|
||||
nsInputFileStream(s, 0, 0);
|
||||
|
@ -42,13 +42,15 @@ nsBuffer::nsBuffer()
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::Init(PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIAllocator* allocator)
|
||||
nsIBufferObserver* observer, nsIAllocator* allocator)
|
||||
{
|
||||
NS_ASSERTION(sizeof(PRCList) <= SEGMENT_OVERHEAD,
|
||||
"need to change SEGMENT_OVERHEAD size");
|
||||
NS_ASSERTION(growBySize > SEGMENT_OVERHEAD, "bad growBySize");
|
||||
mGrowBySize = growBySize;
|
||||
mMaxSize = maxSize;
|
||||
mObserver = observer;
|
||||
NS_IF_ADDREF(mObserver);
|
||||
mAllocator = allocator;
|
||||
NS_ADDREF(mAllocator);
|
||||
return NS_OK;
|
||||
@ -56,6 +58,7 @@ nsBuffer::Init(PRUint32 growBySize, PRUint32 maxSize,
|
||||
|
||||
nsBuffer::~nsBuffer()
|
||||
{
|
||||
NS_IF_RELEASE(mObserver);
|
||||
NS_IF_RELEASE(mAllocator);
|
||||
}
|
||||
|
||||
@ -85,6 +88,10 @@ nsBuffer::PushWriteSegment()
|
||||
nsAutoMonitor mon(this); // protect mSegments
|
||||
|
||||
if (mBufferSize >= mMaxSize) {
|
||||
if (mObserver) {
|
||||
nsresult rv = mObserver->OnFull();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -135,6 +142,10 @@ nsBuffer::PopReadSegment()
|
||||
mReadSegment = nsnull;
|
||||
mReadSegmentEnd = nsnull;
|
||||
mReadCursor = nsnull;
|
||||
if (mObserver) {
|
||||
rv = mObserver->OnEmpty();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mReadSegment = mSegments.next;
|
||||
@ -159,11 +170,11 @@ nsBuffer::ReadSegments(nsWriteSegmentFun writer, void* closure, PRUint32 count,
|
||||
while (count > 0) {
|
||||
rv = GetReadSegment(0, &readBuffer, &readBufferLen);
|
||||
if (rv == NS_BASE_STREAM_EOF) // all we're going to get
|
||||
return *readCount > 0 ? NS_OK : NS_BASE_STREAM_EOF;
|
||||
return *readCount == 0 ? rv : NS_OK;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (readBufferLen == 0)
|
||||
return mEOF && *readCount == 0 ? NS_BASE_STREAM_EOF : NS_OK;
|
||||
return mEOF && (*readCount == 0) ? NS_BASE_STREAM_EOF : NS_OK;
|
||||
|
||||
readBufferLen = PR_MIN(readBufferLen, count);
|
||||
while (readBufferLen > 0) {
|
||||
@ -172,7 +183,7 @@ nsBuffer::ReadSegments(nsWriteSegmentFun writer, void* closure, PRUint32 count,
|
||||
if (NS_FAILED(rv)) {
|
||||
// if we failed to write just report what we were
|
||||
// able to read so far
|
||||
return NS_OK;
|
||||
return (*readCount == 0) ? rv : NS_OK;
|
||||
}
|
||||
NS_ASSERTION(writeCount <= readBufferLen, "writer returned bad writeCount");
|
||||
readBuffer += writeCount;
|
||||
@ -192,7 +203,7 @@ nsBuffer::ReadSegments(nsWriteSegmentFun writer, void* closure, PRUint32 count,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
static NS_METHOD
|
||||
nsWriteToRawBuffer(void* closure,
|
||||
const char* fromRawSegment,
|
||||
PRUint32 offset,
|
||||
@ -208,39 +219,7 @@ nsWriteToRawBuffer(void* closure,
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::Read(char* toBuf, PRUint32 bufLen, PRUint32 *readCount)
|
||||
{
|
||||
#if 1
|
||||
return ReadSegments(nsWriteToRawBuffer, toBuf, bufLen, readCount);
|
||||
#else
|
||||
nsresult rv;
|
||||
PRUint32 readBufferLen;
|
||||
char* readBuffer;
|
||||
|
||||
*readCount = 0;
|
||||
while (bufLen > 0) {
|
||||
rv = GetReadSegment(0, &readBuffer, &readBufferLen);
|
||||
if (rv == NS_BASE_STREAM_EOF) // all we're going to get
|
||||
return *readCount > 0 ? NS_OK : NS_BASE_STREAM_EOF;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (readBufferLen == 0)
|
||||
return mEOF && *readCount == 0 ? NS_BASE_STREAM_EOF : NS_OK;
|
||||
|
||||
PRUint32 count = PR_MIN(bufLen, readBufferLen);
|
||||
nsCRT::memcpy(toBuf, readBuffer, count);
|
||||
*readCount += count;
|
||||
toBuf += count;
|
||||
bufLen -= count;
|
||||
|
||||
if (mReadCursor + count == mReadSegmentEnd) {
|
||||
rv = PopReadSegment();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
else {
|
||||
mReadCursor += count;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -319,6 +298,59 @@ nsBuffer::GetReadSegment(PRUint32 segmentLogicalOffset,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetReadableAmount(PRUint32 *result)
|
||||
{
|
||||
// first set the read segment and cursor if not already set
|
||||
if (mReadSegment == nsnull) {
|
||||
if (PR_CLIST_IS_EMPTY(&mSegments)) {
|
||||
*result = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
mReadSegment = mSegments.next;
|
||||
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
|
||||
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
|
||||
*result = mGrowBySize;
|
||||
}
|
||||
}
|
||||
|
||||
// now search for the segment starting from segmentLogicalOffset and return it
|
||||
PRCList* curSeg = mReadSegment;
|
||||
char* curSegStart = mReadCursor;
|
||||
char* curSegEnd = mReadSegmentEnd;
|
||||
PRInt32 amt;
|
||||
while (PR_TRUE) {
|
||||
// snapshot the write cursor into a local variable -- this allows
|
||||
// a writer to freely change it while we're reading while avoiding
|
||||
// using a lock
|
||||
char* snapshotWriteCursor = mWriteCursor; // atomic
|
||||
|
||||
// next check if the write cursor is in our segment
|
||||
if (curSegStart <= snapshotWriteCursor &&
|
||||
snapshotWriteCursor < curSegEnd) {
|
||||
// same segment -- read up to the snapshotWriteCursor
|
||||
curSegEnd = snapshotWriteCursor;
|
||||
|
||||
amt = curSegEnd - curSegStart;
|
||||
*result += amt;
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
amt = curSegEnd - curSegStart;
|
||||
*result += amt;
|
||||
curSeg = PR_NEXT_LINK(curSeg);
|
||||
if (curSeg == mReadSegment) {
|
||||
// been all the way around
|
||||
return NS_OK;
|
||||
}
|
||||
curSegEnd = (char*)curSeg + mGrowBySize;
|
||||
curSegStart = (char*)curSeg + sizeof(PRCList);
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -339,7 +371,7 @@ nsBuffer::WriteSegments(nsReadSegmentFun reader, void* closure, PRUint32 count,
|
||||
// if we failed to allocate a new segment, we're probably out
|
||||
// of memory, but we don't care -- just report what we were
|
||||
// able to write so far
|
||||
return (*writeCount == 0) ? NS_BASE_STREAM_FULL : NS_OK;
|
||||
return (*writeCount == 0) ? NS_BASE_STREAM_FULL : NS_OK;
|
||||
}
|
||||
|
||||
writeBufLen = PR_MIN(writeBufLen, count);
|
||||
@ -350,11 +382,11 @@ nsBuffer::WriteSegments(nsReadSegmentFun reader, void* closure, PRUint32 count,
|
||||
// If the input stream ends, set EOF on the buffer so that
|
||||
// nsBuffer::Read later notices it.
|
||||
SetEOF();
|
||||
return NS_OK;
|
||||
return (*writeCount == 0) ? rv : NS_OK;
|
||||
}
|
||||
else if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
// If no more data is available then return...
|
||||
return rv;
|
||||
// If no more data is available then return...
|
||||
return rv;
|
||||
}
|
||||
else if (NS_FAILED(rv)) {
|
||||
// if we failed to read just report what we were
|
||||
@ -380,7 +412,7 @@ nsBuffer::WriteSegments(nsReadSegmentFun reader, void* closure, PRUint32 count,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
static NS_METHOD
|
||||
nsReadFromRawBuffer(void* closure,
|
||||
char* toRawSegment,
|
||||
PRUint32 offset,
|
||||
@ -396,45 +428,10 @@ nsReadFromRawBuffer(void* closure,
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::Write(const char* fromBuf, PRUint32 bufLen, PRUint32 *writeCount)
|
||||
{
|
||||
#if 1
|
||||
return WriteSegments(nsReadFromRawBuffer, (void*)fromBuf, bufLen, writeCount);
|
||||
#else
|
||||
nsresult rv;
|
||||
|
||||
if (mEOF)
|
||||
return NS_BASE_STREAM_EOF;
|
||||
|
||||
*writeCount = 0;
|
||||
while (bufLen > 0) {
|
||||
PRUint32 writeBufLen;
|
||||
char* writeBuf;
|
||||
rv = GetWriteSegment(&writeBuf, &writeBufLen);
|
||||
if (NS_FAILED(rv)) {
|
||||
// if we failed to allocate a new segment, we're probably out
|
||||
// of memory, but we don't care -- just report what we were
|
||||
// able to write so far
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32 count = PR_MIN(writeBufLen, bufLen);
|
||||
nsCRT::memcpy(writeBuf, fromBuf, count);
|
||||
fromBuf += count;
|
||||
bufLen -= count;
|
||||
*writeCount += count;
|
||||
// set the write cursor after the data is valid
|
||||
if (mWriteCursor + count == mWriteSegmentEnd) {
|
||||
mWriteSegment = nsnull; // allocate a new segment next time around
|
||||
mWriteSegmentEnd = nsnull;
|
||||
mWriteCursor = nsnull;
|
||||
}
|
||||
else
|
||||
mWriteCursor += count;
|
||||
}
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
static NS_METHOD
|
||||
nsReadFromInputStream(void* closure,
|
||||
char* toRawSegment,
|
||||
PRUint32 offset,
|
||||
@ -448,52 +445,7 @@ nsReadFromInputStream(void* closure,
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::WriteFrom(nsIInputStream* fromStream, PRUint32 count, PRUint32 *writeCount)
|
||||
{
|
||||
#if 1
|
||||
return WriteSegments(nsReadFromInputStream, fromStream, count, writeCount);
|
||||
#else
|
||||
nsresult rv;
|
||||
|
||||
if (mEOF)
|
||||
return NS_BASE_STREAM_EOF;
|
||||
|
||||
*writeCount = 0;
|
||||
while (count > 0) {
|
||||
PRUint32 writeBufLen;
|
||||
char* writeBuf;
|
||||
rv = GetWriteSegment(&writeBuf, &writeBufLen);
|
||||
if (NS_FAILED(rv)) {
|
||||
// if we failed to allocate a new segment, we're probably out
|
||||
// of memory, but we don't care -- just report what we were
|
||||
// able to write so far
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32 readCount;
|
||||
rv = fromStream->Read(writeBuf, PR_MIN(writeBufLen, count), &readCount);
|
||||
if (rv == NS_BASE_STREAM_EOF) {
|
||||
// If the input stream ends, set EOF on the buffer so that
|
||||
// nsBuffer::Read later notices it.
|
||||
SetEOF();
|
||||
return NS_OK;
|
||||
}
|
||||
else if (NS_FAILED(rv)) {
|
||||
// if we failed to read just report what we were
|
||||
// able to write so far
|
||||
return NS_OK;
|
||||
}
|
||||
*writeCount += readCount;
|
||||
count -= readCount;
|
||||
// set the write cursor after the data is valid
|
||||
if (mWriteCursor + readCount == mWriteSegmentEnd) {
|
||||
mWriteSegment = nsnull; // allocate a new segment next time around
|
||||
mWriteSegmentEnd = nsnull;
|
||||
mWriteCursor = nsnull;
|
||||
}
|
||||
else
|
||||
mWriteCursor += readCount;
|
||||
}
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -507,9 +459,6 @@ nsBuffer::GetWriteSegment(char* *resultSegment,
|
||||
|
||||
nsresult rv;
|
||||
if (mWriteSegment == nsnull) {
|
||||
if (mBufferSize >= mMaxSize)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv = PushWriteSegment();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
@ -521,6 +470,17 @@ nsBuffer::GetWriteSegment(char* *resultSegment,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetWritableAmount(PRUint32 *amount)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 readableAmount;
|
||||
rv = GetReadableAmount(&readableAmount);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
*amount = mMaxSize - readableAmount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::SetEOF()
|
||||
{
|
||||
@ -616,7 +576,8 @@ static NS_DEFINE_CID(kAllocatorCID, NS_ALLOCATOR_CID);
|
||||
|
||||
NS_COM nsresult
|
||||
NS_NewBuffer(nsIBuffer* *result,
|
||||
PRUint32 growBySize, PRUint32 maxSize)
|
||||
PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIBufferObserver* observer)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIAllocator, alloc, kAllocatorCID, &rv);
|
||||
@ -626,7 +587,7 @@ NS_NewBuffer(nsIBuffer* *result,
|
||||
rv = nsBuffer::Create(NULL, nsIBuffer::GetIID(), (void**)&buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = buf->Init(growBySize, maxSize, alloc);
|
||||
rv = buf->Init(growBySize, maxSize, observer, alloc);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(buf);
|
||||
return rv;
|
||||
@ -640,7 +601,8 @@ static NS_DEFINE_CID(kPageManagerCID, NS_PAGEMANAGER_CID);
|
||||
|
||||
NS_COM nsresult
|
||||
NS_NewPageBuffer(nsIBuffer* *result,
|
||||
PRUint32 growBySize, PRUint32 maxSize)
|
||||
PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIBufferObserver* observer)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIAllocator, alloc, kPageManagerCID, &rv);
|
||||
@ -650,7 +612,7 @@ NS_NewPageBuffer(nsIBuffer* *result,
|
||||
rv = nsBuffer::Create(NULL, nsIBuffer::GetIID(), (void**)&buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = buf->Init(growBySize, maxSize, alloc);
|
||||
rv = buf->Init(growBySize, maxSize, observer, alloc);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(buf);
|
||||
return rv;
|
||||
|
@ -33,19 +33,21 @@ public:
|
||||
|
||||
// nsIBuffer methods:
|
||||
NS_IMETHOD Init(PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIAllocator* allocator);
|
||||
nsIBufferObserver* observer, nsIAllocator* allocator);
|
||||
NS_IMETHOD Read(char* toBuf, PRUint32 bufLen, PRUint32 *readCount);
|
||||
NS_IMETHOD ReadSegments(nsWriteSegmentFun writer, void* closure, PRUint32 count,
|
||||
PRUint32 *readCount);
|
||||
NS_IMETHOD GetReadSegment(PRUint32 segmentLogicalOffset,
|
||||
const char* *resultSegment,
|
||||
PRUint32 *resultSegmentLen);
|
||||
NS_IMETHOD GetReadableAmount(PRUint32 *amount);
|
||||
NS_IMETHOD Write(const char* fromBuf, PRUint32 bufLen, PRUint32 *writeCount);
|
||||
NS_IMETHOD WriteFrom(nsIInputStream* fromStream, PRUint32 count, PRUint32 *writeCount);
|
||||
NS_IMETHOD WriteSegments(nsReadSegmentFun reader, void* closure, PRUint32 count,
|
||||
PRUint32 *writeCount);
|
||||
NS_IMETHOD GetWriteSegment(char* *resultSegment,
|
||||
PRUint32 *resultSegmentLen);
|
||||
NS_IMETHOD GetWritableAmount(PRUint32 *amount);
|
||||
NS_IMETHOD SetEOF();
|
||||
NS_IMETHOD AtEOF(PRBool *result);
|
||||
NS_IMETHOD Search(const char* forString, PRBool ignoreCase,
|
||||
@ -62,6 +64,7 @@ protected:
|
||||
PRUint32 mGrowBySize;
|
||||
PRUint32 mMaxSize;
|
||||
nsIAllocator* mAllocator;
|
||||
nsIBufferObserver* mObserver;
|
||||
|
||||
PRCList mSegments;
|
||||
PRUint32 mBufferSize;
|
||||
|
@ -26,6 +26,7 @@ class nsIInputStream;
|
||||
class nsIAllocator;
|
||||
class nsIBufferInputStream;
|
||||
class nsIBufferOutputStream;
|
||||
class nsIBufferObserver;
|
||||
|
||||
#define NS_IBUFFER_IID \
|
||||
{ /* 1eebb300-fb8b-11d2-9324-00104ba0fd40 */ \
|
||||
@ -76,7 +77,7 @@ public:
|
||||
* minus SEGMENT_OVERHEAD bytes.
|
||||
*/
|
||||
NS_IMETHOD Init(PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIAllocator* allocator) = 0;
|
||||
nsIBufferObserver* observer, nsIAllocator* allocator) = 0;
|
||||
|
||||
/**
|
||||
* Reads from the read cursor into a char buffer up to a specified length.
|
||||
@ -103,6 +104,11 @@ public:
|
||||
const char* *resultSegment,
|
||||
PRUint32 *resultSegmentLen) = 0;
|
||||
|
||||
/**
|
||||
* Returns the amount of data currently in the buffer available for reading.
|
||||
*/
|
||||
NS_IMETHOD GetReadableAmount(PRUint32 *amount) = 0;
|
||||
|
||||
/**
|
||||
* Writes from a char buffer up to a specified length.
|
||||
* @param writeCount - The amount that could be written. If the buffer becomes full,
|
||||
@ -133,6 +139,11 @@ public:
|
||||
NS_IMETHOD GetWriteSegment(char* *resultSegment,
|
||||
PRUint32 *resultSegmentLen) = 0;
|
||||
|
||||
/**
|
||||
* Returns the amount of space currently in the buffer available for writing.
|
||||
*/
|
||||
NS_IMETHOD GetWritableAmount(PRUint32 *amount) = 0;
|
||||
|
||||
/**
|
||||
* Sets an EOF marker (typcially done by the writer) so that a reader can be informed
|
||||
* when all the data in the buffer is consumed. After the EOF marker has been
|
||||
@ -160,13 +171,47 @@ public:
|
||||
PRBool *found, PRUint32 *offsetSearchedTo) = 0;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define NS_IBUFFEROBSERVER_IID \
|
||||
{ /* 0c18bef0-22a8-11d3-9349-00104ba0fd40 */ \
|
||||
0x0c18bef0, \
|
||||
0x22a8, \
|
||||
0x11d3, \
|
||||
{0x93, 0x49, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
|
||||
}
|
||||
|
||||
/**
|
||||
* A buffer observer is used to detect when the buffer becomes completely full
|
||||
* or completely empty.
|
||||
*/
|
||||
class nsIBufferObserver : public nsISupports {
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IBUFFEROBSERVER_IID);
|
||||
|
||||
NS_IMETHOD OnFull() = 0;
|
||||
|
||||
NS_IMETHOD OnEmpty() = 0;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Creates a new buffer.
|
||||
* @param observer - may be null
|
||||
*/
|
||||
extern NS_COM nsresult
|
||||
NS_NewBuffer(nsIBuffer* *result,
|
||||
PRUint32 growBySize, PRUint32 maxSize);
|
||||
PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIBufferObserver* observer);
|
||||
|
||||
/**
|
||||
* Creates a new buffer, allocating segments from virtual memory pages.
|
||||
*/
|
||||
extern NS_COM nsresult
|
||||
NS_NewPageBuffer(nsIBuffer* *result,
|
||||
PRUint32 growBySize, PRUint32 maxSize);
|
||||
PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIBufferObserver* observer);
|
||||
|
||||
extern NS_COM nsresult
|
||||
NS_NewBufferInputStream(nsIBufferInputStream* *result,
|
||||
@ -177,8 +222,11 @@ NS_NewBufferOutputStream(nsIBufferOutputStream* *result,
|
||||
nsIBuffer* buffer, PRBool blocking = PR_FALSE);
|
||||
|
||||
extern NS_COM nsresult
|
||||
NS_NewPipe2(nsIBufferInputStream* *inStrResult,
|
||||
NS_NewPipe(nsIBufferInputStream* *inStrResult,
|
||||
nsIBufferOutputStream* *outStrResult,
|
||||
PRUint32 growBySize, PRUint32 maxSize);
|
||||
PRUint32 growBySize, PRUint32 maxSize,
|
||||
PRBool blocking, nsIBufferObserver* observer);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // nsIBuffer_h___
|
||||
|
@ -168,16 +168,18 @@ nsBufferInputStream::Read(char* aBuf, PRUint32 aCount, PRUint32 *aReadCount)
|
||||
while (aCount > 0) {
|
||||
PRUint32 amt;
|
||||
rv = mBuffer->Read(aBuf, aCount, &amt);
|
||||
if (rv == NS_BASE_STREAM_EOF)
|
||||
return *aReadCount > 0 ? NS_OK : rv;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (rv == NS_BASE_STREAM_EOF) {
|
||||
rv = (*aReadCount == 0) ? rv : NS_OK;
|
||||
break;
|
||||
}
|
||||
if (NS_FAILED(rv)) break;
|
||||
if (amt == 0) {
|
||||
rv = Fill();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!mBlocking) {
|
||||
// Only return WOULD_BLOCK if no data was read...
|
||||
return *aReadCount > 0 ? NS_OK : rv;
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
rv = (*aReadCount == 0) ? rv : NS_OK;
|
||||
break;
|
||||
}
|
||||
if (NS_FAILED(rv)) break;
|
||||
}
|
||||
else {
|
||||
*aReadCount += amt;
|
||||
@ -185,6 +187,11 @@ nsBufferInputStream::Read(char* aBuf, PRUint32 aCount, PRUint32 *aReadCount)
|
||||
aCount -= amt;
|
||||
}
|
||||
}
|
||||
if (rv == NS_BASE_STREAM_EOF) {
|
||||
// all we're ever going to get -- so wake up anyone in Flush
|
||||
nsAutoMonitor mon(mBuffer);
|
||||
mon.Notify(); // wake up writer
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -200,21 +207,62 @@ nsBufferInputStream::GetBuffer(nsIBuffer* *result)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBufferInputStream::Fill(const char* buf, PRUint32 count, PRUint32 *result)
|
||||
nsBufferInputStream::Fill(const char* aBuf, PRUint32 aCount, PRUint32 *aWriteCount)
|
||||
{
|
||||
if (mBuffer == nsnull)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
return mBuffer->Write(buf, count, result);
|
||||
nsresult rv = NS_OK;
|
||||
*aWriteCount = 0;
|
||||
|
||||
while (aCount > 0) {
|
||||
PRUint32 amt;
|
||||
rv = mBuffer->Write(aBuf, aCount, &amt);
|
||||
if (rv == NS_BASE_STREAM_EOF)
|
||||
return *aWriteCount > 0 ? NS_OK : rv;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (amt == 0) {
|
||||
rv = Fill();
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK)
|
||||
return *aWriteCount > 0 ? NS_OK : rv;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
else {
|
||||
aBuf += amt;
|
||||
aCount -= amt;
|
||||
*aWriteCount += amt;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBufferInputStream::FillFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *result)
|
||||
nsBufferInputStream::FillFrom(nsIInputStream *fromStream, PRUint32 aCount, PRUint32 *aWriteCount)
|
||||
{
|
||||
if (mBuffer == nsnull)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
return mBuffer->WriteFrom(inStr, count, result);
|
||||
nsresult rv = NS_OK;
|
||||
*aWriteCount = 0;
|
||||
|
||||
while (aCount > 0) {
|
||||
PRUint32 amt;
|
||||
rv = mBuffer->WriteFrom(fromStream, aCount, &amt);
|
||||
if (rv == NS_BASE_STREAM_EOF)
|
||||
return *aWriteCount > 0 ? NS_OK : rv;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (amt == 0) {
|
||||
rv = Fill();
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK)
|
||||
return *aWriteCount > 0 ? NS_OK : rv;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
else {
|
||||
aCount -= amt;
|
||||
*aWriteCount += amt;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -348,12 +396,18 @@ nsBufferOutputStream::Write(const char* aBuf, PRUint32 aCount, PRUint32 *aWriteC
|
||||
while (aCount > 0) {
|
||||
PRUint32 amt;
|
||||
rv = mBuffer->Write(aBuf, aCount, &amt);
|
||||
if (rv == NS_BASE_STREAM_EOF)
|
||||
return *aWriteCount > 0 ? NS_OK : rv;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (rv == NS_BASE_STREAM_EOF) {
|
||||
rv = (*aWriteCount == 0) ? rv : NS_OK;
|
||||
break;
|
||||
}
|
||||
if (NS_FAILED(rv)) break;
|
||||
if (amt == 0) {
|
||||
rv = Flush();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
rv = (*aWriteCount == 0) ? rv : NS_OK;
|
||||
break;
|
||||
}
|
||||
if (NS_FAILED(rv)) break;
|
||||
}
|
||||
else {
|
||||
aBuf += amt;
|
||||
@ -361,6 +415,11 @@ nsBufferOutputStream::Write(const char* aBuf, PRUint32 aCount, PRUint32 *aWriteC
|
||||
*aWriteCount += amt;
|
||||
}
|
||||
}
|
||||
if (rv == NS_BASE_STREAM_EOF) {
|
||||
// all we're ever going to get -- so wake up anyone in Flush
|
||||
nsAutoMonitor mon(mBuffer);
|
||||
mon.Notify(); // wake up writer
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -377,18 +436,29 @@ nsBufferOutputStream::WriteFrom(nsIInputStream* fromStream, PRUint32 aCount,
|
||||
while (aCount > 0) {
|
||||
PRUint32 amt;
|
||||
rv = mBuffer->WriteFrom(fromStream, aCount, &amt);
|
||||
if (rv == NS_BASE_STREAM_EOF)
|
||||
return *aWriteCount > 0 ? NS_OK : rv;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (rv == NS_BASE_STREAM_EOF) {
|
||||
rv = (*aWriteCount == 0) ? rv : NS_OK;
|
||||
break;
|
||||
}
|
||||
if (NS_FAILED(rv)) break;
|
||||
if (amt == 0) {
|
||||
rv = Flush();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
rv = (*aWriteCount == 0) ? rv : NS_OK;
|
||||
break;
|
||||
}
|
||||
if (NS_FAILED(rv)) break;
|
||||
}
|
||||
else {
|
||||
aCount -= amt;
|
||||
*aWriteCount += amt;
|
||||
}
|
||||
}
|
||||
if (rv == NS_BASE_STREAM_EOF) {
|
||||
// all we're ever going to get -- so wake up anyone in Flush
|
||||
nsAutoMonitor mon(mBuffer);
|
||||
mon.Notify(); // wake up writer
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -406,10 +476,10 @@ nsBufferOutputStream::Flush(void)
|
||||
PRUint32 amt;
|
||||
char* buf;
|
||||
rv = mBuffer->GetWriteSegment(&buf, &amt);
|
||||
if (rv == NS_BASE_STREAM_EOF) return rv;
|
||||
// don't exit on EOF here -- we need to block until the data is consumed
|
||||
if (NS_SUCCEEDED(rv) && amt > 0) return NS_OK;
|
||||
|
||||
// else notify the reader and wait
|
||||
// else notify the reader and wait
|
||||
rv = mon.Notify();
|
||||
if (NS_FAILED(rv)) return rv; // interrupted
|
||||
rv = mon.Wait();
|
||||
@ -446,22 +516,23 @@ NS_NewBufferOutputStream(nsIBufferOutputStream* *result,
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_COM nsresult
|
||||
NS_NewPipe2(nsIBufferInputStream* *inStrResult,
|
||||
NS_NewPipe(nsIBufferInputStream* *inStrResult,
|
||||
nsIBufferOutputStream* *outStrResult,
|
||||
PRUint32 growBySize, PRUint32 maxSize)
|
||||
PRUint32 growBySize, PRUint32 maxSize,
|
||||
PRBool blocking, nsIBufferObserver* observer)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIBufferInputStream* inStr = nsnull;
|
||||
nsIBufferOutputStream* outStr = nsnull;
|
||||
nsIBuffer* buf = nsnull;
|
||||
|
||||
rv = NS_NewPageBuffer(&buf, growBySize, maxSize);
|
||||
rv = NS_NewPageBuffer(&buf, growBySize, maxSize, observer);
|
||||
if (NS_FAILED(rv)) goto error;
|
||||
|
||||
rv = NS_NewBufferInputStream(&inStr, buf, PR_TRUE);
|
||||
rv = NS_NewBufferInputStream(&inStr, buf, blocking);
|
||||
if (NS_FAILED(rv)) goto error;
|
||||
|
||||
rv = NS_NewBufferOutputStream(&outStr, buf, PR_TRUE);
|
||||
rv = NS_NewBufferOutputStream(&outStr, buf, blocking);
|
||||
if (NS_FAILED(rv)) goto error;
|
||||
|
||||
NS_RELEASE(buf);
|
||||
|
@ -18,17 +18,45 @@
|
||||
|
||||
#include "nsThread.h"
|
||||
#include "prmem.h"
|
||||
//#include <stdio.h>
|
||||
#include "prlog.h"
|
||||
|
||||
PRUintn nsThread::kIThreadSelfIndex = 0;
|
||||
static nsIThread *gMainThread = 0;
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
//
|
||||
// Log module for nsIThread logging...
|
||||
//
|
||||
// To enable logging (see prlog.h for full details):
|
||||
//
|
||||
// set NSPR_LOG_MODULES=nsIThread:5
|
||||
// set NSPR_LOG_FILE=nspr.log
|
||||
//
|
||||
// this enables PR_LOG_DEBUG level information and places all output in
|
||||
// the file nspr.log
|
||||
//
|
||||
// gSocketLog is defined in nsSocketTransport.cpp
|
||||
//
|
||||
PRLogModuleInfo* nsIThreadLog = nsnull;
|
||||
|
||||
#endif /* PR_LOGGING */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsThread::nsThread()
|
||||
: mThread(nsnull), mRunnable(nsnull), mDead(PR_FALSE)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
//
|
||||
// Initialize the global PRLogModule for nsIThread logging
|
||||
// if necessary...
|
||||
//
|
||||
if (nsIThreadLog == nsnull) {
|
||||
nsIThreadLog = PR_NewLogModule("nsIThread");
|
||||
}
|
||||
#endif /* PR_LOGGING */
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -46,7 +74,8 @@ nsThread::Init(nsIRunnable* runnable,
|
||||
NS_ADDREF_THIS(); // released in nsThread::Join
|
||||
mThread = PR_CreateThread(PR_USER_THREAD, Main, this,
|
||||
priority, scope, state, stackSize);
|
||||
// printf("%x %x (%d) create\n", this, mThread, mRefCnt);
|
||||
PR_LOG(nsIThreadLog, PR_LOG_DEBUG,
|
||||
("nsIThread %p created\n", this));
|
||||
if (mThread == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
@ -54,7 +83,8 @@ nsThread::Init(nsIRunnable* runnable,
|
||||
|
||||
nsThread::~nsThread()
|
||||
{
|
||||
// printf("%x %x (%d) destroy\n", this, mThread, mRefCnt);
|
||||
PR_LOG(nsIThreadLog, PR_LOG_DEBUG,
|
||||
("nsIThread %p destroyed\n", this));
|
||||
NS_IF_RELEASE(mRunnable);
|
||||
}
|
||||
|
||||
@ -67,13 +97,15 @@ nsThread::Main(void* arg)
|
||||
rv = self->RegisterThreadSelf();
|
||||
NS_ASSERTION(rv == NS_OK, "failed to set thread self");
|
||||
|
||||
// printf("%x %x (%d) start run\n", self, self->mThread, self->mRefCnt);
|
||||
PR_LOG(nsIThreadLog, PR_LOG_DEBUG,
|
||||
("nsIThread %p start run %p\n", self, self->mRunnable));
|
||||
rv = self->mRunnable->Run();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "runnable failed");
|
||||
|
||||
PRThreadState state;
|
||||
rv = self->GetState(&state);
|
||||
// printf("%x %x (%d) end run\n", self, self->mThread, self->mRefCnt);
|
||||
PR_LOG(nsIThreadLog, PR_LOG_DEBUG,
|
||||
("nsIThread %p end run %p\n", self, self->mRunnable));
|
||||
}
|
||||
|
||||
void
|
||||
@ -82,7 +114,8 @@ nsThread::Exit(void* arg)
|
||||
nsThread* self = (nsThread*)arg;
|
||||
nsresult rv = NS_OK;
|
||||
self->mDead = PR_TRUE;
|
||||
// printf("%x %x (%d) exit\n", self, self->mThread, self->mRefCnt - 1);
|
||||
PR_LOG(nsIThreadLog, PR_LOG_DEBUG,
|
||||
("nsIThread %p exited\n", self));
|
||||
NS_RELEASE(self);
|
||||
}
|
||||
|
||||
@ -94,11 +127,13 @@ nsThread::Join()
|
||||
// don't check for mDead here because nspr calls Exit (cleaning up
|
||||
// thread-local storage) before they let us join with the thread
|
||||
|
||||
// printf("%x %x (%d) start join\n", this, mThread, mRefCnt);
|
||||
PR_LOG(nsIThreadLog, PR_LOG_DEBUG,
|
||||
("nsIThread %p start join\n", this));
|
||||
PRStatus status = PR_JoinThread(mThread);
|
||||
// XXX can't use NS_RELEASE here because the macro wants to set
|
||||
// this to null (bad c++)
|
||||
// printf("%x %x (%d) end join\n", this, mThread, mRefCnt);
|
||||
PR_LOG(nsIThreadLog, PR_LOG_DEBUG,
|
||||
("nsIThread %p end join\n", this));
|
||||
if (status == PR_SUCCESS) {
|
||||
this->Release(); // most likely the final release of this thread
|
||||
return NS_OK;
|
||||
@ -368,7 +403,12 @@ nsThreadPool::GetRequest()
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
// printf("thread %x waiting\n", PR_CurrentThread());
|
||||
#if defined(PR_LOGGING)
|
||||
nsIThread* th;
|
||||
nsIThread::GetCurrent(&th);
|
||||
#endif
|
||||
PR_LOG(nsIThreadLog, PR_LOG_DEBUG,
|
||||
("nsIThreadPool thread %p waiting\n", th));
|
||||
PRStatus status = PR_Wait(mRequestMonitor, PR_INTERVAL_NO_TIMEOUT);
|
||||
if (status != PR_SUCCESS || mShuttingDown) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
@ -495,17 +535,23 @@ nsThreadPoolRunnable::Run()
|
||||
PR_CNotify(mPool);
|
||||
PR_CExitMonitor(mPool);
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
nsIThread* th;
|
||||
nsIThread::GetCurrent(&th);
|
||||
#endif
|
||||
while ((request = mPool->GetRequest()) != nsnull) {
|
||||
// printf("running %x, thread %x\n", this, PR_CurrentThread());
|
||||
PR_LOG(nsIThreadLog, PR_LOG_DEBUG,
|
||||
("nsIThreadPool thread %p running %p\n", th, this));
|
||||
rv = request->Run();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "runnable failed");
|
||||
|
||||
// let the thread pool know we're finished a run
|
||||
// let the thread pool know we've finished a run
|
||||
PR_CEnterMonitor(mPool);
|
||||
PR_CNotify(mPool);
|
||||
PR_CExitMonitor(mPool);
|
||||
}
|
||||
// printf("quitting %x, thread %x\n", this, PR_CurrentThread());
|
||||
PR_LOG(nsIThreadLog, PR_LOG_DEBUG,
|
||||
("nsIThreadPool thread %p quitting %x\n", th, this));
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user