summaryrefslogtreecommitdiff
path: root/src/socket.c
diff options
context:
space:
mode:
authorBinbin <binloveplay1314@qq.com>2022-11-05 00:46:37 +0800
committerGitHub <noreply@github.com>2022-11-04 18:46:37 +0200
commitfac188b49d9680fdeb90332f163e5634cec1ea13 (patch)
treef39837f530ebc0ed32e7edc2cae2020807900431 /src/socket.c
parentc337c0a8a49d7cb64617b0a414d05b31425666f7 (diff)
downloadredis-fac188b49d9680fdeb90332f163e5634cec1ea13.tar.gz
Introduce socket shutdown into connection type, used if a fork is active (#11376)
Introduce socket `shutdown()` into connection type, and use it on normal socket if a fork is active. This allows us to close client connections when there are child processes sharing the file descriptors. Fixes #10077. The reason is that since the `fork()` child is holding the file descriptors, the `close` in `unlinkClient -> connClose` isn't sufficient. The client will not realize that the connection is disconnected until the child process ends. Let's try to be conservative and only use shutdown when the fork is active.
Diffstat (limited to 'src/socket.c')
-rw-r--r--src/socket.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/socket.c b/src/socket.c
index 83000eaf8..7190d5358 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -125,6 +125,12 @@ static int connSocketConnect(connection *conn, const char *addr, int port, const
* move here as we implement additional connection types.
*/
+static void connSocketShutdown(connection *conn) {
+ if (conn->fd == -1) return;
+
+ shutdown(conn->fd, SHUT_RDWR);
+}
+
/* Close the connection and free resources. */
static void connSocketClose(connection *conn) {
if (conn->fd != -1) {
@@ -388,9 +394,10 @@ static ConnectionType CT_Socket = {
.addr = connSocketAddr,
.listen = connSocketListen,
- /* create/close connection */
+ /* create/shutdown/close connection */
.conn_create = connCreateSocket,
.conn_create_accepted = connCreateAcceptedSocket,
+ .shutdown = connSocketShutdown,
.close = connSocketClose,
/* connect & accept */