fixes bug 193917 "incorporate changes from bz's comments in bug 176919" r+sr=bzbarsky
git-svn-id: svn://10.0.0.236/trunk@147780 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -40,6 +40,34 @@
|
||||
|
||||
interface nsIMemory;
|
||||
|
||||
/**
|
||||
* nsIPipe represents an in-process buffer that can be read using nsIInputStream
|
||||
* and written using nsIOutputStream. The reader and writer of a pipe do not
|
||||
* have to be on the same thread. As a result, the pipe is an ideal mechanism
|
||||
* to bridge data exchange between two threads. For example, a worker thread
|
||||
* might write data to a pipe from which the main thread will read.
|
||||
*
|
||||
* Each end of the pipe can be either blocking or non-blocking. Recall that a
|
||||
* non-blocking stream will return NS_BASE_STREAM_WOULD_BLOCK if it cannot be
|
||||
* read or written to without blocking the calling thread. For example, if you
|
||||
* try to read from an empty pipe that has not yet been closed, then if that
|
||||
* pipe's input end is non-blocking, then the read call will fail immediately
|
||||
* with NS_BASE_STREAM_WOULD_BLOCK as the error condition. However, if that
|
||||
* pipe's input end is blocking, then the read call will not return until the
|
||||
* pipe has data or until the pipe is closed. This example presumes that the
|
||||
* pipe is being filled asynchronously on some background thread.
|
||||
*
|
||||
* The pipe supports nsIAsyncInputStream and nsIAsyncOutputStream, which give
|
||||
* the user of a non-blocking pipe the ability to wait for the pipe to become
|
||||
* ready again. For example, in the case of an empty non-blocking pipe, the
|
||||
* user can call AsyncWait on the input end of the pipe to be notified when
|
||||
* the pipe has data to read (or when the pipe becomes closed).
|
||||
*
|
||||
* NS_NewPipe2 and NS_NewPipe provide convenient pipe constructors. In most
|
||||
* cases nsIPipe is not actually used. It is usually enough to just get
|
||||
* references to the pipe's input and output end. In which case, the pipe is
|
||||
* automatically closed when the respective pipe ends are released.
|
||||
*/
|
||||
[scriptable, uuid(f4211abc-61b3-11d4-9877-00c04fa0cf4a)]
|
||||
interface nsIPipe : nsISupports
|
||||
{
|
||||
@@ -52,10 +80,21 @@ interface nsIPipe : nsISupports
|
||||
in unsigned long segmentCount,
|
||||
in nsIMemory segmentAllocator);
|
||||
|
||||
/**
|
||||
* The pipe's input end, which also implements nsISearchableInputStream.
|
||||
*/
|
||||
readonly attribute nsIAsyncInputStream inputStream;
|
||||
|
||||
/**
|
||||
* The pipe's output end.
|
||||
*/
|
||||
readonly attribute nsIAsyncOutputStream outputStream;
|
||||
};
|
||||
|
||||
/**
|
||||
* XXX this interface doesn't really belong in here. It is here because
|
||||
* currently nsPipeInputStream is the only implementation of this interface.
|
||||
*/
|
||||
[scriptable, uuid(8C39EF62-F7C9-11d4-98F5-001083010E9B)]
|
||||
interface nsISearchableInputStream : nsISupports
|
||||
{
|
||||
@@ -77,6 +116,35 @@ interface nsISearchableInputStream : nsISupports
|
||||
|
||||
%{C++
|
||||
|
||||
/**
|
||||
* NS_NewPipe2
|
||||
*
|
||||
* This function supercedes NS_NewPipe. It differs from NS_NewPipe in two
|
||||
* major ways:
|
||||
* (1) returns nsIAsyncInputStream and nsIAsyncOutputStream, so it is
|
||||
* not necessary to QI in order to access these interfaces.
|
||||
* (2) the size of the pipe is determined by the number of segments
|
||||
* times the size of each segment.
|
||||
*
|
||||
* @param pipeIn
|
||||
* resulting input end of the pipe
|
||||
* @param pipeOut
|
||||
* resulting output end of the pipe
|
||||
* @param nonBlockingInput
|
||||
* true specifies non-blocking input stream behavior
|
||||
* @param nonBlockingOutput
|
||||
* true specifies non-blocking output stream behavior
|
||||
* @param segmentSize
|
||||
* specifies the segment size in bytes (pass 0 to use default value)
|
||||
* @param segmentCount
|
||||
* specifies the max number of segments (pass 0 to use default value)
|
||||
* passing PR_UINT32_MAX here causes the pipe to have "infinite" space.
|
||||
* this mode can be useful in some cases, but should always be used with
|
||||
* caution. the default value for this parameter is a finite value.
|
||||
* @param segmentAlloc
|
||||
* pass reference to nsIMemory to have all pipe allocations use this
|
||||
* allocator (pass null to use the default allocator)
|
||||
*/
|
||||
extern NS_COM nsresult
|
||||
NS_NewPipe2(nsIAsyncInputStream **pipeIn,
|
||||
nsIAsyncOutputStream **pipeOut,
|
||||
@@ -86,6 +154,34 @@ NS_NewPipe2(nsIAsyncInputStream **pipeIn,
|
||||
PRUint32 segmentCount = 0,
|
||||
nsIMemory *segmentAlloc = nsnull);
|
||||
|
||||
/**
|
||||
* NS_NewPipe
|
||||
*
|
||||
* Preserved for backwards compatibility. Plus, this interface is more
|
||||
* amiable in certain contexts (e.g., when you don't need the pipe's async
|
||||
* capabilities).
|
||||
*
|
||||
* @param pipeIn
|
||||
* resulting input end of the pipe
|
||||
* @param pipeOut
|
||||
* resulting output end of the pipe
|
||||
* @param segmentSize
|
||||
* specifies the segment size in bytes (pass 0 to use default value)
|
||||
* @param maxSize
|
||||
* specifies the max size of the pipe (pass 0 to use default value)
|
||||
* number of segments is maxSize / segmentSize, and maxSize must be a
|
||||
* multiple of segmentSize. passing PR_UINT32_MAX here causes the
|
||||
* pipe to have "infinite" space. this mode can be useful in some
|
||||
* cases, but should always be used with caution. the default value
|
||||
* for this parameter is a finite value.
|
||||
* @param nonBlockingInput
|
||||
* true specifies non-blocking input stream behavior
|
||||
* @param nonBlockingOutput
|
||||
* true specifies non-blocking output stream behavior
|
||||
* @param segmentAlloc
|
||||
* pass reference to nsIMemory to have all pipe allocations use this
|
||||
* allocator (pass null to use the default allocator)
|
||||
*/
|
||||
inline nsresult
|
||||
NS_NewPipe(nsIInputStream **pipeIn,
|
||||
nsIOutputStream **pipeOut,
|
||||
|
||||
@@ -183,6 +183,14 @@ nsInputStreamTee::GetSource(nsIInputStream **source)
|
||||
NS_IMETHODIMP
|
||||
nsInputStreamTee::SetSink(nsIOutputStream *sink)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (sink) {
|
||||
PRBool nonBlocking;
|
||||
nsresult rv = sink->IsNonBlocking(&nonBlocking);
|
||||
if (NS_FAILED(rv) || nonBlocking)
|
||||
NS_ERROR("sink should be a blocking stream");
|
||||
}
|
||||
#endif
|
||||
mSink = sink;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -319,7 +319,6 @@ nsPipe::nsPipe()
|
||||
, mWriteLimit(nsnull)
|
||||
, mStatus(NS_OK)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsPipe::~nsPipe()
|
||||
@@ -760,7 +759,7 @@ nsPipeInputStream::ReadSegments(nsWriteSegmentFun writer,
|
||||
|
||||
rv = writer(this, closure, segment, *readCount, segmentLen, &writeCount);
|
||||
|
||||
if (NS_FAILED(rv) || (writeCount == 0)) {
|
||||
if (NS_FAILED(rv) || writeCount == 0) {
|
||||
count = 0;
|
||||
// any errors returned from the writer end here: do not
|
||||
// propogate to the caller of ReadSegments.
|
||||
@@ -768,6 +767,7 @@ nsPipeInputStream::ReadSegments(nsWriteSegmentFun writer,
|
||||
break;
|
||||
}
|
||||
|
||||
NS_ASSERTION(writeCount <= segmentLen, "wrote more than expected");
|
||||
segment += writeCount;
|
||||
segmentLen -= writeCount;
|
||||
count -= writeCount;
|
||||
@@ -1095,7 +1095,7 @@ nsPipeOutputStream::WriteSegments(nsReadSegmentFun reader,
|
||||
|
||||
rv = reader(this, closure, segment, *writeCount, segmentLen, &readCount);
|
||||
|
||||
if (NS_FAILED(rv) || (readCount == 0)) {
|
||||
if (NS_FAILED(rv) || readCount == 0) {
|
||||
count = 0;
|
||||
// any errors returned from the reader end here: do not
|
||||
// propogate to the caller of WriteSegments.
|
||||
@@ -1103,6 +1103,7 @@ nsPipeOutputStream::WriteSegments(nsReadSegmentFun reader,
|
||||
break;
|
||||
}
|
||||
|
||||
NS_ASSERTION(readCount <= segmentLen, "read more than expected");
|
||||
segment += readCount;
|
||||
segmentLen -= readCount;
|
||||
count -= readCount;
|
||||
|
||||
Reference in New Issue
Block a user