Created
December 2, 2022 15:32
-
-
Save sitano/821713423f7cc57ba598b21171c7326c to your computer and use it in GitHub Desktop.
test sqlite3 interrupt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _MULTI_THREADED | |
#include <sqlite3.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <pthread.h> | |
int callback(void *, int, char **, char **); | |
void check(const char *str, int err); | |
void *threadfunc(void *parm); | |
// clang -O3 -lsqlite3 ./test_sqlite_int.cc && /usr/bin/time ./a.out | |
int main(void) { | |
sqlite3 *db; | |
sqlite3_stmt *res; | |
int rc = sqlite3_open(":memory:", &db); | |
if (rc != SQLITE_OK) { | |
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db)); | |
sqlite3_close(db); | |
return 1; | |
} | |
{ | |
rc = sqlite3_prepare_v2(db, "SELECT SQLITE_VERSION()", -1, &res, 0); | |
if (rc != SQLITE_OK) { | |
fprintf(stderr, "Failed to fetch data: %s\n", sqlite3_errmsg(db)); | |
sqlite3_close(db); | |
return 1; | |
} | |
rc = sqlite3_step(res); | |
if (rc == SQLITE_ROW) { | |
printf("%s\n", sqlite3_column_text(res, 0)); | |
} | |
sqlite3_finalize(res); | |
} | |
{ | |
// 2**26 = 67108864 | |
const char *sql = | |
"WITH RECURSIVE" | |
" fibo (curr, next) " | |
"AS " | |
"( SELECT 1,1" | |
" UNION ALL" | |
" SELECT next, curr+next FROM fibo" | |
" LIMIT 67108864 ) " | |
"SELECT curr, next FROM fibo LIMIT 1 OFFSET 67108864-1"; | |
char *err_msg = 0; | |
pthread_t t; | |
check("pthread_create", pthread_create(&t, nullptr, threadfunc, db)); | |
rc = sqlite3_exec(db, sql, callback, 0, &err_msg); | |
if (rc != SQLITE_OK) { | |
fprintf(stderr, "Failed to select data\n"); | |
fprintf(stderr, "SQL error: %s\n", err_msg); | |
sqlite3_free(err_msg); | |
sqlite3_close(db); | |
return 1; | |
} | |
pthread_join(t, nullptr); | |
} | |
sqlite3_close(db); | |
return 0; | |
} | |
int callback(void *NotUsed, int argc, char **argv, char **azColName) { | |
NotUsed = 0; | |
for (int i = 0; i < argc; i++) { | |
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); | |
} | |
printf("\n"); | |
return 0; | |
} | |
void check(const char *str, int err) { | |
if (err) { | |
fprintf(stderr, "[%d] %s: err=%d\n", gettid(), str, err); | |
} | |
} | |
void *threadfunc(void *parm) { | |
printf("[%d] watcher: sleep 1\n", gettid()); | |
sleep(1); | |
printf("[%d] watcher: slept 1\n", gettid()); | |
sqlite3_interrupt((sqlite3*)parm); | |
printf("[%d] watcher: interrupted?!\n", gettid()); | |
return NULL; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment