User:Brahmana/Netwerk Docs/Stream Operations

From MozillaWiki
< User:Brahmana‎ | Netwerk Docs
Revision as of 00:14, 31 December 2008 by Brahmana (talk | contribs) (Created the page with the class diagram)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
Stream Pump Listener.png

The three main players are and a small player:

  • nsIInputStream - The Stream
  • nsIStreamListener - The Listener
  • nsIInputStreamPump - The Pump
    • nsIInputStreamCallback - The Callback

(Forget the super classes)

The Stream is a straight forward thing and here it represents a stream of data that can be read. The stream can be blocking or non-blocking. Lets assume for now that it is not blocking. Now the standard way of reading from the stream would be to poll the stream at some regular intervals and ask it if there is some data. If it says yes then we call read.

To avoid this, there are stream listeners, The Listener in our case. The Listener provides methods to notify it of Start, Stop and data availability. Now we would expect The Stream to take this listener and call the methods on it. But that is not how it works here. Probably because it is not a good to tie the listener with Stream. Honestly I do not know the precise reason. It might have something to do with blocking streams. Basically you cannot just directly pass a listener to a stream and ask it to notify you when there is data. [biesi: Any explanation?]

This is where The Pump comes into picture. The pump takes a stream and a listener and plays the mediator between the two. It basically factors out the responsibility of notifying a listener from the stream.

If the stream is non-blocking and also implements nsIAsyncInputStream, the pump just calls AsyncWait on the stream and the stream notifies the pump with the callback whether the stream is ready. It might notify readiness for reading or for closing. If its readiness for read the pump then fetches info about the available data like its size and all and passes it to the stream listener along with the stream from which the listener ultimately reads the data.

If the stream is a blocking one and does not implement nsIAsyncStream, then the pump creates a nsITransport using the nsIStreamTransportService. This nsITransport takes the blocking stream and returns a stream that implements nsIAsyncStream. Essentially, the pump gets a nsIAsyncStream and calls asyncWait() on that to get notified. This happens in EnsureWaiting(). Since we get one notification for every call to asyncWait(), EnsureWaiting() is called after processing every callback notification.

With this the user of this stream can create a StreamPump and pass his listener to it. The pump will then notify the listener about the Start, Stop and availability of data.