1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Bind sqlite3_interrupt() and sqlite3_is_interrupted() to JNI but with caveats regarding mutexing of the JNIEnv cache. Add a loud warning to the JNI 'dist' target that it should be built with JDK8 (a.k.a. Java 1.8) for compatibility reasons.

FossilOrigin-Name: fbf99a2423dd20e4544bdeea85f714e9368ce3b92fefe97efb39a0fb4a557abe
This commit is contained in:
stephan
2023-08-12 23:47:58 +00:00
parent 202651fe86
commit 0c07549fd6
7 changed files with 72 additions and 13 deletions

View File

@ -2624,6 +2624,20 @@ JDECL(jint,1finalize)(JENV_CSELF, jobject jpStmt){
return rc;
}
JDECL(void,1interrupt)(JENV_CSELF, jobject jpDb){
sqlite3 * const pDb = PtrGet_sqlite3(jpDb);
if( pDb ) sqlite3_interrupt(pDb);
}
JDECL(jboolean,1is_1interrupted)(JENV_CSELF, jobject jpDb){
int rc = 0;
sqlite3 * const pDb = PtrGet_sqlite3(jpDb);
if( pDb ){
rc = sqlite3_is_interrupted(pDb);
}
return rc ? JNI_TRUE : JNI_FALSE;
}
JDECL(jlong,1last_1insert_1rowid)(JENV_CSELF, jobject jpDb){
return (jlong)sqlite3_last_insert_rowid(PtrGet_sqlite3(jpDb));

View File

@ -1120,7 +1120,7 @@ JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1filename
* Method: sqlite3_db_config
* Signature: (Lorg/sqlite/jni/sqlite3;IILorg/sqlite/jni/OutputPointer/Int32;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1config__Lorg_sqlite_jni_sqlite3_2IILorg_sqlite_jni_OutputPointer_00024Int32_2
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1config__Lorg_sqlite_jni_sqlite3_2IILorg_sqlite_jni_OutputPointer_Int32_2
(JNIEnv *, jclass, jobject, jint, jint, jobject);
/*
@ -1211,6 +1211,22 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1finalize
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1initialize
(JNIEnv *, jclass);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_interrupt
* Signature: (Lorg/sqlite/jni/sqlite3;)V
*/
JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1interrupt
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_is_interrupted
* Signature: (Lorg/sqlite/jni/sqlite3;)Z
*/
JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1is_1interrupted
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_last_insert_rowid

View File

@ -557,6 +557,25 @@ public final class SQLite3Jni {
public static synchronized native int sqlite3_initialize();
/**
Design note/FIXME: we have a problem vis-a-vis 'synchronized'
here: we specifically want other threads to be able to cancel a
long-running thread, but this routine requires access to C-side
global state which does not have a mutex. Making this function
synchronized would make it impossible for a long-running job to
be cancelled from another thread.
The mutexing problem here is not within the core lib or Java, but
within the cached data held by the JNI binding. The cache holds
per-thread state, used by all but a tiny fraction of the JNI
binding layer, and access to that state needs to be
mutex-protected.
*/
public static native void sqlite3_interrupt(@NotNull sqlite3 db);
//! See sqlite3_interrupt() for threading concerns.
public static native boolean sqlite3_is_interrupted(@NotNull sqlite3 db);
public static synchronized native long sqlite3_last_insert_rowid(@NotNull sqlite3 db);
public static synchronized native String sqlite3_libversion();

View File

@ -163,6 +163,13 @@ public class Tester1 {
/* This function has different mangled names in jdk8 vs jdk19,
and this call is here to ensure that the build fails
if it cannot find both names. */;
// These interrupt checks are only to make sure that the JNI binding
// has the proper exported symbol names. They don't actually test
// anything useful.
affirm( !sqlite3_is_interrupted(db) );
sqlite3_interrupt(db);
affirm( sqlite3_is_interrupted(db) );
sqlite3_close_v2(db);
affirm(0 == db.getNativePointer());
}