Skip to content

Instantly share code, notes, and snippets.

@piscisaureus
Created November 26, 2011 23:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save piscisaureus/38095e87e6df011bcf58 to your computer and use it in GitHub Desktop.
Save piscisaureus/38095e87e6df011bcf58 to your computer and use it in GitHub Desktop.
From 0ea8558505d0ba08f53ab0b120a0f15f38ef5b80 Mon Sep 17 00:00:00 2001
From: Bert Belder <bertbelder@gmail.com>
Date: Sun, 27 Nov 2011 00:46:19 +0100
Subject: [PATCH 1/1] Loop starvation quickfix
---
src/win/core.c | 14 ++++++--------
src/win/req.c | 36 ++++++++++++++----------------------
2 files changed, 20 insertions(+), 30 deletions(-)
diff --git a/src/win/core.c b/src/win/core.c
index 4914fb4..e6bcc5f 100644
--- a/src/win/core.c
+++ b/src/win/core.c
@@ -204,13 +204,8 @@ 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; \
@@ -218,7 +213,10 @@ static void uv_poll_ex(uv_loop_t* loop, int block) {
\
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)); \
}
diff --git a/src/win/req.c b/src/win/req.c
index dd2b388..65aa6c1 100644
--- a/src/win/req.c
+++ b/src/win/req.c
@@ -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) { \
@@ -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);
--
1.7.7.1.msysgit.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment