From 785903ae6d157ebda824e4e841f1f63aa93f9208 Mon Sep 17 00:00:00 2001 From: Maas-Maarten Zeeman Date: Wed, 22 Feb 2017 22:03:26 +0100 Subject: [PATCH] Keep a reference to the connection before the prepare statement is put on the command queue. This should fix a race condition when a prepare is called right before the db connection is garbage collected. --- c_src/esqlite3_nif.c | 15 ++++++++++----- src/esqlite3.erl | 4 ++-- src/esqlite3_nif.erl | 4 ++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/c_src/esqlite3_nif.c b/c_src/esqlite3_nif.c index 3b46fdb..f836cef 100644 --- a/c_src/esqlite3_nif.c +++ b/c_src/esqlite3_nif.c @@ -1,5 +1,5 @@ /* - * Copyright 2011, 2012, 2013 Maas-Maarten Zeeman + * Copyright 2011 - 2017 Maas-Maarten Zeeman * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -346,12 +346,12 @@ do_prepare(ErlNifEnv *env, esqlite_connection *conn, const ERL_NIF_TERM arg) return make_error_tuple(env, "no_memory"); rc = sqlite3_prepare_v2(conn->db, (char *) bin.data, bin.size, &(stmt->statement), &tail); - if(rc != SQLITE_OK) - return make_sqlite3_error_tuple(env, rc, conn->db); + if(rc != SQLITE_OK) { + enif_release_resource(conn); + return make_sqlite3_error_tuple(env, rc, conn->db); + } - enif_keep_resource(conn); stmt->connection = conn; - esqlite_stmt = enif_make_resource(env, stmt); enif_release_resource(stmt); @@ -871,6 +871,11 @@ esqlite_prepare(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) if(!cmd) return make_error_tuple(env, "command_create_failed"); + /* Keep a reference to the connection to prevent it from being taken down + * while the prepare statement is waiting on the queue. + */ + enif_keep_resource(conn); + cmd->type = cmd_prepare; cmd->ref = enif_make_copy(cmd->env, argv[1]); cmd->pid = pid; diff --git a/src/esqlite3.erl b/src/esqlite3.erl index caffdd0..3f5b1b2 100644 --- a/src/esqlite3.erl +++ b/src/esqlite3.erl @@ -1,9 +1,9 @@ %% @author Maas-Maarten Zeeman -%% @copyright 2011, 2012, 2013 Maas-Maarten Zeeman +%% @copyright 2011 - 2017 Maas-Maarten Zeeman %% @doc Erlang API for sqlite3 databases -%% Copyright 2011, 2012 Maas-Maarten Zeeman +%% Copyright 2011 - 2017 Maas-Maarten Zeeman %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/src/esqlite3_nif.erl b/src/esqlite3_nif.erl index ca1bad5..1cbd0b6 100644 --- a/src/esqlite3_nif.erl +++ b/src/esqlite3_nif.erl @@ -1,9 +1,9 @@ %% @author Maas-Maarten Zeeman -%% @copyright 2011, 2012, 2013 Maas-Maarten Zeeman +%% @copyright 2011 - 2017 Maas-Maarten Zeeman %% @doc Low level erlang API for sqlite3 databases -%% Copyright 2011, 2012, 2013, 2014 Maas-Maarten Zeeman +%% Copyright 2011 - 2017 Maas-Maarten Zeeman %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License.