Fix transport_conn_close fd double-close race
transport_conn_close previously called close(conn->fd), but the detached read thread also calls close(conn->fd) when it exits. If the kernel reused the fd number before the read thread ran, the thread's close() would hit the new connection — explaining connections that appeared to not terminate. Fix: use shutdown(SHUT_RDWR) instead. This signals EOF to the remote end and unblocks the blocked read() without releasing the fd. The read thread remains the sole owner of the fd and is the only one to call close(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -319,5 +319,11 @@ struct App_Error transport_send_frame(struct Transport_Conn *conn,
|
||||
}
|
||||
|
||||
void transport_conn_close(struct Transport_Conn *conn) {
|
||||
close(conn->fd);
|
||||
/* shutdown() rather than close(): signals EOF to the remote end and
|
||||
* unblocks the read thread without releasing the fd. The read thread
|
||||
* is the sole owner of the fd and will close() it when it exits.
|
||||
* Using close() here would create a race where the fd number could be
|
||||
* reused by the next transport_connect() before the detached read
|
||||
* thread calls its own close(), which would then close the wrong fd. */
|
||||
shutdown(conn->fd, SHUT_RDWR);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user