зеркало из https://github.com/mozilla/gecko-dev.git
Changed doRead() to fill the stream using the IBuffer::WriteSegments api rather than Fill()... This removes an intermediate buffer copy and cleans up the code...
This commit is contained in:
Родитель
5cb58c574b
Коммит
3b9b3f2321
|
@ -598,6 +598,56 @@ nsresult nsSocketTransport::doConnection(PRInt16 aSelectFlags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_METHOD
|
||||||
|
nsReadFromSocket(void* closure,
|
||||||
|
char* toRawSegment,
|
||||||
|
PRUint32 offset,
|
||||||
|
PRUint32 count,
|
||||||
|
PRUint32 *readCount)
|
||||||
|
{
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
PRInt32 len;
|
||||||
|
PRErrorCode code;
|
||||||
|
|
||||||
|
PRFileDesc* fd = (PRFileDesc*)closure;
|
||||||
|
|
||||||
|
*readCount = 0;
|
||||||
|
|
||||||
|
len = PR_Read(fd, toRawSegment, count);
|
||||||
|
if (len > 0) {
|
||||||
|
*readCount = (PRUint32)len;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// The read operation has completed...
|
||||||
|
//
|
||||||
|
else if (len == 0) {
|
||||||
|
rv = NS_BASE_STREAM_EOF;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Error...
|
||||||
|
//
|
||||||
|
else {
|
||||||
|
code = PR_GetError();
|
||||||
|
|
||||||
|
if (PR_WOULD_BLOCK_ERROR == code) {
|
||||||
|
rv = NS_BASE_STREAM_WOULD_BLOCK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PR_LOG(gSocketLog, PR_LOG_ERROR,
|
||||||
|
("PR_Read() failed. PRErrorCode = %x\n", code));
|
||||||
|
|
||||||
|
// XXX: What should this error code be?
|
||||||
|
rv = NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PR_LOG(gSocketLog, PR_LOG_DEBUG,
|
||||||
|
("nsReadFromSocket [fd=%x]. rv = %x. Buffer space = %d. Bytes read =%d\n",
|
||||||
|
fd, rv, count, *readCount));
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
//-----
|
//-----
|
||||||
//
|
//
|
||||||
// doRead:
|
// doRead:
|
||||||
|
@ -614,9 +664,7 @@ nsresult nsSocketTransport::doConnection(PRInt16 aSelectFlags)
|
||||||
//-----
|
//-----
|
||||||
nsresult nsSocketTransport::doRead(PRInt16 aSelectFlags)
|
nsresult nsSocketTransport::doRead(PRInt16 aSelectFlags)
|
||||||
{
|
{
|
||||||
PRUint32 size, bytesWritten, totalBytesWritten;
|
PRUint32 totalBytesWritten;
|
||||||
PRInt32 len;
|
|
||||||
PRErrorCode code;
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
NS_ASSERTION(eSocketState_WaitReadWrite == mCurrentState, "Wrong state.");
|
NS_ASSERTION(eSocketState_WaitReadWrite == mCurrentState, "Wrong state.");
|
||||||
|
@ -637,67 +685,32 @@ nsresult nsSocketTransport::doRead(PRInt16 aSelectFlags)
|
||||||
rv = NS_ERROR_FAILURE;
|
rv = NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill the stream with as much data from the network as possible...
|
||||||
|
//
|
||||||
|
//
|
||||||
totalBytesWritten = 0;
|
totalBytesWritten = 0;
|
||||||
while (NS_OK == rv) {
|
rv = mReadStream->FillStream(nsReadFromSocket, (void*)mSocketFD,
|
||||||
//
|
MAX_IO_TRANSFER_SIZE, &totalBytesWritten);
|
||||||
// Determine how much space is available in the input stream...
|
PR_LOG(gSocketLog, PR_LOG_DEBUG,
|
||||||
//
|
("FillStream [fd=%x]. rv = %x. Bytes read =%d\n",
|
||||||
// Since, the data is being read into a global buffer from the net, unless
|
mSocketFD, rv, totalBytesWritten));
|
||||||
// it can all be pushed into the stream it will be lost!
|
|
||||||
//
|
//
|
||||||
rv = mReadStream->GetWriteAmount(&size);
|
// Deal with the possible return values...
|
||||||
if (size > MAX_IO_BUFFER_SIZE) {
|
//
|
||||||
size = MAX_IO_BUFFER_SIZE;
|
if (NS_BASE_STREAM_FULL == rv) {
|
||||||
}
|
if (0 == totalBytesWritten) {
|
||||||
if (size > 0) {
|
mSuspendCount += 1;
|
||||||
len = PR_Read(mSocketFD, gIOBuffer, size);
|
mReadStream->BlockTransport();
|
||||||
if (len > 0) {
|
|
||||||
rv = mReadStream->Fill(gIOBuffer, len, &bytesWritten);
|
|
||||||
NS_ASSERTION(bytesWritten == (PRUint32)len, "Data was lost during read.");
|
|
||||||
|
|
||||||
totalBytesWritten += bytesWritten;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// The read operation has completed...
|
|
||||||
//
|
|
||||||
else if (len == 0) {
|
|
||||||
rv = NS_OK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Error...
|
|
||||||
else {
|
|
||||||
code = PR_GetError();
|
|
||||||
|
|
||||||
if (PR_WOULD_BLOCK_ERROR == code) {
|
|
||||||
rv = NS_BASE_STREAM_WOULD_BLOCK;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PR_LOG(gSocketLog, PR_LOG_ERROR,
|
|
||||||
("PR_Read() failed. [this=%x]. PRErrorCode = %x\n",
|
|
||||||
this, code));
|
|
||||||
|
|
||||||
// XXX: What should this error code be?
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// There is no room in the input stream for more data...
|
|
||||||
//
|
|
||||||
// Remove this entry from the select list until the consumer has read
|
|
||||||
// some data... Since we are already holding the transport lock, just
|
|
||||||
// increment the suspend count...
|
|
||||||
//
|
|
||||||
// When the consumer makes some room in the stream, the transport will be
|
|
||||||
// resumed...
|
|
||||||
//
|
|
||||||
else {
|
|
||||||
if (0 == totalBytesWritten) {
|
|
||||||
mSuspendCount += 1;
|
|
||||||
mReadStream->BlockTransport();
|
|
||||||
}
|
|
||||||
rv = NS_BASE_STREAM_WOULD_BLOCK;
|
|
||||||
}
|
}
|
||||||
|
rv = NS_BASE_STREAM_WOULD_BLOCK;
|
||||||
|
}
|
||||||
|
else if (NS_BASE_STREAM_EOF == rv) {
|
||||||
|
rv = NS_OK;
|
||||||
|
}
|
||||||
|
else if (NS_SUCCEEDED(rv)) {
|
||||||
|
rv = NS_BASE_STREAM_WOULD_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -705,12 +718,13 @@ nsresult nsSocketTransport::doRead(PRInt16 aSelectFlags)
|
||||||
// been filled into the stream as possible...
|
// been filled into the stream as possible...
|
||||||
//
|
//
|
||||||
if (totalBytesWritten && mReadListener) {
|
if (totalBytesWritten && mReadListener) {
|
||||||
mReadListener->OnDataAvailable(mReadContext, mReadStream, mSourceOffset, totalBytesWritten);
|
mReadListener->OnDataAvailable(mReadContext, mReadStream, mSourceOffset,
|
||||||
|
totalBytesWritten);
|
||||||
mSourceOffset += totalBytesWritten;
|
mSourceOffset += totalBytesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set up the select flags for connect...
|
// Set up the select flags for read...
|
||||||
//
|
//
|
||||||
if (NS_BASE_STREAM_WOULD_BLOCK == rv) {
|
if (NS_BASE_STREAM_WOULD_BLOCK == rv) {
|
||||||
mSelectFlags |= (PR_POLL_READ | PR_POLL_EXCEPT);
|
mSelectFlags |= (PR_POLL_READ | PR_POLL_EXCEPT);
|
||||||
|
|
|
@ -33,6 +33,11 @@
|
||||||
//
|
//
|
||||||
#define MAX_IO_BUFFER_SIZE 8192
|
#define MAX_IO_BUFFER_SIZE 8192
|
||||||
|
|
||||||
|
//
|
||||||
|
// This is the maximum amount of data that will be read into a stream before
|
||||||
|
// another transport is processed...
|
||||||
|
//
|
||||||
|
#define MAX_IO_TRANSFER_SIZE 32768
|
||||||
|
|
||||||
enum nsSocketState {
|
enum nsSocketState {
|
||||||
eSocketState_Created = 0,
|
eSocketState_Created = 0,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче