Skip to content

Commit

Permalink
fix(api): get_connections cause deadlock
Browse files Browse the repository at this point in the history
  • Loading branch information
qzhuyan committed Mar 6, 2024
1 parent e921206 commit 4d9f0af
Showing 1 changed file with 28 additions and 4 deletions.
32 changes: 28 additions & 4 deletions c_src/quicer_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ static QUIC_STATUS handle_connection_event_resumption_ticket_received(
static QUIC_STATUS handle_connection_event_peer_certificate_received(
QuicerConnCTX *c_ctx, QUIC_CONNECTION_EVENT *Event);

static void put_conn_handles(ErlNifEnv *env, ERL_NIF_TERM conn_handles);

BOOLEAN
parse_registration(ErlNifEnv *env,
ERL_NIF_TERM options,
Expand Down Expand Up @@ -1124,9 +1126,7 @@ continue_connection_handshake(QuicerConnCTX *c_ctx)
}

ERL_NIF_TERM
async_handshake_1(ErlNifEnv *env,
int argc,
const ERL_NIF_TERM argv[])
async_handshake_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])

{
QuicerConnCTX *c_ctx;
Expand Down Expand Up @@ -1763,12 +1763,16 @@ get_connectionsX(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
if (get_conn_handle(c_ctx))
{
res = enif_make_list_cell(env, enif_make_resource(env, c_ctx), res);
put_conn_handle(c_ctx);
}
Entry = Entry->Flink;
}
enif_mutex_unlock(r_ctx->lock);

// We must deref c_ctx without locking the r_ctx
// becasue deref c_ctx may casue connection close and then trigger callback
// that destroy c_ctx which locks r_ctx in another thread, causing dead lock
put_conn_handles(env, res);

if (argc == 0) // use global registration
{
pthread_mutex_unlock(&GRegLock);
Expand Down Expand Up @@ -1799,6 +1803,26 @@ get_conn_owner1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
return res;
}

/*
** Helper function.
** put a list of connection handles
*/
void
put_conn_handles(ErlNifEnv *env, ERL_NIF_TERM conn_handles)
{
ERL_NIF_TERM head;
ERL_NIF_TERM tail;
QuicerConnCTX *c_ctx = NULL;
while (enif_get_list_cell(env, conn_handles, &head, &tail))
{
if (enif_get_resource(env, head, ctx_connection_t, (void **)&c_ctx))
{
put_conn_handle(c_ctx);
}
conn_handles = tail;
}
}

///_* Emacs
///====================================================================
/// Local Variables:
Expand Down

0 comments on commit 4d9f0af

Please sign in to comment.