First try with buffered readline.

More efficient for remote servers but a big performance bug for local ones.
See http://sourceforge.net/bugs/?func=detailbug&bug_id=104290&group_id=4581
buffered-read-3-0-BETA
Stephane Bortzmeyer 24 years ago
parent 6ca0e5e291
commit dc3b8101fd

@ -391,6 +391,8 @@ main (argc, argv)
for (i = 1; i <= number; i++) for (i = 1; i <= number; i++)
{ {
clear_read_buffer();
attempts++; attempts++;
if (!udp) if (!udp)
{ {

@ -3,9 +3,7 @@
#define DEFLINE 256 #define DEFLINE 256
#define MAXLINE 65535 #define MAXLINE 65535
#define UDPMAX 65535 #define UDPMAX 65535
#ifdef HTTP
#define MAXTOREAD 150000 #define MAXTOREAD 150000
#endif
#define MAXNUMBER 20 #define MAXNUMBER 20
/* Settings you should not change */ /* Settings you should not change */
@ -95,6 +93,7 @@ char *sys_err_str ();
int writen (); int writen ();
/* readline.c */ /* readline.c */
int readline (); int readline ();
void clear_read_buffer ();
/* util.c */ /* util.c */
char *random_string (); char *random_string ();
void tvsub (); void tvsub ();

@ -68,6 +68,7 @@ read_from_server (int fd)
while (!body) while (!body)
{ {
nr = readline (fd, big_recvline, MAXTOREAD, TRUE); nr = readline (fd, big_recvline, MAXTOREAD, TRUE);
/* printf ("DEBUG HTTP, I got (%s)\n", big_recvline); */
/* HTTP replies should be separated by CR-LF. Unfortunately, some /* HTTP replies should be separated by CR-LF. Unfortunately, some
servers send only CR :-( */ servers send only CR :-( */
body = ((nr == 2) || (nr == 1)); /* Empty line CR-LF seen */ body = ((nr == 2) || (nr == 1)); /* Empty line CR-LF seen */
@ -91,8 +92,9 @@ read_from_server (int fd)
nr = readline (fd, big_recvline, MAXTOREAD, FALSE); nr = readline (fd, big_recvline, MAXTOREAD, FALSE);
if ((nr < 2) && (errno == EINTR)) /* Probably a timeout */ if ((nr < 2) && (errno == EINTR)) /* Probably a timeout */
return -1; return -1;
if (nr < 2) /* Hmm, if the body is empty, we'll get a meaningless error message */ if (nr < 2) /* Hmm, if the body is empty, we'll
err_sys ("Reading HTTP body"); get a meaningless error message */
err_sys ("Reading HTTP body, may be empty");
total = total + nr; total = total + nr;
return total; /* How to do if we want only the body's size? */ return total; /* How to do if we want only the body's size? */
} }

@ -1,18 +1,19 @@
/* /*
* Read a line from a descriptor. Read the line one byte at a time, looking * Read a line from a descriptor.
* for the newline. We store the newline in the buffer, then follow it with
* a null (the same as fgets(3)). We return the number of characters up to,
* but not including, the null (the same as strlen(3)). If ln == 0, we treat
* newline as an ordinary charracter.
* *
* Stolen from Stevens' book * To save read() system calls, we first check the static buffer if it
* still contains data. If so, we send it back. Otherwise, we call
* read().
* *
* $Id$ * If ln == 0, we treat newline as an ordinary charracter.
* *
*/ * $Id$
* */
#include "echoping.h" #include "echoping.h"
char buffer[MAXTOREAD]; /* Must survive between calls to readline */
int int
readline (fd, ptr, maxlen, ln) readline (fd, ptr, maxlen, ln)
int fd; int fd;
@ -20,30 +21,71 @@ readline (fd, ptr, maxlen, ln)
int maxlen; int maxlen;
unsigned short ln; unsigned short ln;
{ {
int n, rc; char *origptr = ptr;
char c; int n, i, j, rc;
char s[maxlen];
int bufend = strlen(buffer);
for (n = 1; n < maxlen; n++) n = 0;
/* Use the buffer if it is still full */
for (i = 0; i < strlen(buffer); i++) {
*ptr++ = buffer[i];
n++;
if (buffer[i] == '\n' && ln == 1)
break;
}
if (n) {
/* printf ("DEBUG, got %d bytes from the buffer\n", i); */
strcpy (buffer, (char *)(buffer+i+1));
*ptr = 0;
return (n);
}
bufend = strlen (buffer);
reading:
for (; n < maxlen;)
{ {
if (timeout_flag) if (timeout_flag)
return n; return n;
if ((rc = read (fd, &c, 1)) == 1) if ((rc = read (fd, &s, maxlen)) > 0)
{ {
*ptr++ = c; /* printf ("DEBUG, %d bytes asked (nl = %d) %d bytes read\n", maxlen, ln, rc); */
if (c == '\n' && ln == 1) parsing:
for (i = 0; i < rc; i++) {
*ptr++ = s[i];
/* printf ("DEBUG, adding %c ", s[i]); */
n++;
if (s[i] == '\n' && ln == 1) {
for (j = i+1; j < rc; j++) {
buffer[bufend++] = s[j];
}
break;
}
}
if (s[i] == '\n' && ln == 1) {
break; break;
}
} }
else if (rc == 0) else if (rc == 0)
{ {
if (n == 1) if (n == 1)
return (0); /* EOF, no data read */ return (0); /* EOF, no data read */
else else {
n++;
break; /* EOF, some data was read */ break; /* EOF, some data was read */
}
} }
else else
return (-1); /* error */ return (-1); /* error */
} }
*ptr = 0; *ptr = 0;
/* printf ("DEBUG, Returning %d bytes (%s)\n", n, origptr); */
return (n); return (n);
} }
void clear_read_buffer () {
buffer[0] = 0;
}

Loading…
Cancel
Save