@@ -4,7 +4,7 @@ use crossbeam_channel::{unbounded, Sender};
4
4
use either:: Either ;
5
5
use futures_channel:: oneshot;
6
6
use libsqlite3_sys:: { sqlite3_step, SQLITE_DONE , SQLITE_ROW } ;
7
- use std:: sync:: Arc ;
7
+ use std:: sync:: { Arc , Weak } ;
8
8
use std:: thread;
9
9
10
10
// Each SQLite connection has a dedicated thread.
@@ -19,7 +19,7 @@ pub(crate) struct StatementWorker {
19
19
20
20
enum StatementWorkerCommand {
21
21
Step {
22
- statement : Arc < StatementHandle > ,
22
+ statement : Weak < StatementHandle > ,
23
23
tx : oneshot:: Sender < Result < Either < u64 , ( ) > , Error > > ,
24
24
} ,
25
25
}
@@ -32,14 +32,19 @@ impl StatementWorker {
32
32
for cmd in rx {
33
33
match cmd {
34
34
StatementWorkerCommand :: Step { statement, tx } => {
35
- let status = unsafe { sqlite3_step ( statement. 0 . as_ptr ( ) ) } ;
35
+ let resp = if let Some ( statement) = statement. upgrade ( ) {
36
+ let status = unsafe { sqlite3_step ( statement. 0 . as_ptr ( ) ) } ;
36
37
37
- let resp = match status {
38
- SQLITE_ROW => Ok ( Either :: Right ( ( ) ) ) ,
39
- SQLITE_DONE => Ok ( Either :: Left ( statement. changes ( ) ) ) ,
40
- _ => Err ( statement. last_error ( ) . into ( ) ) ,
38
+ let resp = match status {
39
+ SQLITE_ROW => Ok ( Either :: Right ( ( ) ) ) ,
40
+ SQLITE_DONE => Ok ( Either :: Left ( statement. changes ( ) ) ) ,
41
+ _ => Err ( statement. last_error ( ) . into ( ) ) ,
42
+ } ;
43
+ resp
44
+ } else {
45
+ // Statement is already finalized.
46
+ Err ( Error :: WorkerCrashed )
41
47
} ;
42
-
43
48
let _ = tx. send ( resp) ;
44
49
}
45
50
}
@@ -57,7 +62,7 @@ impl StatementWorker {
57
62
58
63
self . tx
59
64
. send ( StatementWorkerCommand :: Step {
60
- statement : Arc :: clone ( statement) ,
65
+ statement : Arc :: downgrade ( statement) ,
61
66
tx,
62
67
} )
63
68
. map_err ( |_| Error :: WorkerCrashed ) ?;
0 commit comments