"RUNNING" means that the statement is running.  When you call sqlite3_prepare, 
SQLite3 generates a PROGRAM which will "yield" the results of the execution of 
that SQL statement.  It looks something like this:

START:
  ... do stuff ...
LOOP:
  ... do stuff ...
  return a result row (SQLITE_ROW)
CARRYON:
  are we done?
   no?  Go to LOOP
   yes?  Go to END
END
  ... do some cleanup ...
  return that there are no more rows (SQLITE_DONE) and reset the program

When you call sqlite3_step FOR THE FIRST TIME, the program commences "RUNNING" 
at START.  Periodically it may "return" (yield) a result row to you by 
returning the SQLITE_ROW result code.  The program is still running (unless you 
call sqlite3_reset or sqlite3_finalize on the program).  You do your stuff and 
then call sqlite3_step again to CARRYON execution of the program.  It will do 
some more stuff and return to you again.  Lather, Rinse, Repeat.  Eventually 
there will be no more work to be done and when you CARRYON (sqlite3_step) there 
will not be anything more to do and the program will branch to END, clean 
itself up, and return to you the SQLITE_DONE return code.  After this, the 
program statement is no longer "RUNNING".  

At any time the program is in the "RUNNING" state (that is, subsequent to the 
first call to sqlite3_step and before sqlite3_step returns SQLITE_DONE) you may 
call sqlite3_interrupt to interrupt the execution of the program.  This will 
cause sqlite3_step to return SQLITE_INTERRUPT rather that SQLITE_ROW or 
SQLITE_DONE.  You can then call sqlite3_reset and/or sqlite3_finalize to "clean 
up" the interrupted program.

Since you can sqlite3_prepare more than one statement (program) on a connection 
at a time, and you can be executing more than one statement on the same 
connection at the "same time", it is possible for there to be multiple 
statements (programs) associated with the connection (which is what you 
interrupt) in the "RUNNING" state at the same time (that is, you have called 
sqlite3_step on the statement but have not yet received an SQLITE_DONE return). 
 [NB:  Multiple statements may be RUNNING on the same connection at the same 
time, but only one may be executing at a time]

A typical use for sqlite3_interrupt is to attach it to a "STOP" button in your 
hooey-gooey so that you can "stop" execution of an operation or attach it to a 
signal (such as the BREAK key) for the same purpose in a non-hooey-gooey 
console application, or perhaps to SIGHUP or SIGINT or somesuch so that you can 
stop a runaway operation.

sqlite3_interrupt does not "interrupt" the execution of a "step", it interrupts 
the execution of the stream of steps that are required to execute the statement 
which has been prepared.  You can call sqlite3_interrupt at any time from 
anywhere (with a few restrictions).  FOr example, maybe you want to do this for 
some reason:


sqlite3_prepare(....)
while sqlite3_step() == SQLITE_ROW:
  get column 47
  ... do a bunch of stuff ...
  if column 47 is "Uh Oh Lets Stop" then sqlite3_interrupt()
sqlite3_reset()
sqlite3_finalize()


---
The fact that there's a Highway to Hell but only a Stairway to Heaven says a 
lot about anticipated traffic volume.

>-----Original Message-----
>From: sqlite-users [mailto:sqlite-users-
>boun...@mailinglists.sqlite.org] On Behalf Of Jesse Rittner
>Sent: Monday, 31 December, 2018 09:03
>To: sqlite-users@mailinglists.sqlite.org
>Subject: [sqlite] Using sqlite3_interrupt with a timeout
>
>Consider the following pseudo-code.
>
>void interrupt_timeout(sqlite3* db, int timeout) {
>    sleep(timeout);
>    sqlite3_interrupt(db);
>}
>
>int main() {
>    sqlite3* db = sqlite3_open_v2(...);
>    sqlite3_stmt* stmt = sqlite3_prepare_v2(db, ...);
>
>    ...
>
>    pthread_create(interrupt_timeout, db, timeout);
>
>    int rv = sqlite3_step(stmt);
>
>    ...
>}
>
>(I know this doesn't work properly if sqlite3_step doesn't time out,
>but it
>suffices for this example.)
>
>For the purposes of this example, let's suppose that the call to
>sqlite3_step takes a while. According to the docs, "New SQL
>statements that
>are started after the running statement count reaches zero are not
>effected
>by the sqlite3_interrupt()." But for very small timeouts, it's
>possible that
>sqlite3_interrupt gets executed /before/ sqlite3_step ever gets
>called, in
>which case sqlite3_step runs to completion no matter how long it
>takes.
>
>Am I missing something? Is there another way to leverage
>sqlite3_interrupt
>that doesn't have this race condition? What exactly is meant by
>"running
>statements"? Is it statements that are in the middle of a call to
>sqlite3_step? Statements that have been stepped, but not yet reset?
>Something else?
>
>
>
>--
>Sent from: http://sqlite.1065341.n5.nabble.com/
>_______________________________________________
>sqlite-users mailing list
>sqlite-users@mailinglists.sqlite.org
>http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users



_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to