]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Code restructuring. Force SQLITE_THREADSAFE in JNI builds for the time being, as...
authorstephan <stephan@noemail.net>
Fri, 25 Aug 2023 11:32:56 +0000 (11:32 +0000)
committerstephan <stephan@noemail.net>
Fri, 25 Aug 2023 11:32:56 +0000 (11:32 +0000)
FossilOrigin-Name: 5a099caa2c21bec647f0a521e7f5d0d1cc2f96d388d3d6c53d5ec80947f33e8d

ext/jni/src/c/sqlite3-jni.c
ext/jni/src/org/sqlite/jni/SQLite3Jni.java
ext/jni/src/org/sqlite/jni/Tester1.java
manifest
manifest.uuid

index 0d2adff5aa4069390f4acfd65de55ad1549bf5fa..4c9f5e6e5bac493636e232fe39a1cb5b06c7e2ba 100644 (file)
 # define SQLITE_THREADSAFE 1
 #endif
 
+/*
+** 2023-08-25: initial attempts at running with SQLITE_THREADSAFE=0
+** lead to as-yet-uninvestigated bad reference errors from JNI.
+*/
+#if SQLITE_THREADSAFE==0
+# error "This code currently requires SQLITE_THREADSAFE!=0."
+#endif
+
 /**********************************************************************/
 /* SQLITE_USE_... */
 #ifndef SQLITE_USE_URI
@@ -445,11 +453,12 @@ struct S3JniGlobalType {
   **   threads. Caching a copy of the JavaVM object enables any thread
   **   with access to the cached object to get access to its own
   **   JNIEnv when necessary.
+  **
   */
   JavaVM * jvm;
   /*
-  ** Cache of Java refs/IDs for NativePointerHolder subclasses.
-  ** Initialized on demand.
+  ** Cache of Java refs and method IDs for NativePointerHolder
+  ** subclasses.  Initialized on demand.
   */
   S3JniNphClass nph[S3Jni_NphCache_size];
   /*
@@ -459,24 +468,23 @@ struct S3JniGlobalType {
     S3JniEnv * aHead /* Linked list of in-use instances */;
     S3JniEnv * aFree /* Linked list of free instances */;
     sqlite3_mutex * mutex /* mutex for aHead and aFree as well for
-                             first-time inits of nph members. */;
+                             first-time inits of nph[] entries. */;
     void const * locker /* env mutex is held on this object's behalf.
                            Used only for sanity checking. */;
   } envCache;
+  /*
+  ** Per-db state. This can move into the core library once we can tie
+  ** client-defined state to db handles there.
+  */
   struct {
-    S3JniDb * aUsed  /* Linked list of in-use instances */;
+    S3JniDb * aHead  /* Linked list of in-use instances */;
     S3JniDb * aFree  /* Linked list of free instances */;
-    sqlite3_mutex * mutex /* mutex for aUsed and aFree */;
+    sqlite3_mutex * mutex /* mutex for aHead and aFree */;
     void const * locker /* perDb mutex is held on this object's
                            behalf.  Unlike envCache.locker, we cannot
                            always have this set to the current JNIEnv
                            object. Used only for sanity checking. */;
   } perDb;
-#ifdef SQLITE_ENABLE_SQLLOG
-  struct {
-    S3JniHook sqllog  /* sqlite3_config(SQLITE_CONFIG_SQLLOG) callback */;
-  } hooks;
-#endif
   /*
   ** Refs to global classes and methods. Obtained during static init
   ** and never released.
@@ -490,6 +498,22 @@ struct S3JniGlobalType {
     jmethodID ctorStringBA   /* the String(byte[],Charset) constructor */;
     jmethodID stringGetBytes /* the String.getBytes(Charset) method */;
   } g /* refs to global Java state */;
+  /**
+     The list of bound auto-extensions (Java-side:
+     org.sqlite.jni.auto_extension objects).
+  */
+  struct {
+    S3JniAutoExtension *pExt /* The auto-extension list. It is
+                                maintained such that all active
+                                entries are in the first contiguous
+                                nExt array elements. */;
+    int nAlloc               /* number of entries allocated for pExt,
+                                as distinct from the number of active
+                                entries. */;
+    int nExt                 /* number of active entries in pExt, all in the
+                                first nExt'th array elements. */;
+    sqlite3_mutex * mutex    /* mutex for manipulation/traversal of pExt */;
+  } autoExt;
 #ifdef SQLITE_ENABLE_FTS5
   struct {
     volatile jobject jFtsExt /* Global ref to Java singleton for the
@@ -500,6 +524,11 @@ struct S3JniGlobalType {
     } jPhraseIter;
   } fts5;
 #endif
+#ifdef SQLITE_ENABLE_SQLLOG
+  struct {
+    S3JniHook sqllog  /* sqlite3_config(SQLITE_CONFIG_SQLLOG) callback */;
+  } hooks;
+#endif
 #ifdef SQLITE_JNI_ENABLE_METRICS
   /* Internal metrics. */
   struct {
@@ -529,18 +558,6 @@ struct S3JniGlobalType {
 #endif
   } metrics;
 #endif /* SQLITE_JNI_ENABLE_METRICS */
-  /**
-     The list of bound auto-extensions (Java-side:
-     org.sqlite.jni.auto_extension objects).
-   */
-  struct {
-    S3JniAutoExtension *pExt /* Head of the auto-extension list */;
-    int nAlloc               /* number of entries allocated for pExt,
-                                as distinct from the number of active
-                                entries. */;
-    int nExt                 /* number of active entries in pExt. */;
-    sqlite3_mutex * mutex    /* mutex for manipulation/traversal of pExt */;
-  } autoExt;
 };
 static S3JniGlobalType S3JniGlobal = {};
 #define SJG S3JniGlobal
@@ -550,23 +567,24 @@ static S3JniGlobalType S3JniGlobal = {};
 #define s3jni_incr(PTR)
 #elif S3JNI_METRICS_MUTEX
 static void s3jni_incr( volatile unsigned int * const p ){
-  sqlite3_mutex * const m = SJG.metrics.mutex;
-  sqlite3_mutex_enter(m);
+  sqlite3_mutex_enter(SJG.metrics.mutex);
   ++SJG.metrics.nMetrics;
   ++(*p);
-  sqlite3_mutex_leave(m);
+  sqlite3_mutex_leave(SJG.metrics.mutex);
 }
 #else
 #define s3jni_incr(PTR) ++(*(PTR))
 #endif
 
 /* Helpers for working with specific mutexes. */
+#if SQLITE_THREADSAFE
 #define S3JniMutex_Env_assertLocked \
   assert( 0 != SJG.envCache.locker && "Misuse of S3JniGlobal.envCache.mutex" )
 #define S3JniMutex_Env_assertLocker \
   assert( (env) == SJG.envCache.locker && "Misuse of S3JniGlobal.envCache.mutex" )
 #define S3JniMutex_Env_assertNotLocker \
   assert( (env) != SJG.envCache.locker && "Misuse of S3JniGlobal.envCache.mutex" )
+
 #define S3JniMutex_Env_enter                        \
   S3JniMutex_Env_assertNotLocker;                   \
   /*MARKER(("Entering ENV mutex@%p %s.\n", env));*/ \
@@ -606,6 +624,19 @@ static void s3jni_incr( volatile unsigned int * const p ){
   assert( env == SJG.perDb.locker );                  \
   SJG.perDb.locker = 0;                               \
   sqlite3_mutex_leave( SJG.perDb.mutex )
+#else /* SQLITE_THREADSAFE==0 */
+#define S3JniMutex_Env_assertLocked
+#define S3JniMutex_Env_assertLocker
+#define S3JniMutex_Env_assertNotLocker
+#define S3JniMutex_Env_enter
+#define S3JniMutex_Env_leave
+#define S3JniMutex_Ext_enter
+#define S3JniMutex_Ext_leave
+#define S3JniMutex_Nph_enter
+#define S3JniMutex_Nph_leave
+#define S3JniMutex_S3JniDb_enter
+#define S3JniMutex_S3JniDb_leave
+#endif
 
 #define s3jni_oom_check(VAR) if( !(VAR) ) s3jni_oom(env)
 static inline void s3jni_oom(JNIEnv * const env){
@@ -917,15 +948,17 @@ static void S3JniHook_unref(JNIEnv * const env, S3JniHook * const s, int doXDest
 */
 static void S3JniDb_set_aside_unlocked(JNIEnv * env, S3JniDb * const s){
   if( s ){
+#if SQLITE_THREADSAFE
     assert( S3JniGlobal.perDb.locker == env );
+#endif
     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.aUsed == s){
+    else if(SJG.perDb.aHead == s){
       assert(!s->pPrev);
-      SJG.perDb.aUsed = s->pNext;
+      SJG.perDb.aHead = s->pNext;
     }
     sqlite3_free( s->zMainDbName );
 #define UNHOOK(MEMBER,XDESTROY) S3JniHook_unref(env, &s->hooks.MEMBER, XDESTROY)
@@ -1107,8 +1140,8 @@ static S3JniDb * S3JniDb_alloc(JNIEnv * const env, sqlite3 *pDb,
     }
   }
   if( rv ){
-    rv->pNext = SJG.perDb.aUsed;
-    SJG.perDb.aUsed = rv;
+    rv->pNext = SJG.perDb.aHead;
+    SJG.perDb.aHead = rv;
     if( rv->pNext ){
       assert(!rv->pNext->pPrev);
       rv->pNext->pPrev = rv;
@@ -1135,7 +1168,7 @@ static S3JniDb * S3JniDb_for_db(JNIEnv * const env, jobject jDb, sqlite3 *pDb){
   S3JniDb * s = 0;
   if( jDb || pDb ){
     S3JniMutex_S3JniDb_enter;
-    s = SJG.perDb.aUsed;
+    s = SJG.perDb.aHead;
     if( !pDb ){
       assert( jDb );
       pDb = PtrGet_sqlite3(jDb);
@@ -4707,6 +4740,7 @@ Java_org_sqlite_jni_SQLite3Jni_init(JniArgsEnvClass){
     {"SQLITE_MAX_TRIGGER_DEPTH", JTYPE_INT, SQLITE_MAX_TRIGGER_DEPTH},
     {"SQLITE_LIMIT_WORKER_THREADS", JTYPE_INT, SQLITE_LIMIT_WORKER_THREADS},
     {"SQLITE_MAX_WORKER_THREADS", JTYPE_INT, SQLITE_MAX_WORKER_THREADS},
+    {"SQLITE_THREADSAFE", JTYPE_INT, SQLITE_THREADSAFE},
     {0,0}
   };
   jfieldID fieldId;
@@ -4714,7 +4748,7 @@ Java_org_sqlite_jni_SQLite3Jni_init(JniArgsEnvClass){
   const ConfigFlagEntry * pConfFlag;
 
   if( 0==sqlite3_threadsafe() ){
-    (*env)->FatalError(env, "sqlite3 was not built with SQLITE_THREADSAFE.");
+    (*env)->FatalError(env, "sqlite3 currently requires SQLITE_THREADSAFE!=0.");
     return;
   }
   memset(&S3JniGlobal, 0, sizeof(S3JniGlobal));
index 9146e61ccadcd1f919e3434a442e74cddb4b4582..5a9e3c080536f1c9f48d1125c77c1402cfd05890 100644 (file)
@@ -1318,6 +1318,10 @@ public final class SQLite3Jni {
   public static final String SQLITE_VERSION = sqlite3_libversion();
   public static final String SQLITE_SOURCE_ID = sqlite3_sourceid();
 
+  // Initialized at static init time to the build-time value of
+  // SQLITE_THREADSAFE.
+  public static int SQLITE_THREADSAFE = -1;
+
   // access
   public static final int SQLITE_ACCESS_EXISTS = 0;
   public static final int SQLITE_ACCESS_READWRITE = 1;
index 7587cad88489be7b52e48387e18e009fe53767dd..1c452f720cbf922145d3d8c2322abe020da41382 100644 (file)
@@ -1530,12 +1530,29 @@ public class Tester1 implements Runnable {
 
     final long timeStart = System.currentTimeMillis();
     int nLoop = 0;
-    affirm( 0==sqlite3_config( SQLITE_CONFIG_SINGLETHREAD ),
-            "Could not switch to single-thread mode." );
-    affirm( 0==sqlite3_config( SQLITE_CONFIG_MULTITHREAD ),
-            "Could not switch to multithread mode."  );
-    affirm( 0==sqlite3_config( SQLITE_CONFIG_SERIALIZED ),
-            "Could not switch to serialized threading mode."  );
+    switch( SQLITE_THREADSAFE ){ /* Sanity checking */
+      case 0:
+        affirm( 0==sqlite3_config( SQLITE_CONFIG_SINGLETHREAD ),
+                "Could not switch to single-thread mode." );
+        affirm( 0!=sqlite3_config( SQLITE_CONFIG_MULTITHREAD ),
+                "Could switch to multithread mode."  );
+        affirm( 0!=sqlite3_config( SQLITE_CONFIG_SERIALIZED ),
+                "Could not switch to serialized threading mode."  );
+        outln("This is a single-threaded build. Not using threads.");
+        nThread = 1;
+        break;
+      case 1:
+      case 2:
+        affirm( 0==sqlite3_config( SQLITE_CONFIG_SINGLETHREAD ),
+                "Could not switch to single-thread mode." );
+        affirm( 0==sqlite3_config( SQLITE_CONFIG_MULTITHREAD ),
+                "Could not switch to multithread mode."  );
+        affirm( 0==sqlite3_config( SQLITE_CONFIG_SERIALIZED ),
+                "Could not switch to serialized threading mode."  );
+        break;
+      default:
+        affirm( false, "Unhandled SQLITE_THREADSAFE value." );
+    }
     outln("libversion_number: ",
           sqlite3_libversion_number(),"\n",
           sqlite3_libversion(),"\n",SQLITE_SOURCE_ID);
index 347cb57fcb87abdc220d85e0a2c2f83ef22d5ff4..88ce877e9e7f6c61fec91ff238dee6a7cb273834 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\sincorrect\s(but\sharmless)\sdependency\son\ssource\scode\sfile\s"sessionfuzz-data1.db"\sfrom\smain.mk\sand\sMakefile.in.
-D 2023-08-25T11:06:26.590
+C Code\srestructuring.\sForce\sSQLITE_THREADSAFE\sin\sJNI\sbuilds\sfor\sthe\stime\sbeing,\sas\sthreadsafe==0\sleads\sto\sas-yet-mysterious\sJNI-level\sreference\serrors.
+D 2023-08-25T11:32:56.589
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -236,7 +236,7 @@ F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a3
 F ext/jni/GNUmakefile 2fe04e7a7534a069ea8448f42e95bb5f8fc279ea3c9883598acedc99bbc254a7
 F ext/jni/README.md 1332b1fa27918bd5d9ca2d0d4f3ac3a6ab86b9e3699dc5bfe32904a027f3d2a9
 F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
-F ext/jni/src/c/sqlite3-jni.c 969e59cdf9ad2394dcfc7b7fd3e259ff27cacfbe4946ccfdb8de6554745a32cb
+F ext/jni/src/c/sqlite3-jni.c 2d13c93fbf83feb2725922cc63e3157284848a435a9ff5faa8949d9157e1490f
 F ext/jni/src/c/sqlite3-jni.h 3d8cdacce26d20fd967d67a2e8539d38fc2e9fe13598147399db4b2c303a89c8
 F ext/jni/src/org/sqlite/jni/Fts5.java a45cd890202d72c3bfe8aea69b57b02b6dd588361af81d8b921954c37940b2f7
 F ext/jni/src/org/sqlite/jni/Fts5Context.java 0a5a02047a6a1dd3e4a38b0e542a8dd2de365033ba30e6ae019a676305959890
@@ -250,8 +250,8 @@ F ext/jni/src/org/sqlite/jni/Nullable.java b2f8755970e9dd0e917a505638d036ccc699c
 F ext/jni/src/org/sqlite/jni/OutputPointer.java 4ae06135decef35eb04498daa2868939d91a294e948747c580ef9ce31563a6b3
 F ext/jni/src/org/sqlite/jni/ResultCode.java ba701f20213a5f259e94cfbfdd36eb7ac7ce7797f2c6c7fca2004ff12ce20f86
 F ext/jni/src/org/sqlite/jni/SQLFunction.java 4d6291fa14fcca1a040609378f9f00a193145d79c3abbda98ba32c340904cbeb
-F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 92d0711f004327728704cc7ff33d9923be6c98dad50515093c96a99f34e13f9d
-F ext/jni/src/org/sqlite/jni/Tester1.java 3bfbcbf0720f9b71e461eb016b8bc30289a7ceaab1aa5da13e319fd303bf19fd
+F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 582242f27aea55bce0d3b88dd63bea03e4cb49a8c40950ef99a7e19d9307dfb9
+F ext/jni/src/org/sqlite/jni/Tester1.java c2e3d18229e9443c3e6cf54a150cfa832219ba63a0b17f7bef102e5e4b2b2a8d
 F ext/jni/src/org/sqlite/jni/TesterFts5.java 6f135c60e24c89e8eecb9fe61dde0f3bb2906de668ca6c9186bcf34bdaf94629
 F ext/jni/src/org/sqlite/jni/ValueHolder.java f022873abaabf64f3dd71ab0d6037c6e71cece3b8819fa10bf26a5461dc973ee
 F ext/jni/src/org/sqlite/jni/authorizer_callback.java 1d2d7fd584f917afa507820644d95504bcc9c5d7363a7afeb58de3b256851bfe
@@ -2100,8 +2100,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 646e7fc3b5ba81c207f013c9a06781986138379f20e787320a811ba3ed5489dc
-R b08c9d8a6a2483e5f535446bff4911b8
-U dan
-Z 116a690cb7924a8fc2ec464347e1c482
+P 17d56c0207f63614b34ef3594d06602ab7a6e85604f3589b30aa79316f1744ee
+R 0d04424045f1de02bc280794aad48b2b
+U stephan
+Z a29af0815bfb2df6f8dd8b5fbb60db4d
 # Remove this line to create a well-formed Fossil manifest.
index 1b78f9a3953647218b7de304c17ef3795ebcfbf3..8c6286a678998826f9985943a11bb956a0d569da 100644 (file)
@@ -1 +1 @@
-17d56c0207f63614b34ef3594d06602ab7a6e85604f3589b30aa79316f1744ee
\ No newline at end of file
+5a099caa2c21bec647f0a521e7f5d0d1cc2f96d388d3d6c53d5ec80947f33e8d
\ No newline at end of file