Skip to content

Commit

Permalink
Merge pull request #268 from qzhuyan/dev/william/proper-tests
Browse files Browse the repository at this point in the history
fix dead lock while get connecions
  • Loading branch information
qzhuyan committed Mar 6, 2024
2 parents dc3e24c + d846186 commit 574417a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 16 deletions.
4 changes: 2 additions & 2 deletions Makefile
Expand Up @@ -21,7 +21,7 @@ clean: distclean


fmt:
@clang-format-12 -i c_src/*
@clang-format-14 -i c_src/*
@rebar3 fmt


Expand Down Expand Up @@ -81,7 +81,7 @@ check: clang-format

.PHONY: clang-format
clang-format:
clang-format-11 --Werror --dry-run c_src/*
clang-format-14 --Werror --dry-run c_src/*

.PHONY: ci
ci: test dialyzer
Expand Down
37 changes: 29 additions & 8 deletions c_src/quicer_connection.c
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,18 +1126,13 @@ continue_connection_handshake(QuicerConnCTX *c_ctx)
}

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

{
QuicerConnCTX *c_ctx;
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
ERL_NIF_TERM res = ATOM_OK;
if (1 != argc)
{
return ERROR_TUPLE_2(ATOM_BADARG);
}
CXPLAT_FRE_ASSERT(argc == 1);

if (!enif_get_resource(env, argv[0], ctx_connection_t, (void **)&c_ctx))
{
Expand Down Expand Up @@ -1766,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 cause 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 @@ -1802,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
16 changes: 11 additions & 5 deletions test/prop_stateful_client_conn.erl
Expand Up @@ -60,7 +60,9 @@ initial_state() ->
state => connected,
handle => H,
owner => self(),
me => self()
me => self(),
% cnt calls
calls => 0
}.

%% @doc List of possible commands to run against the system
Expand Down Expand Up @@ -208,17 +210,21 @@ postcondition(_State, {call, _Mod, _Fun, _Args} = _Call, _Res) ->

%% @doc Assuming the postcondition for a call was true, update the model
%% accordingly for the test to proceed.
next_state(#{state := connected} = State, _Res, {call, quicer, close_connection, _Args}) ->
next_state(State, Res, Call) ->
step_calls(do_next_state(State, Res, Call)).
do_next_state(#{state := connected} = State, _Res, {call, quicer, close_connection, _Args}) ->
State#{state := closed};
next_state(#{state := connected} = State, _Res, {call, quicer, shutdown_connection, _Args}) ->
do_next_state(#{state := connected} = State, _Res, {call, quicer, shutdown_connection, _Args}) ->
State#{state := closed};
next_state(
do_next_state(
#{state := connected} = State, ok, {call, quicer, controlling_process, [_, Owner]}
) ->
State#{owner := Owner};
next_state(State, _Res, {call, _Mod, _Fun, _Args}) ->
do_next_state(State, _Res, {call, _Mod, _Fun, _Args}) ->
State.

step_calls(#{calls := Calls} = S) ->
S#{calls := Calls + 1}.
%%% Generators

%%%%%%%%%%%%%%%%%%%%%%%
Expand Down
2 changes: 1 addition & 1 deletion tools/asan/bin/sanitizer-check
Expand Up @@ -56,5 +56,5 @@ if [ $# -eq 1 ]; then
;;
esac
else
escript "$REBAR3" do ct $@
escript "$REBAR3" $@
fi

0 comments on commit 574417a

Please sign in to comment.