7070** src/sqlite3ext.h
7171** src/sqliteInt.h
7272** src/status.c
73+ ** src/test1.c
7374** src/test2.c
7475** src/test3.c
7576** src/test8.c
@@ -90201,7 +90202,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
9020190202#ifdef SQLITE_DEBUG
9020290203 p->nWrite = 0;
9020390204#endif
90204- p->isInterrupted = 0 ;
90205+ AtomicStore(& p->isInterrupted, 0) ;
9020590206
9020690207 /* Save profiling information from this VDBE run.
9020790208 */
@@ -93043,7 +93044,9 @@ void libsql_stmt_interrupt(sqlite3_stmt *pStmt){
9304393044 (void)SQLITE_MISUSE_BKPT;
9304493045 return;
9304593046 }
93046- v->isInterrupted = 1;
93047+ /* Set atomically: this may be called from a different thread than the one
93048+ ** executing the statement, mirroring sqlite3_interrupt(). */
93049+ AtomicStore(&v->isInterrupted, 1);
9304793050}
9304893051
9304993052/*
@@ -93061,7 +93064,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
9306193064 return SQLITE_MISUSE_BKPT;
9306293065 }
9306393066 db = v->db;
93064- if( v->isInterrupted ){
93067+ if( AtomicLoad(& v->isInterrupted) ){
9306593068 rc = SQLITE_INTERRUPT;
9306693069 v->rc = rc;
9306793070 db->errCode = rc;
@@ -95105,6 +95108,12 @@ SQLITE_API int sqlite3_search_count = 0;
9510595108*/
9510695109#ifdef SQLITE_TEST
9510795110SQLITE_API int sqlite3_interrupt_count = 0;
95111+ /*
95112+ ** As above, but simulates a statement-level interrupt
95113+ ** (libsql_stmt_interrupt()) on the statement that is currently executing,
95114+ ** rather than a connection-wide sqlite3_interrupt().
95115+ */
95116+ SQLITE_API int sqlite3_stmt_interrupt_count = 0;
9510895117#endif
9510995118
9511095119/*
@@ -95928,7 +95937,9 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
9592895937 p->iCurrentTime = 0;
9592995938 assert( p->explain==0 );
9593095939 db->busyHandler.nBusy = 0;
95931- if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
95940+ if( AtomicLoad(&db->u1.isInterrupted) || AtomicLoad(&p->isInterrupted) ){
95941+ goto abort_due_to_interrupt;
95942+ }
9593295943 sqlite3VdbeIOTraceSql(p);
9593395944#ifdef SQLITE_DEBUG
9593495945 sqlite3BeginBenignMalloc();
@@ -95997,6 +96008,12 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
9599796008 sqlite3_interrupt(db);
9599896009 }
9599996010 }
96011+ if( sqlite3_stmt_interrupt_count>0 ){
96012+ sqlite3_stmt_interrupt_count--;
96013+ if( sqlite3_stmt_interrupt_count==0 ){
96014+ libsql_stmt_interrupt((sqlite3_stmt*)p);
96015+ }
96016+ }
9600096017#endif
9600196018
9600296019 /* Sanity checking on other operands */
@@ -96118,7 +96135,9 @@ case OP_Goto: { /* jump */
9611896135 ** checks on every opcode. This helps sqlite3_step() to run about 1.5%
9611996136 ** faster according to "valgrind --tool=cachegrind" */
9612096137check_for_interrupt:
96121- if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
96138+ if( AtomicLoad(&db->u1.isInterrupted) || AtomicLoad(&p->isInterrupted) ){
96139+ goto abort_due_to_interrupt;
96140+ }
9612296141#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
9612396142 /* Call the progress callback if it is configured and the required number
9612496143 ** of VDBE ops have been executed (either since this invocation of
@@ -104463,7 +104482,7 @@ default: { /* This is really OP_Noop, OP_Explain */
104463104482 ** flag.
104464104483 */
104465104484abort_due_to_interrupt:
104466- assert( AtomicLoad(&db->u1.isInterrupted) );
104485+ assert( AtomicLoad(&db->u1.isInterrupted) || AtomicLoad(&p->isInterrupted) );
104467104486 rc = SQLITE_INTERRUPT;
104468104487 goto abort_due_to_error;
104469104488}
0 commit comments