Skip to content

Commit

Permalink
RDMA: Use conn ref counter to prevent double close (#1250)
Browse files Browse the repository at this point in the history
RDMA: Use connection reference counter style
    
The reference counter of connection is used to protect re-entry of closenmethod.
Use this style instead the unsafe one.

Signed-off-by: zhenwei pi <[email protected]>
  • Loading branch information
pizhenwei authored Nov 8, 2024
1 parent e972d56 commit 45d596e
Showing 1 changed file with 15 additions and 8 deletions.
23 changes: 15 additions & 8 deletions src/rdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,14 @@ static void connRdmaClose(connection *conn) {
conn->fd = -1;
}

/* If called from within a handler, schedule the close but
* keep the connection until the handler returns.
*/
if (connHasRefs(conn)) {
conn->flags |= CONN_FLAG_CLOSE_SCHEDULED;
return;
}

if (!cm_id) {
return;
}
Expand Down Expand Up @@ -1689,25 +1697,24 @@ static int rdmaProcessPendingData(void) {
listNode *ln;
rdma_connection *rdma_conn;
connection *conn;
listNode *node;
int processed;

processed = listLength(pending_list);
listRewind(pending_list, &li);
while ((ln = listNext(&li))) {
rdma_conn = listNodeValue(ln);
conn = &rdma_conn->c;
node = rdma_conn->pending_list_node;

/* a connection can be disconnected by remote peer, CM event mark state as CONN_STATE_CLOSED, kick connection
* read/write handler to close connection */
if (conn->state == CONN_STATE_ERROR || conn->state == CONN_STATE_CLOSED) {
listDelNode(pending_list, node);
/* do NOT call callHandler(conn, conn->read_handler) here, conn is freed in handler! */
if (conn->read_handler) {
conn->read_handler(conn);
} else if (conn->write_handler) {
conn->write_handler(conn);
listDelNode(pending_list, rdma_conn->pending_list_node);
rdma_conn->pending_list_node = NULL;
/* Invoke both read_handler and write_handler, unless read_handler
returns 0, indicating the connection has closed, in which case
write_handler will be skipped. */
if (callHandler(conn, conn->read_handler)) {
callHandler(conn, conn->write_handler);
}

continue;
Expand Down

0 comments on commit 45d596e

Please sign in to comment.