]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
JNI internal cleanups and docs.
authorstephan <stephan@noemail.net>
Sat, 26 Aug 2023 11:57:34 +0000 (11:57 +0000)
committerstephan <stephan@noemail.net>
Sat, 26 Aug 2023 11:57:34 +0000 (11:57 +0000)
FossilOrigin-Name: b7b26bfb4f86e0b8aaabab258ccb0713737ffd4ecd3156d6a83a4f9a1d25edf6

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

index 1446992c95c0c78061748bd333de7e507ca0d749..d3927f6256f6c021800800712701b4d3e102f50d 100644 (file)
@@ -233,8 +233,8 @@ static inline void s3jni_unref_local(JNIEnv * const env, jobject const v){
 #define S3JniUnrefGlobal(VAR) s3jni_unref_global(env, (VAR))
 #define S3JniUnrefLocal(VAR) s3jni_unref_local(env, (VAR))
 
-/**
-   Keys for use with S3JniGlobal_nph_cache().
+/*
+** Key type for use with S3JniGlobal_nph_cache().
 */
 typedef struct S3NphRef S3NphRef;
 struct S3NphRef {
@@ -242,10 +242,11 @@ struct S3NphRef {
   const char * const zName  /* Full Java name of the class */;
 };
 
-/**
-   Keys for each concrete NativePointerHolder subclass. These are to
-   be used with S3JniGlobal_nph_cache() and friends. These are
-   initialized on-demand by S3JniGlobal_nph_cache().
+/*
+** Cache keys for each concrete NativePointerHolder subclass and
+** OutputPointer type. The members are to be used with
+** S3JniGlobal_nph_cache() and friends, and each one's member->index
+** corresponds to its index in the S3JniGlobal.nph[] array.
 */
 static const struct {
   const S3NphRef sqlite3;
@@ -289,21 +290,14 @@ static const struct {
 #undef NREF
 };
 
-/* Helpers for jstring and jbyteArray. */
-#define s3jni_jstring_to_mutf8(ARG) (*env)->GetStringUTFChars(env, ARG, NULL)
-#define s3jni_mutf8_release(ARG,VAR) if( VAR ) (*env)->ReleaseStringUTFChars(env, ARG, VAR)
-#define s3jni_jbytearray_bytes(ARG) (*env)->GetByteArrayElements(env,ARG, NULL)
-#define s3jni_jbytearray_release(ARG,VAR) if( VAR ) (*env)->ReleaseByteArrayElements(env, ARG, VAR, JNI_ABORT)
-
 enum {
   /*
   ** Size of the NativePointerHolder cache.  Need enough space for
-  ** (only) the library's NativePointerHolder types, a fixed count
-  ** known at build-time. If we add more than this a fatal error will
-  ** be triggered with a reminder to increase this.  This value needs
-  ** to be exactly the number of entries in the S3NphRefs object. The
-  ** index field of those entries are the keys for this particular
-  ** cache.
+  ** (only) the library's NativePointerHolder and OutputPointer types,
+  ** a fixed count known at build-time.  This value needs to be
+  ** exactly the number of S3NphRef entries in the S3NphRefs
+  ** object. The index field of those entries are the keys for this
+  ** particular cache.
   */
   S3Jni_NphCache_size = sizeof(S3NphRefs) / sizeof(S3NphRef)
 };
@@ -315,15 +309,15 @@ enum {
 typedef struct S3JniNphClass S3JniNphClass;
 struct S3JniNphClass {
   volatile const S3NphRef * pRef /* Entry from S3NphRefs. */;
-  jclass klazz              /* global ref to the concrete
-                            ** NativePointerHolder subclass represented by
-                            ** zClassName */;
-  volatile jmethodID midCtor /* klazz's no-arg constructor. Used by
-                             ** new_NativePointerHolder_object(). */;
-  volatile jfieldID fidValue /* NativePointerHolder.nativePointer or
-                             ** OutputPointer.T.value */;
-  volatile jfieldID fidAggCtx /* sqlite3_context::aggregateContext. Used only
-                              **  by the sqlite3_context binding. */;
+  jclass klazz                /* global ref to the concrete
+                              ** NativePointerHolder subclass
+                              ** represented by zClassName */;
+  volatile jmethodID midCtor  /* klazz's no-arg constructor. Used by
+                              ** new_NativePointerHolder_object(). */;
+  volatile jfieldID fidValue  /* NativePointerHolder.nativePointer or
+                              ** OutputPointer.T.value */;
+  volatile jfieldID fidAggCtx /* sqlite3_context.aggregateContext, used only
+                              ** by the sqlite3_context binding. */;
 };
 
 /*
@@ -337,7 +331,7 @@ struct S3JniHook{
   /* We lookup the jObj.xDestroy() method as-needed for contexts which
   ** have custom finalizers. */
 };
-#ifndef SQLITE_ENABLE_PREUPDATE_HOOK
+#if !defined(SQLITE_ENABLE_PREUPDATE_HOOK) || defined(SQLITE_ENABLE_SQLLOG)
 static const S3JniHook S3JniHook_empty = {0,0};
 #endif
 
@@ -459,6 +453,7 @@ struct S3JniGlobalType {
   **
   */
   JavaVM * jvm;
+  sqlite3_mutex * mutex;
   /*
   ** Cache of Java refs and method IDs for NativePointerHolder
   ** subclasses.  Initialized on demand.
@@ -546,6 +541,7 @@ struct S3JniGlobalType {
                                          a S3JniNphClass operation. */;
     volatile unsigned nMutexPerDb     /* number of times perDb.mutex was entered */;
     volatile unsigned nMutexAutoExt   /* number of times autoExt.mutex was entered */;
+    volatile unsigned nMutexGlobal    /* number of times global mutex was entered. */;
     volatile unsigned nDestroy        /* xDestroy() calls across all types */;
     volatile unsigned nPdbAlloc       /* Number of S3JniDb alloced. */;
     volatile unsigned nPdbRecycled    /* Number of S3JniDb reused. */;
@@ -601,6 +597,7 @@ static void s3jni_incr( volatile unsigned int * const p ){
   S3JniMutex_Env_assertLocker;                       \
   SJG.envCache.locker = 0;                           \
   sqlite3_mutex_leave( SJG.envCache.mutex )
+
 #define S3JniMutex_Ext_enter                            \
   /*MARKER(("Entering autoExt mutex@%p %s.\n", env));*/ \
   sqlite3_mutex_enter( SJG.autoExt.mutex );             \
@@ -612,6 +609,15 @@ static void s3jni_incr( volatile unsigned int * const p ){
   sqlite3_mutex_leave( SJG.autoExt.mutex )
 #define S3JniMutex_Ext_assertLocker                     \
   assert( env == SJG.autoExt.locker )
+
+#define S3JniMutex_Global_enter                        \
+  /*MARKER(("Entering GLOBAL mutex@%p %s.\n", env));*/ \
+  sqlite3_mutex_enter( SJG.mutex );                    \
+  s3jni_incr(&SJG.metrics.nMutexGlobal);
+#define S3JniMutex_Global_leave                         \
+  /*MARKER(("Leaving GLOBAL mutex @%p %s.\n", env));*/  \
+  sqlite3_mutex_leave( SJG.mutex )
+
 #define S3JniMutex_Nph_enter                        \
   S3JniMutex_Env_assertNotLocker;                   \
   /*MARKER(("Entering NPH mutex@%p %s.\n", env));*/ \
@@ -623,6 +629,7 @@ static void s3jni_incr( volatile unsigned int * const p ){
   S3JniMutex_Env_assertLocker;                       \
   SJG.envCache.locker = 0;                           \
   sqlite3_mutex_leave( SJG.envCache.mutex )
+
 #define S3JniMutex_S3JniDb_enter                      \
   sqlite3_mutex_enter( SJG.perDb.mutex );             \
   assert( 0==SJG.perDb.locker );                      \
@@ -633,6 +640,7 @@ 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
@@ -642,17 +650,29 @@ static void s3jni_incr( volatile unsigned int * const p ){
 #define S3JniMutex_Ext_assertLocker
 #define S3JniMutex_Ext_enter
 #define S3JniMutex_Ext_leave
+#define S3JniMutex_Global_enter
+#define S3JniMutex_Global_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)
+/* Helpers for jstring and jbyteArray. */
+#define s3jni_jstring_to_mutf8(ARG) (*env)->GetStringUTFChars(env, ARG, NULL)
+#define s3jni_mutf8_release(ARG,VAR) if( VAR ) (*env)->ReleaseStringUTFChars(env, ARG, VAR)
+#define s3jni_jbytearray_bytes(ARG) (*env)->GetByteArrayElements(env,ARG, NULL)
+#define s3jni_jbytearray_release(ARG,VAR) if( VAR ) (*env)->ReleaseByteArrayElements(env, ARG, VAR, JNI_ABORT)
+
+
+/* Fail fatally with an OOM message. */
 static inline void s3jni_oom(JNIEnv * const env){
   (*env)->FatalError(env, "Out of memory.") /* does not return */;
 }
 
+/* Fail fatally if !VAR. */
+#define s3jni_oom_check(VAR) if( !(VAR) ) s3jni_oom(env)
+
 /*
 ** sqlite3_malloc() proxy which fails fatally on OOM.  This should
 ** only be used for routines which manage global state and have no
@@ -969,8 +989,8 @@ static void S3JniHook_unref(JNIEnv * const env, S3JniHook * const s, int doXDest
 ** has to haves its own Java reference, but it need only be
 ** call-local.
 */
-static void S3JniHook_copy( JNIEnv * const env, S3JniHook const * const src,
-                            S3JniHook * const dest ){
+static void S3JniHook_localdup( JNIEnv * const env, S3JniHook const * const src,
+                                S3JniHook * const dest ){
   S3JniMutex_S3JniDb_enter;
   *dest = *src;
   if(dest->jObj) dest->jObj = S3JniRefLocal(dest->jObj);
@@ -1402,7 +1422,7 @@ static int CollationState_xCompare(void *pArg, int nLhs, const void *lhs,
   jint rc = 0;
   S3JniHook hook;
 
-  S3JniHook_copy(env, &ps->hooks.collation, &hook );
+  S3JniHook_localdup(env, &ps->hooks.collation, &hook );
   if( hook.jObj ){
     jbyteArray jbaLhs = (*env)->NewByteArray(env, (jint)nLhs);
     jbyteArray jbaRhs = jbaLhs ? (*env)->NewByteArray(env, (jint)nRhs) : NULL;
@@ -2092,7 +2112,7 @@ static int s3jni_busy_handler(void* pState, int n){
   S3JniDeclLocal_env;
   S3JniHook hook;
 
-  S3JniHook_copy(env, &ps->hooks.busyHandler, &hook );
+  S3JniHook_localdup(env, &ps->hooks.busyHandler, &hook );
   if( hook.jObj ){
     rc = (*env)->CallIntMethod(env, hook.jObj,
                                hook.midCallback, (jint)n);
@@ -2230,7 +2250,7 @@ static void s3jni_collation_needed_impl16(void *pState, sqlite3 *pDb,
   S3JniDeclLocal_env;
   S3JniHook hook;
 
-  S3JniHook_copy(env, &ps->hooks.collationNeeded, &hook );
+  S3JniHook_localdup(env, &ps->hooks.collationNeeded, &hook );
   if( hook.jObj ){
     unsigned int const nName = s3jni_utf16_strlen(z16Name);
     jstring jName = (*env)->NewString(env, (jchar const *)z16Name, nName);
@@ -2354,7 +2374,7 @@ static int s3jni_commit_rollback_hook_impl(int isCommit,
   int rc = 0;
   S3JniHook hook;
 
-  S3JniHook_copy( env,
+  S3JniHook_localdup( env,
                   isCommit ? &ps->hooks.commit : &ps->hooks.rollback,
                   &hook);
   if( hook.jObj ){
@@ -2472,9 +2492,12 @@ static void s3jni_config_sqllog(void *ignored, sqlite3 *pDb, const char *z, int
   jstring jArg1 = 0;
   S3JniDeclLocal_env;
   S3JniDb * const ps = S3JniDb_for_db(env, 0, pDb);
-  S3JniHook * const hook = &SJG.hooks.sqllog;
+  S3JniHook hook = S3JniHook_empty;
 
-  if( !ps || !hook->jObj ) return;
+  if( ps ){
+    S3JniHook_localdup(env, &SJG.hooks.sqllog, &hook);
+  }
+  if( !hook.jObj ) return;
   jArg0 = S3JniRefLocal(ps->jDb);
   switch( op ){
     case 0: /* db opened */
@@ -2487,11 +2510,12 @@ static void s3jni_config_sqllog(void *ignored, sqlite3 *pDb, const char *z, int
       (*env)->FatalError(env, "Unhandled 4th arg to SQLITE_CONFIG_SQLLOG.");
       break;
   }
-  (*env)->CallVoidMethod(env, hook->jObj, hook->midCallback, jArg0, jArg1, op);
+  (*env)->CallVoidMethod(env, hook.jObj, hook.midCallback, jArg0, jArg1, op);
   S3JniIfThrew{
     S3JniExceptionWarnCallbackThrew("SQLITE_CONFIG_SQLLOG callback");
     S3JniExceptionClear;
   }
+  S3JniUnrefLocal(hook.jObj);
   S3JniUnrefLocal(jArg0);
   S3JniUnrefLocal(jArg1);
 }
@@ -2502,41 +2526,40 @@ void sqlite3_init_sqllog(void){
 #endif
 
 S3JniApi(sqlite3_config() /* for SQLLOG */,
-         jint,1config__Lorg_sqlite_jni_SQLLog_2)(JniArgsEnvClass, jobject jLog){
+         jint, 1config__Lorg_sqlite_jni_ConfigSqllogCallback_2)(
+           JniArgsEnvClass, jobject jLog
+         ){
 #ifndef SQLITE_ENABLE_SQLLOG
   return SQLITE_MISUSE;
 #else
-  S3JniHook tmpHook;
-  S3JniHook * const hook = &tmpHook;
-  S3JniHook * const hookOld = & SJG.hooks.sqllog;
-  jclass klazz;
+  S3JniHook * const pHook = &SJG.hooks.sqllog;
   int rc = 0;
+
+  S3JniMutex_Global_enter;
   if( !jLog ){
-    S3JniHook_unref(env, hookOld, 0);
-    return 0;
-  }
-  if( hookOld->jObj && (*env)->IsSameObject(env, jLog, hookOld->jObj) ){
-    return 0;
-  }
-  klazz = (*env)->GetObjectClass(env, jLog);
-  hook->midCallback = (*env)->GetMethodID(env, klazz, "call",
-                                          "(Lorg/sqlite/jni/sqlite3;"
-                                          "Ljava/lang/String;"
-                                          "I)V");
-  S3JniUnrefLocal(klazz);
-  if( !hook->midCallback ){
-    S3JniExceptionWarnIgnore;
-    S3JniHook_unref(env, hook, 0);
-    return SQLITE_ERROR;
-  }
-  hook->jObj = S3JniRefGlobal(jLog);
-  rc = sqlite3_config( SQLITE_CONFIG_SQLLOG, s3jni_config_sqllog, 0 );
-  if( rc ){
-    S3JniHook_unref(env, hook, 0);
-  }else{
-    S3JniHook_unref(env, hookOld, 0);
-    *hookOld = *hook;
+    S3JniHook_unref(env, pHook, 0);
+  }else if( pHook->jObj && (*env)->IsSameObject(env, jLog, pHook->jObj) ){
+    /* No-op */
+  }else {
+    jclass const klazz = (*env)->GetObjectClass(env, jLog);
+    jmethodID const midCallback = (*env)->GetMethodID(env, klazz, "call",
+                                                      "(Lorg/sqlite/jni/sqlite3;"
+                                                      "Ljava/lang/String;"
+                                                      "I)V");
+    S3JniUnrefLocal(klazz);
+    if( midCallback ){
+      rc = sqlite3_config( SQLITE_CONFIG_SQLLOG, s3jni_config_sqllog, 0 );
+      if( 0==rc ){
+        S3JniHook_unref(env, pHook, 0);
+        pHook->midCallback = midCallback;
+        pHook->jObj = S3JniRefGlobal(jLog);
+      }
+    }else{
+      S3JniExceptionWarnIgnore;
+      rc = SQLITE_ERROR;
+    }
   }
+  S3JniMutex_Global_leave;
   return rc;
 #endif
 }
@@ -3080,7 +3103,7 @@ static void s3jni_updatepre_hook_impl(void * pState, sqlite3 *pDb, int opId,
   const int isPre = 0!=pDb;
   S3JniHook hook;
 
-  S3JniHook_copy(env, isPre ?
+  S3JniHook_localdup(env, isPre ?
 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
                  &ps->hooks.preUpdate
 #else
@@ -3274,7 +3297,7 @@ static int s3jni_progress_handler_impl(void *pP){
   S3JniDeclLocal_env;
   S3JniHook hook;
 
-  S3JniHook_copy( env, &ps->hooks.progress, &hook );
+  S3JniHook_localdup( env, &ps->hooks.progress, &hook );
   if( hook.jObj ){
     rc = (int)(*env)->CallIntMethod(env, hook.jObj, hook.midCallback);
     S3JniIfThrew{
@@ -3569,7 +3592,7 @@ int s3jni_xAuth(void* pState, int op,const char*z0, const char*z1,
   S3JniHook hook;
   int rc = 0;
 
-  S3JniHook_copy(env, &ps->hooks.auth, &hook );
+  S3JniHook_localdup(env, &ps->hooks.auth, &hook );
   if( hook.jObj ){
     jstring const s0 = z0 ? s3jni_utf8_to_jstring(env, z0, -1) : 0;
     jstring const s1 = z1 ? s3jni_utf8_to_jstring(env, z1, -1) : 0;
@@ -3759,7 +3782,7 @@ static int s3jni_trace_impl(unsigned traceflag, void *pC, void *pP, void *pX){
   int rc = 0;
   S3JniHook hook;
 
-  S3JniHook_copy( env, &ps->hooks.trace, &hook );
+  S3JniHook_localdup( env, &ps->hooks.trace, &hook );
   if( !hook.jObj ){
     return 0;
   }
@@ -3973,13 +3996,15 @@ JniDecl(void,1jni_1internal_1details)(JniArgsEnvClass){
          SJG.metrics.envCacheMisses,
          SJG.metrics.envCacheHits);
   printf("Mutex entry:"
+         "\n\tglobal %u"
          "\n\tenv %u"
          "\n\tnph inits %u"
          "\n\tperDb %u"
          "\n\tautoExt %u list accesses"
          "\n\tmetrics %u\n",
-         SJG.metrics.nMutexEnv, SJG.metrics.nMutexEnv2,
-         SJG.metrics.nMutexPerDb, SJG.metrics.nMutexAutoExt,
+         SJG.metrics.nMutexGlobal, SJG.metrics.nMutexEnv,
+         SJG.metrics.nMutexEnv2, SJG.metrics.nMutexPerDb,
+         SJG.metrics.nMutexAutoExt,
          SJG.metrics.nMetrics);
   printf("S3JniDb: %u alloced (*%u = %u bytes), %u recycled\n",
          SJG.metrics.nPdbAlloc, (unsigned) sizeof(S3JniDb),
@@ -4906,6 +4931,8 @@ Java_org_sqlite_jni_SQLite3Jni_init(JniArgsEnvClass){
   S3JniUnrefLocal(klazz);
 #endif
 
+  SJG.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+  s3jni_oom_check( SJG.mutex );
   SJG.envCache.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
   s3jni_oom_check( SJG.envCache.mutex );
   SJG.perDb.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
index 6c1ec796db2aa0a76e4f627f79ee4c9d1f3cc302..86b20e70c3bcc34a4dc481454f9cbc8aee9004f7 100644 (file)
@@ -494,6 +494,11 @@ public final class SQLite3Jni {
 
      <p>Others may be added in the future. It returns SQLITE_MISUSE if
      given an argument it does not handle.
+
+     <p>Note that sqlite3_config() is not threadsafe with regards to
+     the rest of the library. This must not be called when any other
+     library APIs are being called.
+
   */
   public static native int sqlite3_config(int op);
 
@@ -504,8 +509,13 @@ public final class SQLite3Jni {
      logger. If installation of a logger fails, any previous logger is
      retained.
 
-     If not built with SQLITE_ENABLE_SQLLOG defined, this returns
+     <p>If not built with SQLITE_ENABLE_SQLLOG defined, this returns
      SQLITE_MISUSE.
+
+     <p>Note that sqlite3_config() is not threadsafe with regards to
+     the rest of the library. This must not be called when any other
+     library APIs are being called.
+
   */
   public static native int sqlite3_config( @Nullable ConfigSqllogCallback logger );
 
index db9eb67524e4221f8e94acb877355189a32cd9e7..cd32317d2a3dd15c0aad0645fc001cf3f903c9bf 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\sthe\sJava\sBusyHandler.xDestroy()\smethod\s-\sit\sshould\snot\shave\shad\sone.\sEliminate\sthe\slast\sof\sthe\spotentially-significant\sMUTF-8\scases.
-D 2023-08-26T10:51:19.217
+C JNI\sinternal\scleanups\sand\sdocs.
+D 2023-08-26T11:57:34.208
 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 b28f8b304ef97db8250857cb463aea1b329bfcb584a2902d4c1a490a831e2c9d
 F ext/jni/README.md 1332b1fa27918bd5d9ca2d0d4f3ac3a6ab86b9e3699dc5bfe32904a027f3d2a9
 F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
-F ext/jni/src/c/sqlite3-jni.c 86a9f9182e8c0b1f058196ac4017f3290b948bcfbea1bc55198bdd0ad10a2ea1
+F ext/jni/src/c/sqlite3-jni.c e914d5ec2d7a80a2735d777b4309c1bb0adc721be63abed0b9927a3880008f9b
 F ext/jni/src/c/sqlite3-jni.h 2745c4abd0933a4e8cc48989fffbad3936b4eaada64cce9ce11453dcd30e4184
 F ext/jni/src/org/sqlite/jni/AggregateFunction.java e0aac6ccae05702f8ee779820570866a2760aaa57a73135c57c8d3580bef52d5
 F ext/jni/src/org/sqlite/jni/AuthorizerCallback.java c374bb76409cce7a0bdba94877706b59ac6127fa5d9e6af3e8058c99ce99c030
@@ -262,7 +262,7 @@ F ext/jni/src/org/sqlite/jni/ResultCode.java ba701f20213a5f259e94cfbfdd36eb7ac7c
 F ext/jni/src/org/sqlite/jni/RollbackHookCallback.java be7f7a26d1102fb514d835e11198d51302af8053d97188bfb2e34c2133208568
 F ext/jni/src/org/sqlite/jni/SQLFunction.java d060f302b2cc4cf7a4f5a6b2d36458a2e6fc9648374b5d09c36a43665af41207
 F ext/jni/src/org/sqlite/jni/SQLite3CallbackProxy.java 13c4ea6f35871261eba63fa4117715515e0beecbdebfb879ec5b1f340ed36904
-F ext/jni/src/org/sqlite/jni/SQLite3Jni.java cb3040fcfe35199bb10b4bca2cc541ca383563f85c9b460412c3bd15f413ae23
+F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 4be23360d93011d80676bebb1f21f7da0fc4ab637a6d138c8c35bbb2f764b19d
 F ext/jni/src/org/sqlite/jni/ScalarFunction.java 21301a947e49f0dd9c682dfe2cc8a6518226c837253dd791cd512f847eeca52c
 F ext/jni/src/org/sqlite/jni/Tester1.java 2921142fff8cd5a09d1cee30853457926dc63e647df9a687265bb4e678bc9570
 F ext/jni/src/org/sqlite/jni/TesterFts5.java 6f135c60e24c89e8eecb9fe61dde0f3bb2906de668ca6c9186bcf34bdaf94629
@@ -2103,8 +2103,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 f2af7bbf493fe28d92fc9c77425f8bb9d48c02af9a5eabceb0365c705651e114
-R 0a5c5021d2a5ccca7e44db0ac1e86f8f
+P c852f1ebbde273c3d28fe5aff0bf73cfc06b41dd371a94d7520536dc7a1dbcc1
+R e2cc30a4c5c5fdac12de199e721e1eae
 U stephan
-Z 3f70be94b4b4f3d48d8c6e932937aea1
+Z afcbdc6516d9f37dfcef349abedaeb15
 # Remove this line to create a well-formed Fossil manifest.
index 8ec48b7eebdb3789f41417a35262e71f3be38e17..d29f07c1cc47f7b0ad708eaef5ad83407704c609 100644 (file)
@@ -1 +1 @@
-c852f1ebbde273c3d28fe5aff0bf73cfc06b41dd371a94d7520536dc7a1dbcc1
\ No newline at end of file
+b7b26bfb4f86e0b8aaabab258ccb0713737ffd4ecd3156d6a83a4f9a1d25edf6
\ No newline at end of file