Hiredis: report a bug:with libuv async request, two problem and solutions

Created on 6 Nov 2019  ·  13Comments  ·  Source: redis/hiredis

1.First problem:

include

In this file:
// this is right,because c-fd already is socket fd.
--if (uv_poll_init(loop, &p->handle, c->fd) != 0) {
++if (uv_poll_init_socket(loop, &p->handle, c->fd) != 0) {
return REDIS_ERR;
}
2.Second problem:
redisAsyncConnect -> ... ->_redisContextConnectTcp:
In this function, (origin report "Error: setsockopt(TCP_NODELAY): Input/output error")
if (blocking && redisSetBlocking(c,1) != REDIS_OK)
goto error;
++#ifndef _MSC_VER
++ sleep(0);
++#else
++ _sleep(0);
++#endif
if (redisSetTcpNoDelay(c) != REDIS_OK)
goto error;

Please confirm and repair it.

All 13 comments

Hi @xingyun86, can you post this as a git patch that I can apply?

Hi @xingyun86, can you post this as a git patch that I can apply?

patch-20191107.zip

Hey @mnunberg, @mbitsnbites

I don't have a Windows machine but taking a look at the libuv docs it looks like this change to adapters/libuv.h might be correct.

diff --git adapters/libuv.h adapters/libuv.h
index 39ef7cf..049096e 100644
--- adapters/libuv.h
+++ adapters/libuv.h
@@ -84,7 +84,6 @@ static void redisLibuvCleanup(void *privdata) {
   uv_close((uv_handle_t*)&p->handle, on_close);
 }

-
 static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) {
   redisContext *c = &(ac->c);

@@ -106,7 +105,7 @@ static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) {

   memset(p, 0, sizeof(*p));

-  if (uv_poll_init(loop, &p->handle, c->fd) != 0) {
+  if (uv_poll_init_socket(loop, &p->handle, c->fd) != 0) {
     return REDIS_ERR;
   }

Relevant section:

int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, uv_os_sock_t socket)¶
Initialize the handle using a socket descriptor. On Unix this is identical to uv_poll_init(). On windows it takes a SOCKET handle.

And @xingyun86 can you explain why you're yielding control in the second change? What problem is this solving?

diff --git net.c net.c
index e5f40b0..342d292 100644
--- net.c
+++ net.c
@@ -478,6 +478,13 @@ addrretry:
         }
         if (blocking && redisSetBlocking(c,1) != REDIS_OK)
             goto error;
+
+#ifndef _MSC_VER
+               sleep(0);
+#else
+               _sleep(0);
+#endif // !_MSC_VER
+

Hey @mnunberg, @mbitsnbites

I don't have a Windows machine but taking a look at the libuv docs it looks like this change to adapters/libuv.h might be correct.

diff --git adapters/libuv.h adapters/libuv.h
index 39ef7cf..049096e 100644
--- adapters/libuv.h
+++ adapters/libuv.h
@@ -84,7 +84,6 @@ static void redisLibuvCleanup(void *privdata) {
   uv_close((uv_handle_t*)&p->handle, on_close);
 }

-
 static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) {
   redisContext *c = &(ac->c);

@@ -106,7 +105,7 @@ static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) {

   memset(p, 0, sizeof(*p));

-  if (uv_poll_init(loop, &p->handle, c->fd) != 0) {
+  if (uv_poll_init_socket(loop, &p->handle, c->fd) != 0) {
     return REDIS_ERR;
   }

Relevant section:

int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, uv_os_sock_t socket)¶
Initialize the handle using a socket descriptor. On Unix this is identical to uv_poll_init(). On windows it takes a SOCKET handle.

And @xingyun86 can you explain why you're yielding control in the second change? What problem is this solving?

diff --git net.c net.c
index e5f40b0..342d292 100644
--- net.c
+++ net.c
@@ -478,6 +478,13 @@ addrretry:
         }
         if (blocking && redisSetBlocking(c,1) != REDIS_OK)
             goto error;
+
+#ifndef _MSC_VER
+               sleep(0);
+#else
+               _sleep(0);
+#endif // !_MSC_VER
+

图片

图片

Yes, I think you're right about libuv init function from their docs, I just don't have a windows machine to check. :smile:

////////////////////////////////////////////////////////////////////////////////////////////
diff --git net.c net.c
index e5f40b0..342d292 100644
--- net.c
+++ net.c
@@ -478,6 +478,13 @@ addrretry:
         }
         if (blocking && redisSetBlocking(c,1) != REDIS_OK)
             goto error;
+
+#ifndef _MSC_VER
+               sleep(0);
+#else
+               _sleep(0);
+#endif // !_MSC_VER
+
////////////////////////////////////////////////////////////////////////////////////////////

This modify on Linux does not need. The last modify is:

////////////////////////////////////////////////////////////////////////////////////////////
diff --git net.c net.c
index e5f40b0..342d292 100644
--- net.c
+++ net.c
@@ -478,6 +478,13 @@ addrretry:
         }
         if (blocking && redisSetBlocking(c,1) != REDIS_OK)
             goto error;
+
+#ifdef _MSC_VER
+               _sleep(0);
+#endif // !_MSC_VER
+
////////////////////////////////////////////////////////////////////////////////////////////

I have tested both Windows and Linux.

At least make a PR of this before merging, to get Travis testing first.

Of course. I just tagged you because you're on many of the Windows based commits.

@xingyun86 Do you mind creating a PR?

Of course. I just tagged you because you're on many of the Windows based commits.

@xingyun86 Do you mind creating a PR?

What I can do? How to do it?

Just fork the repo then commit the changes you want and submit a pull request.

I'm happy to do it but then you wouldn't get any credit (in the git history). 😃

Just fork the repo then commit the changes you want and submit a pull request.

I'm happy to do it but then you wouldn't get any credit (in the git history). 😃

Ok.I had done it. https://github.com/redis/hiredis/pull/736

Closing in favor of #736

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ShePastAway0 picture ShePastAway0  ·  7Comments

yudataguy picture yudataguy  ·  10Comments

noloader picture noloader  ·  10Comments

guotie picture guotie  ·  8Comments

kenden picture kenden  ·  5Comments