diff --git a/Document-poll-2-logic-changes.patch b/Document-poll-2-logic-changes.patch new file mode 100644 index 0000000000000000000000000000000000000000..78f7b3eaf679b50b4b6571592a4c55e5a8f0b244 --- /dev/null +++ b/Document-poll-2-logic-changes.patch @@ -0,0 +1,32 @@ +From f8dfdfbe051a678d8373fe286e736652060dc492 Mon Sep 17 00:00:00 2001 +From: michael-grunder +Date: Tue, 25 Jul 2023 10:38:00 -0700 +Subject: [PATCH] Document poll(2) logic changes. + +See #1206, #1213 +--- + README.md | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/README.md b/README.md +index 74364b411..c0fc2a1cc 100644 +--- a/README.md ++++ b/README.md +@@ -23,6 +23,17 @@ Redis version >= 1.2.0. + The library comes with multiple APIs. There is the + *synchronous API*, the *asynchronous API* and the *reply parsing API*. + ++## Upgrading to > 1.2.0 (**PRERELEASE**) ++ ++* After v1.2.0 we modified how we invoke `poll(2)` to wait for connections to complete, such that we will now retry ++ the call if it is interrupted by a signal until: ++ ++ a) The connection succeeds or fails. ++ b) The overall connection timeout is reached. ++ ++ In previous versions, an interrupted `poll(2)` call would cause the connection to fail ++ with `c->err` set to `REDIS_ERR_IO` and `c->errstr` set to `poll(2): Interrupted system call`. ++ + ## Upgrading to `1.1.0` + + Almost all users will simply need to recompile their applications against the newer version of hiredis. diff --git a/Fix-memory-leak.patch b/Fix-memory-leak.patch new file mode 100644 index 0000000000000000000000000000000000000000..9faad79f66ad1095ae63a0827b071f533ceee8e8 --- /dev/null +++ b/Fix-memory-leak.patch @@ -0,0 +1,24 @@ +From 0084435a5fdfdd478bae1d2118bfd0ed37851ace Mon Sep 17 00:00:00 2001 +From: Mark Agranat +Date: Tue, 14 Nov 2023 23:53:25 +0100 +Subject: [PATCH] Fix memory leak. + +When redisLibuvAttach receives error from call to +uv_poll_init_socket there is a memory leaked ptr +of type redisLibuvEvents. +--- + adapters/libuv.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/adapters/libuv.h b/adapters/libuv.h +index 268edab79..ec67c15a2 100644 +--- a/adapters/libuv.h ++++ b/adapters/libuv.h +@@ -159,6 +159,7 @@ static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) { + memset(p, 0, sizeof(*p)); + + if (uv_poll_init_socket(loop, &p->handle, c->fd) != 0) { ++ hi_free(p); + return REDIS_ERR; + } + diff --git a/Retry-poll-2-if-we-are-intterupted.patch b/Retry-poll-2-if-we-are-intterupted.patch new file mode 100644 index 0000000000000000000000000000000000000000..a67f05b2e42d8315b67f471fa8ceaab14ad03301 --- /dev/null +++ b/Retry-poll-2-if-we-are-intterupted.patch @@ -0,0 +1,101 @@ +From 97679e57badd4df954e083f4aa5408d29b39785f Mon Sep 17 00:00:00 2001 +From: michael-grunder +Date: Wed, 12 Jul 2023 14:23:07 -0700 +Subject: [PATCH] Retry poll(2) if we are intterupted. + +This commit adds logic to retry our poll call when waiting for the +connection to complete, in the event that we are interrupted by a +signal. + +Additionally we do some simple bookkeeping to keep track of the overall +timeout specified by the user. + +Fixes #1206 +--- + net.c | 52 +++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 35 insertions(+), 17 deletions(-) + +diff --git a/net.c b/net.c +index 1e016384f..c7d827139 100644 +--- a/net.c ++++ b/net.c +@@ -41,6 +41,7 @@ + #include + #include + #include ++#include + + #include "net.h" + #include "sds.h" +@@ -271,37 +272,54 @@ static int redisContextTimeoutMsec(redisContext *c, long *result) + return REDIS_OK; + } + ++static long redisPollMillis(void) { ++#ifndef _MSC_VER ++ struct timespec now; ++ clock_gettime(CLOCK_MONOTONIC, &now); ++ return (now.tv_sec * 1000) + now.tv_nsec / 1000000; ++#else ++ FILETIME ft; ++ GetSystemTimeAsFileTime(&ft); ++ return (((long long)ft.dwHighDateTime << 32) | ft.dwLowDateTime) / 10; ++#endif ++} ++ + static int redisContextWaitReady(redisContext *c, long msec) { +- struct pollfd wfd[1]; ++ struct pollfd wfd; ++ long end; ++ int res; + +- wfd[0].fd = c->fd; +- wfd[0].events = POLLOUT; ++ if (errno != EINPROGRESS) { ++ __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); ++ redisNetClose(c); ++ return REDIS_ERR; ++ } + +- if (errno == EINPROGRESS) { +- int res; ++ wfd.fd = c->fd; ++ wfd.events = POLLOUT; ++ end = msec >= 0 ? redisPollMillis() + msec : 0; + +- if ((res = poll(wfd, 1, msec)) == -1) { ++ while ((res = poll(&wfd, 1, msec)) <= 0) { ++ if (res < 0 && errno != EINTR) { + __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)"); + redisNetClose(c); + return REDIS_ERR; +- } else if (res == 0) { ++ } else if (res == 0 || (msec >= 0 && redisPollMillis() >= end)) { + errno = ETIMEDOUT; +- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); ++ __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL); + redisNetClose(c); + return REDIS_ERR; ++ } else { ++ /* res < 0 && errno == EINTR, try again */ + } ++ } + +- if (redisCheckConnectDone(c, &res) != REDIS_OK || res == 0) { +- redisCheckSocketError(c); +- return REDIS_ERR; +- } +- +- return REDIS_OK; ++ if (redisCheckConnectDone(c, &res) != REDIS_OK || res == 0) { ++ redisCheckSocketError(c); ++ return REDIS_ERR; + } + +- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); +- redisNetClose(c); +- return REDIS_ERR; ++ return REDIS_OK; + } + + int redisCheckConnectDone(redisContext *c, int *completed) { diff --git a/hiredis.spec b/hiredis.spec index d20e82a1009a05db7eec7f6ad9aad158ab12d531..4e450e26e7b96abe2d3eba070865677efdc1d668 100644 --- a/hiredis.spec +++ b/hiredis.spec @@ -1,6 +1,6 @@ Name: hiredis Version: 1.2.0 -Release: 1 +Release: 2 Summary: A minimalistic C client library for the Redis database License: BSD URL: https://github.com/redis/hiredis @@ -9,6 +9,11 @@ BuildRequires: gcc redis Patch0002: fix-memory-uninitialized-in-fuzz-testcase.patch +Patch0003: Retry-poll-2-if-we-are-intterupted.patch +Patch0004: Document-poll-2-logic-changes.patch +Patch0005: Fix-memory-leak.patch + + %description Hiredis is a minimalistic C client library for the Redis database. @@ -61,6 +66,12 @@ make check || true %{_libdir}/pkgconfig/hiredis.pc %changelog +* Wed Aug 7 2024 zhangxingrong - 1.2.0-2 +- Retry poll(2) if we are intterupted +- Document poll(2) logic changes +- Fix memory leak + + * Tue Aug 22 2023 Ge Wang - 1.2.0-1 - Update to version 1.2.0