Re: Bizarre x86 segment layout problem causing select() slowdown
Re: Bizarre x86 segment layout problem causing select() slowdown
- Subject: Re: Bizarre x86 segment layout problem causing select() slowdown
- From: Dave Hayden <email@hidden>
- Date: Tue, 6 Feb 2007 16:38:04 -0800
On Feb 6, 2007, at 3:33 PM, Eric Albert wrote:
Can you show us the code where you call select()? That'll probably
help here.
Here's the inner select/read bit:
fd_set readmask;
struct timeval timeout = { socketTimeout, 0 };
int res;
FD_ZERO(&readmask);
FD_SET(sock, &readmask);
res = select(sock + 1, &readmask, NULL, NULL, &timeout);
if ( res < 0 )
return NNTP_ERR_READ_FAILED;
if ( res == 0 || !FD_ISSET(sock, &readmask) )
{
[self appendReadTranscript:@"*** (%i) Read timed out", sock];
[self writeLine:@"QUIT"];
[self close];
return NNTP_ERR_READ_TIMEDOUT;
}
if ( ssl != NULL )
count = SSL_read(ssl, buffer + bufptr, bufferLength - bufptr);
else
count = read(sock, buffer + bufptr, bufferLength - bufptr);
FWIW, here's the entire function:
- (NNTPErr)readLine:(char**)outLine length:(int*)outLength log:(BOOL)log
{
// load the rest of the available data, null out the newline, return
pointer to
// beginning of line
char* p = &buffer[lineptr];
char* end = &buffer[bufptr];
[self setStatusMessage:nil];
lastActivityTime = [NSDate timeIntervalSinceReferenceDate];
// look for newline in buffered data
for ( ;; )
{
int count = 0;
while ( p < end )
{
if ( *p == '\n' )
break;
++p;
}
if ( p < end && *p == '\n' )
{
char* line = &buffer[lineptr];
int length = p - line;
bytesReceived += length;
*p = '\0';
lineptr = p + 1 - buffer;
// strip \r if it's there
while ( length > 0 && *--p == '\r' )
{
*p = '\0';
--length;
}
if ( lineptr == bufferLength && bufptr == bufferLength )
{
lineptr = 0;
bufptr = 0;
}
*outLength = length;
*outLine = line;
if ( log )
[self appendReadTranscript:@"%s", *outLine];
return NNTP_ERR_OK;
}
if ( lineptr == 0 && bufptr == bufferLength )
{
// we filled up the buffer without finding a newline
*outLength = bufferLength;
*outLine = buffer;
bufptr = 0;
if ( log )
[self appendReadTranscript:@"%s", *outLine];
return NNTP_ERR_OK;
}
// we don't have a complete line in the buffer, so move what we've
got to the head
if ( lineptr != bufptr && lineptr != 0 )
{
bufptr -= lineptr;
memmove(buffer, &buffer[lineptr], bufptr);
p -= lineptr;
lineptr = 0;
}
// do a read
if ( sock == -1 )
return NNTP_ERR_READ_FAILED;
// Don't select() before SSL_read! The SSL may have data while the
socket's dry. If the SSL layer is dry, too, SSL_read returns 0.
if ( ssl != NULL )
count = SSL_read(ssl, buffer + bufptr, bufferLength - bufptr);
if ( count == 0 )
{
fd_set readmask;
struct timeval timeout = { socketTimeout, 0 };
int res;
FD_ZERO(&readmask);
FD_SET(sock, &readmask);
res = select(sock + 1, &readmask, NULL, NULL, &timeout);
if ( res < 0 )
return NNTP_ERR_READ_FAILED;
if ( res == 0 || !FD_ISSET(sock, &readmask) )
{
[self appendReadTranscript:@"*** (%i) Read timed out", sock];
[self writeLine:@"QUIT"];
[self close];
return NNTP_ERR_READ_TIMEDOUT;
}
if ( ssl != NULL )
count = SSL_read(ssl, buffer + bufptr, bufferLength - bufptr);
else
count = read(sock, buffer + bufptr, bufferLength - bufptr);
}
lastActivityTime = [NSDate timeIntervalSinceReferenceDate];
if ( count == -1 )
{
TRACE(@"NNTPSocket.readLine: *** read failed");
[self appendReadTranscript:@"*** (%i) Read failed", sock];
[self close];
if ( errno == EWOULDBLOCK )
return NNTP_ERR_READ_TIMEDOUT;
if ( errno == ECONNRESET )
return NNTP_ERR_CONNECTION_CLOSED;
return NNTP_ERR_READ_FAILED;
}
if ( count == 0 )
{
[self close];
TRACE(@"NNTPSocket.readLine: *** connection closed");
return NNTP_ERR_CONNECTION_CLOSED;
}
bufptr += count;
// and search again
end = &buffer[bufptr];
}
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden