]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Replace JNI's per-db-instance state tracking with the new sqlite3_set/get_clientdata().
authorstephan <stephan@noemail.net>
Wed, 30 Aug 2023 18:45:42 +0000 (18:45 +0000)
committerstephan <stephan@noemail.net>
Wed, 30 Aug 2023 18:45:42 +0000 (18:45 +0000)
FossilOrigin-Name: e7c11d34ee2eebdca4d9db1496bbb4152e4c62745c083ad5e0337733e8d1254e

ext/jni/src/c/sqlite3-jni.c
manifest
manifest.uuid

index b426a26acce856817ffe1c7a17de6bd096d05113..20bc5cc986b7b4654dfbd73735c7300dd7dd5f67 100644 (file)
@@ -447,8 +447,7 @@ struct S3JniDb {
 #ifdef SQLITE_ENABLE_FTS5
   jobject jFtsApi  /* global ref to s3jni_fts5_api_from_db() */;
 #endif
-  S3JniDb * pNext /* Next entry in SJG.perDb.aFree or SJG.perDb.aHead */;
-  S3JniDb * pPrev /* Previous entry in SJG.perDb.aFree or SJG.perDb.aHead */;
+  S3JniDb * pNext /* Next entry in SJG.perDb.aFree */;
 };
 
 /*
@@ -579,7 +578,6 @@ struct S3JniGlobalType {
   ** client-defined state to db handles there.
   */
   struct {
-    S3JniDb * aHead  /* Linked list of in-use instances */;
     S3JniDb * aFree  /* Linked list of free instances */;
     sqlite3_mutex * mutex /* mutex for aHead and aFree */;
     void const * locker /* perDb mutex is held on this object's
@@ -1225,20 +1223,10 @@ static void S3JniDb_clear(JNIEnv * const env, S3JniDb * const s){
 */
 static void S3JniDb__set_aside_unlocked(JNIEnv * const env, S3JniDb * const s){
   assert( s );
+  S3JniMutex_S3JniDb_assertLocker;
   if( s ){
-    S3JniMutex_S3JniDb_assertLocker;
-    assert(s->pPrev != s);
-    assert(s->pNext != s);
-    assert(s->pPrev ? (s->pPrev!=s->pNext) : 1);
-    if(s->pNext) s->pNext->pPrev = s->pPrev;
-    if(s->pPrev) s->pPrev->pNext = s->pNext;
-    else if(SJG.perDb.aHead == s){
-      assert(!s->pPrev);
-      SJG.perDb.aHead = s->pNext;
-    }
     S3JniDb_clear(env, s);
     s->pNext = SJG.perDb.aFree;
-    if(s->pNext) s->pNext->pPrev = s;
     SJG.perDb.aFree = s;
   }
 }
@@ -1448,40 +1436,27 @@ static S3JniDb * S3JniDb_alloc(JNIEnv * const env, jobject jDb){
   if( SJG.perDb.aFree ){
     rv = SJG.perDb.aFree;
     SJG.perDb.aFree = rv->pNext;
-    assert(rv->pNext != rv);
-    assert(!rv->pPrev);
-    if( rv->pNext ){
-      assert(rv->pNext->pPrev == rv);
-      rv->pNext->pPrev = 0;
-      rv->pNext = 0;
-    }
+    rv->pNext = 0;
     s3jni_incr( &SJG.metrics.nPdbRecycled );
   }else{
     rv = s3jni_malloc( sizeof(S3JniDb));
     if( rv ){
-      memset(rv, 0, sizeof(S3JniDb));
       s3jni_incr( &SJG.metrics.nPdbAlloc );
     }
   }
   if( rv ){
-    rv->pNext = SJG.perDb.aHead;
-    SJG.perDb.aHead = rv;
-    if( rv->pNext ){
-      assert(!rv->pNext->pPrev);
-      rv->pNext->pPrev = rv;
-    }
+    memset(rv, 0, sizeof(S3JniDb));
     rv->jDb = S3JniRefGlobal(jDb);
   }
   S3JniMutex_S3JniDb_leave;
   return rv;
 }
 
+#define S3JniDb_clientdata_key "S3JniDb"
+
 /* Short-lived code consolidator. */
-#define S3JniDb_search            \
-  s = SJG.perDb.aHead;            \
-  for( ; pDb && s; s = s->pNext){ \
-    if( s->pDb == pDb ) break;    \
-  }
+#define S3JniDb_search                                              \
+  s = pDb ? sqlite3_get_clientdata(pDb, S3JniDb_clientdata_key) : 0
 
 /*
 ** Returns the S3JniDb object for the given org.sqlite.jni.sqlite3
@@ -1511,10 +1486,20 @@ static S3JniDb * S3JniDb__from_java_unlocked(JNIEnv * const env, jobject jDb){
   if( jDb ) pDb = PtrGet_sqlite3(jDb);
   S3JniDb_search;
   return s;
-
 }
 #define S3JniDb_from_java_unlocked(JDB) S3JniDb__from_java_unlocked(env, (JDB))
 
+/*
+** S3JniDb finalizer for use with sqlite3_set_clientdata().
+*/
+static void S3JniDb_xDestroy(void *p){
+  S3JniDb * ps = p;
+  S3JniDeclLocal_env;
+
+  assert( !ps->pNext );
+  S3JniDb_set_aside(ps);
+}
+
 /*
 ** Returns the S3JniDb object for the sqlite3 object, or NULL if pDb
 ** is NULL, or no matching entry
@@ -2132,9 +2117,15 @@ static int s3jni_run_java_auto_extensions(sqlite3 *pDb, const char **pzErr,
   jc->pdbOpening = 0;
   assert( !ps->pDb && "it's still being opened" );
   assert( ps->jDb );
-  ps->pDb = pDb;
+  rc = sqlite3_set_clientdata(pDb, S3JniDb_clientdata_key,
+                              ps, 0/* we'll re-set this after open()
+                                      completes. */);
+  if( rc ){
+    return rc;
+  }
   NativePointerHolder_set(&S3JniNphRefs.sqlite3, ps->jDb, pDb)
     /* As of here, the Java/C connection is complete */;
+  ps->pDb = pDb;
   for( i = 0; go && 0==rc; ++i ){
     S3JniAutoExtension ax = {0,0}
       /* We need a copy of the auto-extension object, with our own
@@ -2447,8 +2438,6 @@ S3JniApi(sqlite3_cancel_auto_extension(),jboolean,1cancel_1auto_1extension)(
 /* Wrapper for sqlite3_close(_v2)(). */
 static jint s3jni_close_db(JNIEnv * const env, jobject jDb, int version){
   int rc = 0;
-//#define CLOSE_DB_LOCKED /* An experiment */
-#ifndef CLOSE_DB_LOCKED
   S3JniDb * const ps = S3JniDb_from_java(jDb);
 
   assert(version == 1 || version == 2);
@@ -2458,38 +2447,8 @@ static jint s3jni_close_db(JNIEnv * const env, jobject jDb, int version){
       : (jint)sqlite3_close_v2(ps->pDb);
     if( 0==rc ){
       NativePointerHolder_set(&S3JniNphRefs.sqlite3, jDb, 0);
-      S3JniDb_set_aside(ps)
-        /* MUST come after close() because of ps->trace. */;
     }
   }
-#else
-  /* This impl leads to an assertion in sqlite3_close[_v2]()
-
-     pthreadMutexEnter: Assertion `p->id==SQLITE_MUTEX_RECURSIVE
-                        || pthreadMutexNotheld(p)' failed.
-
-     For reasons not yet fully understood.
-  */
-  assert(version == 1 || version == 2);
-  if( 0!=jDb ){
-    S3JniDb * ps;
-    S3JniMutex_S3JniDb_enter;
-    ps = S3JniDb_from_java_unlocked(jDb);
-    if( ps && ps->pDb ){
-      rc = 1==version
-        ? (jint)sqlite3_close(ps->pDb)
-        : (jint)sqlite3_close_v2(ps->pDb);
-      if( 0==rc ){
-        S3JniDb_set_aside_unlocked(ps)
-          /* MUST come after close() because of ps->hooks.trace. */;
-        NativePointerHolder_set(&S3JniNphRefs.sqlite3, jDb, 0);
-      }
-    }else{
-      /* ps is from S3Global.perDb.aFree. */
-    }
-    S3JniMutex_S3JniDb_leave;
-  }
-#endif
   return (jint)rc;
 }
 
@@ -3307,23 +3266,26 @@ end:
 static int s3jni_open_post(JNIEnv * const env, S3JniEnv * const jc,
                            S3JniDb * ps, sqlite3 **ppDb,
                            jobject jOut, int theRc){
+  int rc = 0;
   jc->pdbOpening = 0;
   if( *ppDb ){
     assert(ps->jDb);
     if( 0==ps->pDb ){
       ps->pDb = *ppDb;
-      NativePointerHolder_set(&S3JniNphRefs.sqlite3, ps->jDb, *ppDb)
-        /* As of here, the Java/C connection is complete */;
+      NativePointerHolder_set(&S3JniNphRefs.sqlite3, ps->jDb, *ppDb);
     }else{
       assert( ps->pDb==*ppDb
               && "Set up via s3jni_run_java_auto_extensions()" );
     }
+    rc = sqlite3_set_clientdata(ps->pDb, S3JniDb_clientdata_key,
+                                ps, S3JniDb_xDestroy);
+    /* As of here, the Java/C connection is complete */
   }else{
     S3JniDb_set_aside(ps);
     ps = 0;
   }
   OutputPointer_set_sqlite3(env, jOut, ps ? ps->jDb : 0);
-  return theRc;
+  return theRc ? theRc : rc;
 }
 
 S3JniApi(sqlite3_open(),jint,1open)(
@@ -4040,7 +4002,6 @@ S3JniApi(sqlite3_shutdown(),jint,1shutdown)(
     while( S3JniGlobal.perDb.aFree ){
       S3JniDb * const d = S3JniGlobal.perDb.aFree;
       S3JniGlobal.perDb.aFree = d->pNext;
-      d->pNext = 0;
       S3JniDb_clear(env, d);
       sqlite3_free(d);
     }
index 9c846bbc476b7f65518646f1fa188699cb3c4d42..9d225290992c22f37d45ff73a703f1746707189e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\sanother\sunreachable\sbranch\sin\sthe\ssqlite3_set_clientdata()\slogic.
-D 2023-08-30T17:41:55.821
+C Replace\sJNI's\sper-db-instance\sstate\stracking\swith\sthe\snew\ssqlite3_set/get_clientdata().
+D 2023-08-30T18:45:42.722
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -237,7 +237,7 @@ F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a3
 F ext/jni/GNUmakefile 374873bf6d2cd6ceafb458e28b59140dbb074f01f7adddf7e15a3ee3daf44551
 F ext/jni/README.md 1332b1fa27918bd5d9ca2d0d4f3ac3a6ab86b9e3699dc5bfe32904a027f3d2a9
 F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
-F ext/jni/src/c/sqlite3-jni.c 3d80af6bfa4af38dc50a919f97219a481410de1f6f885644b2f97cd64ab9b863
+F ext/jni/src/c/sqlite3-jni.c aaec2851258a7d9c9907d8e864a17e055676ec0adb64f335d979fa19674a0cab
 F ext/jni/src/c/sqlite3-jni.h 12e1a5ef5ee1795dc22577c285b4518dfd8aa4af45757f6cb81a555d967bf201
 F ext/jni/src/org/sqlite/jni/AbstractCollationCallback.java 95e88ba04f4aac51ffec65693e878e234088b2f21b387f4e4285c8b72b33e436
 F ext/jni/src/org/sqlite/jni/AggregateFunction.java 7312486bc65fecdb91753c0a4515799194e031f45edbe16a6373cea18f404dc4
@@ -2115,8 +2115,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 565c68adee64b6c838f2fcb162485b6cfe9a976adb79de4370be98fcd4af2baf
-R c44620e6fdc8795cc96b9dcf7aa093f2
-U drh
-Z ba5cdcdbc9c47766f3528cc96f85a22f
+P 57e31e6b10b2aa68b6039914d191819bae0aa60999a99d5ef23ca18128b72e0e
+R 936a89e0748a165d8e043fd6221f1b2f
+U stephan
+Z 84bdefd82082ec3e33e8b63200701207
 # Remove this line to create a well-formed Fossil manifest.
index 99a60a774297079f1ff01c4eac02ef740c17e1d9..28927e95126c9f5357a29e7d487d1e540b6936f4 100644 (file)
@@ -1 +1 @@
-57e31e6b10b2aa68b6039914d191819bae0aa60999a99d5ef23ca18128b72e0e
\ No newline at end of file
+e7c11d34ee2eebdca4d9db1496bbb4152e4c62745c083ad5e0337733e8d1254e
\ No newline at end of file