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

Correct a potential duplicate xDestroy() being triggered for Java-side collations.

FossilOrigin-Name: 25331172f78544f7f23ad7821cbf065589f6d02706184d4c83fe3988452dac5d
This commit is contained in:
stephan
2023-08-26 16:55:27 +00:00
parent fec793dd8a
commit 2a0dc4895b
4 changed files with 31 additions and 28 deletions

View File

@ -981,7 +981,7 @@ static int s3jni_db_exception(JNIEnv * const env, S3JniDb * const ps,
/*
** Extracts the (void xDestroy()) method from jObj and applies it to
** jObj. If jObj is NULL, this is a no-op. The lack of an xDestroy()
** method is silently ignored and any exceptions thrown by xDestroy()
** method is silently ignored. Any exceptions thrown by xDestroy()
** trigger a warning to stdout or stderr and then the exception is
** suppressed.
*/
@ -1012,11 +1012,14 @@ static void s3jni_call_xDestroy(JNIEnv * const env, jobject jObj){
** cleared. It is legal to call this when the object has no Java
** references.
*/
static void S3JniHook_unref(JNIEnv * const env, S3JniHook * const s, int doXDestroy){
if( doXDestroy && s->jObj ){
s3jni_call_xDestroy(env, s->jObj);
static void S3JniHook_unref(JNIEnv * const env, S3JniHook * const s,
int doXDestroy){
if( s->jObj ){
if( doXDestroy ){
s3jni_call_xDestroy(env, s->jObj);
}
S3JniUnrefGlobal(s->jObj);
}
S3JniUnrefGlobal(s->jObj);
memset(s, 0, sizeof(*s));
}
@ -1062,18 +1065,18 @@ static void S3JniDb_set_aside_unlocked(JNIEnv * env, S3JniDb * const s){
SJG.perDb.aHead = s->pNext;
}
sqlite3_free( s->zMainDbName );
#define UNHOOK(MEMBER,XDESTROY) S3JniHook_unref(env, &s->hooks.MEMBER, XDESTROY)
UNHOOK(auth, 0);
UNHOOK(busyHandler, 0);
UNHOOK(collation, 1);
UNHOOK(collationNeeded, 0);
UNHOOK(commit, 0);
UNHOOK(progress, 0);
UNHOOK(rollback, 0);
UNHOOK(trace, 0);
UNHOOK(update, 0);
#define UNHOOK(MEMBER) S3JniHook_unref(env, &s->hooks.MEMBER, 0)
UNHOOK(auth);
UNHOOK(busyHandler);
UNHOOK(collation);
UNHOOK(collationNeeded);
UNHOOK(commit);
UNHOOK(progress);
UNHOOK(rollback);
UNHOOK(trace);
UNHOOK(update);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
UNHOOK(preUpdate, 0);
UNHOOK(preUpdate);
#endif
#undef UNHOOK
S3JniUnrefGlobal(s->jDb);

View File

@ -488,7 +488,7 @@ public class Tester1 implements Runnable {
private void testCollation(){
final sqlite3 db = createNewDb();
execSql(db, "CREATE TABLE t(a); INSERT INTO t(a) VALUES('a'),('b'),('c')");
final ValueHolder<Boolean> xDestroyCalled = new ValueHolder<>(false);
final ValueHolder<Integer> xDestroyCalled = new ValueHolder<>(0);
final CollationCallback myCollation = new CollationCallback() {
private String myState =
"this is local state. There is much like it, but this is mine.";
@ -510,7 +510,7 @@ public class Tester1 implements Runnable {
@Override
public void xDestroy() {
// Just demonstrates that xDestroy is called.
xDestroyCalled.value = true;
++xDestroyCalled.value;
}
};
final CollationNeededCallback collLoader = new CollationNeededCallback(){
@ -552,12 +552,12 @@ public class Tester1 implements Runnable {
}
affirm(3 == counter);
sqlite3_finalize(stmt);
affirm(!xDestroyCalled.value);
affirm( 0 == xDestroyCalled.value );
rc = sqlite3_collation_needed(db, null);
affirm( 0 == rc );
sqlite3_close_v2(db);
affirm( 0 == db.getNativePointer() );
affirm(xDestroyCalled.value);
affirm( 1 == xDestroyCalled.value );
}
@ManualTest /* because threading is meaningless here */