I've been thinking for some time now about changing the interface
of nsIChannel::AsyncWrite. The way it is currently defined doesn't
seem to be very consistent with AsyncRead, and my feeling is that
now is the right time to fix it.
I've been discussing this some on the newsgroup and with others in
the necko group. There's been some interesting feedback. Basically,
my change to AsyncWrite is actually more or less a cosmetic change...
it is just a matter of clarifying what AsyncWrite really means.
What I want to do is change AsyncWrite from:
AsyncWrite(in nsIInputStream source,
in nsIStreamObserver observer,
in nsISupports ctxt);
to
AsyncWrite(in nsIStreamProvider provider,
in nsISupports ctxt);
where nsIStreamProvider is a new interface defined as:
interface nsIStreamProvider : nsIStreamObserver
{
void onProvideData(in nsIChannel channel,
in nsISupports ctxt,
in nsIOutputStream output,
in unsigned long offset,
in unsigned long count);
};
The offset parameter is informational only and can, in most cases,
simply be ignored. It tells you what the current stream position
is and hence how much has been written. The count parameter tells
you how much data you can write to the output stream w/o blocking.
The point is to make it very clear that the channel will request
data from the consumer when it knows that the underlying transport
is ready to accept it. If you think about it, this is no different
than having the channel call Read on the source input stream... it
just clarifies what we are really doing (IMHO).
Writing zero bytes to the output stream (or returning without
writing anything) in response to onProvideData would signify EOF.
If data is not available for writing, then the channel would
have to be suspended (in some manner... probably with the Suspend
method) and then resumed when data is made available. In this
case returning without writing data would be ok.
I've coded up these interface changes. You can see them (from
within the netscape firewall) at
http://status/~darin/idl/nsIChannel.idl
http://status/~darin/idl/nsIStreamProvider.idl
Please take a look at these, and let me know what you think :)
I think it is going to be important for us to start taking advantage
of AsyncWrite, especially in the new cache design. Fortunately, no
one in mozilla calls AsyncWrite at the moment (at least not from
outside necko), so making this change should be fairly painless. I
just want to get some feedback and consensus before moving on it.
Thanks in advance,
Darin
ps. I'm hoping to work this into the trunk ASAP because it is going
to effect both the new cache and imagelib2 as well as many of the
Necko protocols (HTTP, FTP, and FILE in particular).
pps. Feel free to suggest other names for nsIStreamProvider and
onProvideData. I'm looking for something consistent with AsyncRead's
nsIStreamListener and onDataAvailable.