try to avoid extra syscalls when reading sockets
so far we shifted down the buffered data only when we ran out of space. however, that may cause chopping up the actual socket read, which is a bad trade-off with avoiding a moderate-sized memmove. so try to keep enough space for the anticipated read size. note that this ignores the zlib path, as that always does full-size socket reads into z_buf, and saving inflate() calls seems pointless.
This commit is contained in:
parent
ac3b5186b0
commit
859b7dd7f2
16
src/socket.c
16
src/socket.c
|
@ -407,6 +407,7 @@ socket_start_deflate( conn_t *conn )
|
||||||
}
|
}
|
||||||
|
|
||||||
init_wakeup( &conn->z_fake, z_fake_cb, conn );
|
init_wakeup( &conn->z_fake, z_fake_cb, conn );
|
||||||
|
conn->readsz = 0; // This optimization makes no sense past this point
|
||||||
}
|
}
|
||||||
#endif /* HAVE_LIBZ */
|
#endif /* HAVE_LIBZ */
|
||||||
|
|
||||||
|
@ -726,8 +727,9 @@ socket_filled( conn_t *conn, uint len )
|
||||||
uint cnt = conn->bytes + len;
|
uint cnt = conn->bytes + len;
|
||||||
conn->bytes = cnt;
|
conn->bytes = cnt;
|
||||||
if (conn->wanted) {
|
if (conn->wanted) {
|
||||||
// Fulfill as much of the request as still fits into the buffer
|
// Fulfill as much of the request as still fits into the buffer,
|
||||||
if (cnt < conn->wanted && off + cnt < sizeof(conn->buf))
|
// but avoid chopping up the actual socket reads
|
||||||
|
if (cnt < conn->wanted && off + cnt < sizeof(conn->buf) - conn->readsz)
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Need a full line
|
// Need a full line
|
||||||
|
@ -735,7 +737,7 @@ socket_filled( conn_t *conn, uint len )
|
||||||
char *p = memchr( s + conn->scanoff, '\n', cnt - conn->scanoff );
|
char *p = memchr( s + conn->scanoff, '\n', cnt - conn->scanoff );
|
||||||
if (!p) {
|
if (!p) {
|
||||||
conn->scanoff = cnt;
|
conn->scanoff = cnt;
|
||||||
if (off + cnt == sizeof(conn->buf)) {
|
if (off && off + cnt >= sizeof(conn->buf) - conn->readsz) {
|
||||||
memmove( conn->buf, conn->buf + off, cnt );
|
memmove( conn->buf, conn->buf + off, cnt );
|
||||||
conn->offset = 0;
|
conn->offset = 0;
|
||||||
}
|
}
|
||||||
|
@ -803,6 +805,12 @@ socket_fill( conn_t *sock )
|
||||||
if ((n = do_read( sock, buf, len )) <= 0)
|
if ((n = do_read( sock, buf, len )) <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// IIR filter for tracking average size of bulk reads.
|
||||||
|
// We use this to optimize the free space at the end of the
|
||||||
|
// buffer, hence the factor of 1.5.
|
||||||
|
if (n >= MIN_BULK_READ)
|
||||||
|
sock->readsz = (sock->readsz * 3 + n * 3 / 2) / 4;
|
||||||
|
|
||||||
socket_filled( sock, (uint)n );
|
socket_filled( sock, (uint)n );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -831,7 +839,7 @@ socket_expect_bytes( conn_t *conn, uint len )
|
||||||
if (off) {
|
if (off) {
|
||||||
uint cnt = conn->bytes;
|
uint cnt = conn->bytes;
|
||||||
if (off + len > sizeof(conn->buf) ||
|
if (off + len > sizeof(conn->buf) ||
|
||||||
off + cnt == sizeof(conn->buf)) {
|
off + cnt >= sizeof(conn->buf) - conn->readsz) {
|
||||||
memmove( conn->buf, conn->buf + off, cnt );
|
memmove( conn->buf, conn->buf + off, cnt );
|
||||||
conn->offset = 0;
|
conn->offset = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,12 +100,16 @@ typedef struct {
|
||||||
uint bytes; /* number of filled bytes in buffer */
|
uint bytes; /* number of filled bytes in buffer */
|
||||||
uint scanoff; /* offset to continue scanning for newline at, relative to 'offset' */
|
uint scanoff; /* offset to continue scanning for newline at, relative to 'offset' */
|
||||||
uint wanted; // try to accumulate that many bytes before calling back; 0 => full line
|
uint wanted; // try to accumulate that many bytes before calling back; 0 => full line
|
||||||
|
uint readsz; // average size of bulk reads from the underlying socket, times 1.5
|
||||||
char buf[100000];
|
char buf[100000];
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
char z_buf[100000];
|
char z_buf[100000];
|
||||||
#endif
|
#endif
|
||||||
} conn_t;
|
} conn_t;
|
||||||
|
|
||||||
|
// Shorter reads are assumed to be limited by round-trips.
|
||||||
|
#define MIN_BULK_READ 1000
|
||||||
|
|
||||||
/* call this before doing anything with the socket */
|
/* call this before doing anything with the socket */
|
||||||
static INLINE void socket_init( conn_t *conn,
|
static INLINE void socket_init( conn_t *conn,
|
||||||
const server_conf_t *conf,
|
const server_conf_t *conf,
|
||||||
|
@ -123,6 +127,7 @@ static INLINE void socket_init( conn_t *conn,
|
||||||
conn->name = NULL;
|
conn->name = NULL;
|
||||||
conn->write_buf_append = &conn->write_buf;
|
conn->write_buf_append = &conn->write_buf;
|
||||||
conn->wanted = 1;
|
conn->wanted = 1;
|
||||||
|
conn->readsz = MIN_BULK_READ * 3 / 2;
|
||||||
}
|
}
|
||||||
void socket_connect( conn_t *conn, void (*cb)( int ok, void *aux ) );
|
void socket_connect( conn_t *conn, void (*cb)( int ok, void *aux ) );
|
||||||
void socket_start_tls(conn_t *conn, void (*cb)( int ok, void *aux ) );
|
void socket_start_tls(conn_t *conn, void (*cb)( int ok, void *aux ) );
|
||||||
|
|
Loading…
Reference in New Issue
Block a user