Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
Windows: avoid the loop starvation bug. Closes GH-154
Browse files Browse the repository at this point in the history
  • Loading branch information
piscisaureus committed Nov 28, 2011
1 parent 01f64f6 commit fce9065
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 30 deletions.
14 changes: 6 additions & 8 deletions src/win/core.c
Expand Up @@ -204,21 +204,19 @@ static void uv_poll_ex(uv_loop_t* loop, int block) {
uv_idle_invoke((loop)); \
} \
\
/* Completely flush all pending reqs and endgames. */ \
/* We do even when we just called the idle callbacks because those may */ \
/* have closed handles or started requests that short-circuited. */ \
while ((loop)->pending_reqs_tail || (loop)->endgame_handles) { \
uv_process_endgames((loop)); \
uv_process_reqs((loop)); \
} \
uv_process_reqs((loop)); \
uv_process_endgames((loop)); \
\
if ((loop)->refs <= 0) { \
break; \
} \
\
uv_prepare_invoke((loop)); \
\
poll((loop), (loop)->idle_handles == NULL && (loop)->refs > 0); \
poll((loop), (loop)->idle_handles == NULL && \
(loop)->pending_reqs_tail == NULL && \
(loop)->endgame_handles == NULL && \
(loop)->refs > 0); \
\
uv_check_invoke((loop)); \
}
Expand Down
36 changes: 14 additions & 22 deletions src/win/req.c
Expand Up @@ -51,27 +51,6 @@ void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
}


static uv_req_t* uv_remove_pending_req(uv_loop_t* loop) {
uv_req_t* req;

if (loop->pending_reqs_tail) {
req = loop->pending_reqs_tail->next_req;

if (req == loop->pending_reqs_tail) {
loop->pending_reqs_tail = NULL;
} else {
loop->pending_reqs_tail->next_req = req->next_req;
}

return req;

} else {
/* queue empty */
return NULL;
}
}


#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \
do { \
switch (((uv_handle_t*) (req)->handle_at)->type) { \
Expand Down Expand Up @@ -101,8 +80,21 @@ static uv_req_t* uv_remove_pending_req(uv_loop_t* loop) {

void uv_process_reqs(uv_loop_t* loop) {
uv_req_t* req;
uv_req_t* first;
uv_req_t* next;

if (loop->pending_reqs_tail == NULL) {
return;
}

first = loop->pending_reqs_tail->next_req;
next = first;
loop->pending_reqs_tail = NULL;

while (next != NULL) {
req = next;
next = req->next_req != first ? req->next_req : NULL;

while (req = uv_remove_pending_req(loop)) {
switch (req->type) {
case UV_READ:
DELEGATE_STREAM_REQ(loop, req, read, data);
Expand Down

0 comments on commit fce9065

Please sign in to comment.