Auto merge of #468 - paul-scott:master, r=badboy

Prevented uv adapter from calling write when context has been freed

The `redisLibuvPoll` function can be called with both the `UV_READABLE` and `UV_WRITABLE` flags set at the same time.  Calling `redisAsyncHandleRead` can lead to a disconnect and the context being cleaned up/freed.  If this happens then `redisAsyncHandleWrite` should not be called otherwise memory read/write errors and duplicate freeing will occur.

These changes prevent this from happening by having the `redisLibuvCleanup` callback indicate that the context has been cleaned.  This is done indirectly by setting the context to a null pointer, maybe someone can come up with a cleaner way.
This commit is contained in:
not-a-robot 2016-12-09 11:12:16 +01:00 committed by GitHub
commit b4f9fc1a2a

View File

@ -20,10 +20,10 @@ static void redisLibuvPoll(uv_poll_t* handle, int status, int events) {
return; return;
} }
if (events & UV_READABLE) { if (p->context != NULL && (events & UV_READABLE)) {
redisAsyncHandleRead(p->context); redisAsyncHandleRead(p->context);
} }
if (events & UV_WRITABLE) { if (p->context != NULL && (events & UV_WRITABLE)) {
redisAsyncHandleWrite(p->context); redisAsyncHandleWrite(p->context);
} }
} }
@ -83,6 +83,7 @@ static void on_close(uv_handle_t* handle) {
static void redisLibuvCleanup(void *privdata) { static void redisLibuvCleanup(void *privdata) {
redisLibuvEvents* p = (redisLibuvEvents*)privdata; redisLibuvEvents* p = (redisLibuvEvents*)privdata;
p->context = NULL; // indicate that context might no longer exist
uv_close((uv_handle_t*)&p->handle, on_close); uv_close((uv_handle_t*)&p->handle, on_close);
} }