diff --git a/src/unix/stream.c b/src/unix/stream.c index 6f0d1378..bcfa1c93 100644 --- a/src/unix/stream.c +++ b/src/unix/stream.c @@ -523,12 +523,19 @@ static void uv__read(uv_stream_t* stream) { struct cmsghdr* cmsg; char cmsg_space[64]; struct ev_loop* ev = stream->loop->ev; + int count; + + /* Prevent loop starvation when the data comes in as fast as (or faster than) + * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O. + */ + count = 32; /* XXX: Maybe instead of having UV_READING we just test if * tcp->read_cb is NULL or not? */ - while ((stream->read_cb || stream->read2_cb) && - stream->flags & UV_READING) { + while ((stream->read_cb || stream->read2_cb) + && (stream->flags & UV_READING) + && (count-- > 0)) { assert(stream->alloc_cb); buf = stream->alloc_cb((uv_handle_t*)stream, 64 * 1024); diff --git a/src/unix/udp.c b/src/unix/udp.c index 349bfae3..7d58fd9f 100644 --- a/src/unix/udp.c +++ b/src/unix/udp.c @@ -208,12 +208,17 @@ static void uv__udp_recvmsg(uv_udp_t* handle) { ssize_t nread; uv_buf_t buf; int flags; + int count; assert(handle->recv_cb != NULL); assert(handle->alloc_cb != NULL); + /* Prevent loop starvation when the data comes in as fast as (or faster than) + * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O. + */ + count = 32; + do { - /* FIXME: hoist alloc_cb out the loop but for now follow uv__read() */ buf = handle->alloc_cb((uv_handle_t*)handle, 64 * 1024); assert(buf.len > 0); assert(buf.base != NULL); @@ -254,6 +259,7 @@ static void uv__udp_recvmsg(uv_udp_t* handle) { } /* recv_cb callback may decide to pause or close the handle */ while (nread != -1 + && count-- > 0 && handle->fd != -1 && handle->recv_cb != NULL); }