Use a selective receive, and ignore stale answers. I think this fixes #3

This commit is contained in:
Maas-Maarten Zeeman
2013-11-28 19:41:40 +01:00
parent 29ffe329c4
commit 9df3a49445
2 changed files with 16 additions and 3 deletions

View File

@@ -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;
} }

View File

@@ -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.