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:
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
}
|
||||
|
Reference in New Issue
Block a user