Use a selective receive, and ignore stale answers. I think this fixes #3
This commit is contained in:
@@ -71,6 +71,8 @@ typedef struct {
|
|||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
} esqlite_command;
|
} esqlite_command;
|
||||||
|
|
||||||
|
ERL_NIF_TERM atom_esqlite3;
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
static ERL_NIF_TERM
|
||||||
make_atom(ErlNifEnv *env, const char *atom_name)
|
make_atom(ErlNifEnv *env, const char *atom_name)
|
||||||
{
|
{
|
||||||
@@ -570,7 +572,7 @@ push_command(ErlNifEnv *env, esqlite_connection *conn, esqlite_command *cmd) {
|
|||||||
static ERL_NIF_TERM
|
static ERL_NIF_TERM
|
||||||
make_answer(esqlite_command *cmd, ERL_NIF_TERM answer)
|
make_answer(esqlite_command *cmd, ERL_NIF_TERM answer)
|
||||||
{
|
{
|
||||||
return enif_make_tuple2(cmd->env, cmd->ref, answer);
|
return enif_make_tuple3(cmd->env, atom_esqlite3, cmd->ref, answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
@@ -919,6 +921,8 @@ on_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
|
|||||||
return -1;
|
return -1;
|
||||||
esqlite_statement_type = rt;
|
esqlite_statement_type = rt;
|
||||||
|
|
||||||
|
atom_esqlite3 = make_atom(env, "esqlite3");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -287,9 +287,18 @@ close({connection, _Ref, Connection}, Timeout) ->
|
|||||||
%% Internal functions
|
%% Internal functions
|
||||||
|
|
||||||
receive_answer(Ref, Timeout) ->
|
receive_answer(Ref, Timeout) ->
|
||||||
|
Start = os:timestamp(),
|
||||||
receive
|
receive
|
||||||
{Ref, Resp} -> Resp;
|
{esqlite3, Ref, Resp} ->
|
||||||
Other -> throw(Other)
|
Resp;
|
||||||
|
{esqlite3, _, _}=StaleAnswer ->
|
||||||
|
error_logger:warning_msg("Esqlite3: Ignoring stale answer ~p~n", [StaleAnswer]),
|
||||||
|
PassedMics = timer:now_diff(os:timestamp(), Start) div 1000,
|
||||||
|
NewTimeout = case Timeout - PassedMics of
|
||||||
|
Passed when Passed < 0 -> 0;
|
||||||
|
TO -> TO
|
||||||
|
end,
|
||||||
|
receive_answer(Ref, NewTimeout)
|
||||||
after Timeout ->
|
after Timeout ->
|
||||||
throw({error, timeout, Ref})
|
throw({error, timeout, Ref})
|
||||||
end.
|
end.
|
||||||
|
|||||||
Reference in New Issue
Block a user