Remove a superfluous level of indirection in the JNI internals.
FossilOrigin-Name: 8dca6f7660c15eacbda20da1c66c9ef1de36864f78750658226b1a7baf22b726
This commit is contained in:
parent
63f4a9c4db
commit
70b58fc119
@ -294,43 +294,66 @@ static inline void s3jni_unref_local(JNIEnv * const env, jobject const v){
|
||||
#define S3JniUnrefLocal(VAR) s3jni_unref_local(env, (VAR))
|
||||
|
||||
/*
|
||||
** Lookup key type for use with s3jni_nph().
|
||||
** Lookup key type for use with s3jni_nphop() and a cache of a
|
||||
** frequently-needed Java-side class reference and one or two Java
|
||||
** class member IDs.
|
||||
*/
|
||||
typedef struct S3JniNphRef S3JniNphRef;
|
||||
struct S3JniNphRef {
|
||||
typedef struct S3JniNphOp S3JniNphOp;
|
||||
struct S3JniNphOp {
|
||||
const int index /* index into S3JniGlobal.nph[] */;
|
||||
const char * const zName /* Full Java name of the class */;
|
||||
const char * const zMember /* Name of member property */;
|
||||
const char * const zTypeSig /* JNI type signature of zMember */;
|
||||
/*
|
||||
** klazz is a global ref to the class represented by pRef.
|
||||
**
|
||||
** According to:
|
||||
**
|
||||
** https://developer.ibm.com/articles/j-jni/
|
||||
**
|
||||
** > ... the IDs returned for a given class don't change for the
|
||||
** lifetime of the JVM process. But the call to get the field or
|
||||
** method can require significant work in the JVM, because fields
|
||||
** and methods might have been inherited from superclasses, making
|
||||
** the JVM walk up the class hierarchy to find them. Because the
|
||||
** IDs are the same for a given class, you should look them up
|
||||
** once and then reuse them. Similarly, looking up class objects
|
||||
** can be expensive, so they should be cached as well.
|
||||
*/
|
||||
jclass klazz;
|
||||
volatile jfieldID fidValue /* NativePointerHolder.nativePointer or
|
||||
** OutputPointer.T.value */;
|
||||
volatile jmethodID midCtor /* klazz's no-arg constructor. Used by
|
||||
** NativePointerHolder_new(). */;
|
||||
};
|
||||
|
||||
/*
|
||||
** Cache keys for each concrete NativePointerHolder subclasses and
|
||||
** OutputPointer.T types. The members are to be used with s3jni_nph()
|
||||
** OutputPointer.T types. The members are to be used with s3jni_nphop()
|
||||
** and friends, and each one's member->index corresponds to its index
|
||||
** in the S3JniGlobal.nph[] array.
|
||||
*/
|
||||
static const struct {
|
||||
const S3JniNphRef sqlite3;
|
||||
const S3JniNphRef sqlite3_stmt;
|
||||
const S3JniNphRef sqlite3_context;
|
||||
const S3JniNphRef sqlite3_value;
|
||||
const S3JniNphRef OutputPointer_Bool;
|
||||
const S3JniNphRef OutputPointer_Int32;
|
||||
const S3JniNphRef OutputPointer_Int64;
|
||||
const S3JniNphRef OutputPointer_sqlite3;
|
||||
const S3JniNphRef OutputPointer_sqlite3_stmt;
|
||||
const S3JniNphRef OutputPointer_sqlite3_value;
|
||||
const S3JniNphRef OutputPointer_String;
|
||||
const S3JniNphOp sqlite3;
|
||||
const S3JniNphOp sqlite3_stmt;
|
||||
const S3JniNphOp sqlite3_context;
|
||||
const S3JniNphOp sqlite3_value;
|
||||
const S3JniNphOp OutputPointer_Bool;
|
||||
const S3JniNphOp OutputPointer_Int32;
|
||||
const S3JniNphOp OutputPointer_Int64;
|
||||
const S3JniNphOp OutputPointer_sqlite3;
|
||||
const S3JniNphOp OutputPointer_sqlite3_stmt;
|
||||
const S3JniNphOp OutputPointer_sqlite3_value;
|
||||
const S3JniNphOp OutputPointer_String;
|
||||
#ifdef SQLITE_ENABLE_FTS5
|
||||
const S3JniNphRef OutputPointer_ByteArray;
|
||||
const S3JniNphRef Fts5Context;
|
||||
const S3JniNphRef Fts5ExtensionApi;
|
||||
const S3JniNphRef fts5_api;
|
||||
const S3JniNphRef fts5_tokenizer;
|
||||
const S3JniNphRef Fts5Tokenizer;
|
||||
const S3JniNphOp OutputPointer_ByteArray;
|
||||
const S3JniNphOp Fts5Context;
|
||||
const S3JniNphOp Fts5ExtensionApi;
|
||||
const S3JniNphOp fts5_api;
|
||||
const S3JniNphOp fts5_tokenizer;
|
||||
const S3JniNphOp Fts5Tokenizer;
|
||||
#endif
|
||||
} S3JniNphRefs = {
|
||||
} S3JniNphOps = {
|
||||
#define MkRef(INDEX, KLAZZ, MEMBER, SIG) \
|
||||
{ INDEX, "org/sqlite/jni/" KLAZZ, MEMBER, SIG }
|
||||
/* NativePointerHolder ref */
|
||||
@ -364,51 +387,17 @@ static const struct {
|
||||
#undef RefO
|
||||
};
|
||||
|
||||
#define S3JniNph(T) &S3JniNphRefs.T
|
||||
#define S3JniNph(T) &S3JniNphOps.T
|
||||
|
||||
enum {
|
||||
/*
|
||||
** Size of the NativePointerHolder cache. Need enough space for
|
||||
** (only) the library's NativePointerHolder and OutputPointer types,
|
||||
** a fixed count known at build-time. This value needs to be
|
||||
** exactly the number of S3JniNphRef entries in the S3JniNphRefs
|
||||
** exactly the number of S3JniNphOp entries in the S3JniNphOps
|
||||
** object.
|
||||
*/
|
||||
S3Jni_NphCache_size = sizeof(S3JniNphRefs) / sizeof(S3JniNphRef)
|
||||
};
|
||||
|
||||
/*
|
||||
** Cache entry for NativePointerHolder subclasses and OutputPointer
|
||||
** types. The pRef and klazz fields are set up the first time the
|
||||
** entry is fetched using s3jni_nph(). The other fields are
|
||||
** populated as needed by the routines which use them.
|
||||
*/
|
||||
typedef struct S3JniNphClass S3JniNphClass;
|
||||
struct S3JniNphClass {
|
||||
volatile const S3JniNphRef * pRef /* Entry from S3JniNphRefs */;
|
||||
/*
|
||||
** klazz is a global ref to the class represented by pRef.
|
||||
**
|
||||
** According to:
|
||||
**
|
||||
** https://developer.ibm.com/articles/j-jni/
|
||||
**
|
||||
** > ... the IDs returned for a given class don't change for the
|
||||
** lifetime of the JVM process. But the call to get the field or
|
||||
** method can require significant work in the JVM, because fields
|
||||
** and methods might have been inherited from superclasses, making
|
||||
** the JVM walk up the class hierarchy to find them. Because the
|
||||
** IDs are the same for a given class, you should look them up
|
||||
** once and then reuse them. Similarly, looking up class objects
|
||||
** can be expensive, so they should be cached as well.
|
||||
*/
|
||||
jclass klazz;
|
||||
volatile jmethodID midCtor /* klazz's no-arg constructor. Used by
|
||||
** NativePointerHolder_new(). */;
|
||||
volatile jfieldID fidValue /* NativePointerHolder.nativePointer or
|
||||
** OutputPointer.T.value */;
|
||||
volatile jfieldID fidAggCtx /* sqlite3_context.aggregateContext, used only
|
||||
** by the sqlite3_context binding. */;
|
||||
S3Jni_NphCache_size = sizeof(S3JniNphOps) / sizeof(S3JniNphOp)
|
||||
};
|
||||
|
||||
/*
|
||||
@ -420,7 +409,9 @@ struct S3JniHook{
|
||||
jmethodID midCallback /* callback method. Signature depends on
|
||||
** jObj's type */;
|
||||
/* We lookup the jObj.xDestroy() method as-needed for contexts which
|
||||
** have custom finalizers. */
|
||||
** support custom finalizers. Fundamentally we can support them for
|
||||
** any Java type, but we only want to expose support for them where
|
||||
** the C API does. */
|
||||
jobject jExtra /* Global ref to a per-hook-type value */;
|
||||
int doXDestroy /* If true then S3JniHook_unref() will call
|
||||
jObj->xDestroy() if it's available. */;
|
||||
@ -590,10 +581,10 @@ struct S3JniGlobalType {
|
||||
** NativePointerHolder subclasses and OutputPointer.T types.
|
||||
*/
|
||||
struct {
|
||||
S3JniNphClass list[S3Jni_NphCache_size];
|
||||
S3JniNphOp list[S3Jni_NphCache_size];
|
||||
sqlite3_mutex * mutex; /* mutex for this->list */
|
||||
void const * locker; /* sanity-checking-only context object
|
||||
for this->mutex */
|
||||
volatile void const * locker; /* sanity-checking-only context object
|
||||
for this->mutex */
|
||||
} nph;
|
||||
/*
|
||||
** Cache of per-thread state.
|
||||
@ -602,8 +593,9 @@ 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. */;
|
||||
void const * locker /* env mutex is held on this object's behalf.
|
||||
Used only for sanity checking. */;
|
||||
volatile 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
|
||||
@ -612,8 +604,10 @@ struct S3JniGlobalType {
|
||||
struct {
|
||||
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
|
||||
behalf. Used only for sanity checking. */;
|
||||
volatile void const * locker
|
||||
/* perDb mutex is held on this object's behalf. Used only for
|
||||
sanity checking. Note that the mutex is at the class level, not
|
||||
instance level. */;
|
||||
} perDb;
|
||||
struct {
|
||||
S3JniUdf * aFree /* Head of the free-item list. Guarded by global
|
||||
@ -646,8 +640,9 @@ struct S3JniGlobalType {
|
||||
int nExt /* number of active entries in aExt, all in the
|
||||
first nExt'th array elements. */;
|
||||
sqlite3_mutex * mutex /* mutex for manipulation/traversal of aExt */;
|
||||
const void * locker /* object on whose behalf the mutex is held.
|
||||
Only for sanity checking in debug builds. */;
|
||||
volatile const void * locker /* object on whose behalf the mutex
|
||||
is held. Only for sanity checking
|
||||
in debug builds. */;
|
||||
} autoExt;
|
||||
#ifdef SQLITE_ENABLE_FTS5
|
||||
struct {
|
||||
@ -1316,23 +1311,20 @@ static int S3JniEnv_uncache(JNIEnv * const env){
|
||||
** This simple cache catches >99% of searches in the current
|
||||
** (2023-07-31) tests.
|
||||
*/
|
||||
static S3JniNphClass * s3jni__nph(JNIEnv * const env, S3JniNphRef const* pRef){
|
||||
S3JniNphClass * const pNC = &SJG.nph.list[pRef->index];
|
||||
static S3JniNphOp * s3jni__nphop(JNIEnv * const env, S3JniNphOp const* pRef){
|
||||
S3JniNphOp * const pNC = &SJG.nph.list[pRef->index];
|
||||
|
||||
assert( (void*)pRef>=(void*)&S3JniNphRefs && (void*)pRef<(void*)(&S3JniNphRefs + 1)
|
||||
assert( (void*)pRef>=(void*)&S3JniNphOps && (void*)pRef<(void*)(&S3JniNphOps + 1)
|
||||
&& "pRef is out of range" );
|
||||
assert( pRef->index>=0
|
||||
&& (pRef->index < (sizeof(S3JniNphRefs) / sizeof(S3JniNphRef)))
|
||||
&& (pRef->index < (sizeof(S3JniNphOps) / sizeof(S3JniNphOp)))
|
||||
&& "pRef->index is out of range" );
|
||||
if( !pNC->pRef ){
|
||||
if( !pNC->klazz ){
|
||||
S3JniNph_mutex_enter;
|
||||
if( !pNC->pRef ){
|
||||
if( !pNC->klazz ){
|
||||
jclass const klazz = (*env)->FindClass(env, pRef->zName);
|
||||
S3JniExceptionIsFatal("FindClass() unexpectedly threw");
|
||||
pNC->klazz = S3JniRefGlobal(klazz);
|
||||
pNC->pRef = pRef
|
||||
/* Must come last to avoid a race condition where pNC->klass
|
||||
can be NULL after this function returns. */;
|
||||
}
|
||||
S3JniNph_mutex_leave;
|
||||
}
|
||||
@ -1340,11 +1332,11 @@ static S3JniNphClass * s3jni__nph(JNIEnv * const env, S3JniNphRef const* pRef){
|
||||
return pNC;
|
||||
}
|
||||
|
||||
#define s3jni_nph(PRef) s3jni__nph(env, PRef)
|
||||
#define s3jni_nphop(PRef) s3jni__nphop(env, PRef)
|
||||
|
||||
/*
|
||||
** Common code for accessor functions for NativePointerHolder and
|
||||
** OutputPointer types. pRef must be a pointer from S3JniNphRefs. jOut
|
||||
** OutputPointer types. pRef must be a pointer from S3JniNphOps. jOut
|
||||
** must be an instance of that class (Java's type safety takes care of
|
||||
** that requirement). If necessary, this fetches the jfieldID for
|
||||
** jOut's pRef->zMember, which must be of the type represented by the
|
||||
@ -1354,8 +1346,8 @@ static S3JniNphClass * s3jni__nph(JNIEnv * const env, S3JniNphRef const* pRef){
|
||||
**
|
||||
** Property lookups are cached on a per-pRef basis.
|
||||
*/
|
||||
static jfieldID s3jni_nphop_field(JNIEnv * const env, S3JniNphRef const* pRef){
|
||||
S3JniNphClass * const pNC = s3jni_nph(pRef);
|
||||
static jfieldID s3jni_nphop_field(JNIEnv * const env, S3JniNphOp const* pRef){
|
||||
S3JniNphOp * const pNC = s3jni_nphop(pRef);
|
||||
|
||||
if( !pNC->fidValue ){
|
||||
S3JniNph_mutex_enter;
|
||||
@ -1363,7 +1355,7 @@ static jfieldID s3jni_nphop_field(JNIEnv * const env, S3JniNphRef const* pRef){
|
||||
pNC->fidValue = (*env)->GetFieldID(env, pNC->klazz,
|
||||
pRef->zMember, pRef->zTypeSig);
|
||||
S3JniExceptionIsFatal("Code maintenance required: missing "
|
||||
"required S3JniNphClass::fidValue.");
|
||||
"required S3JniNphOp::fidValue.");
|
||||
}
|
||||
S3JniNph_mutex_leave;
|
||||
}
|
||||
@ -1376,7 +1368,7 @@ static jfieldID s3jni_nphop_field(JNIEnv * const env, S3JniNphRef const* pRef){
|
||||
** zClassName must be a static string so we can use its address
|
||||
** as a cache key.
|
||||
*/
|
||||
static void NativePointerHolder__set(JNIEnv * const env, S3JniNphRef const* pRef,
|
||||
static void NativePointerHolder__set(JNIEnv * const env, S3JniNphOp const* pRef,
|
||||
jobject ppOut, const void * p){
|
||||
assert( ppOut );
|
||||
(*env)->SetLongField(env, ppOut, s3jni_nphop_field(env, pRef), (jlong)p);
|
||||
@ -1392,7 +1384,7 @@ static void NativePointerHolder__set(JNIEnv * const env, S3JniNphRef const* pRef
|
||||
** no-op if pObj is NULL.
|
||||
*/
|
||||
static void * NativePointerHolder__get(JNIEnv * env, jobject pObj,
|
||||
S3JniNphRef const* pRef){
|
||||
S3JniNphOp const* pRef){
|
||||
void * rv = 0;
|
||||
if( pObj ){
|
||||
rv = (void*)(*env)->GetLongField(env, pObj, s3jni_nphop_field(env, pRef));
|
||||
@ -1570,7 +1562,7 @@ static void OutputPointer_set_Int64(JNIEnv * const env, jobject const jOut,
|
||||
** Object type.
|
||||
*/
|
||||
static void OutputPointer_set_obj(JNIEnv * const env,
|
||||
S3JniNphRef const * const pRef,
|
||||
S3JniNphOp const * const pRef,
|
||||
jobject const jOut,
|
||||
jobject v){
|
||||
(*env)->SetObjectField(env, jOut, s3jni_nphop_field(env, pRef), v);
|
||||
@ -1666,14 +1658,14 @@ static void ResultJavaValue_finalizer(void *v){
|
||||
** if Java fails to allocate, but the JNI docs are not entirely clear
|
||||
** on that detail.
|
||||
**
|
||||
** Always use a static pointer from the S3JniNphRefs struct for the
|
||||
** Always use a static pointer from the S3JniNphOps struct for the
|
||||
** 2nd argument.
|
||||
*/
|
||||
static jobject NativePointerHolder_new(JNIEnv * const env,
|
||||
S3JniNphRef const * pRef,
|
||||
S3JniNphOp const * pRef,
|
||||
const void * pNative){
|
||||
jobject rv = 0;
|
||||
S3JniNphClass * const pNC = s3jni_nph(pRef);
|
||||
S3JniNphOp * const pNC = s3jni_nphop(pRef);
|
||||
if( !pNC->midCtor ){
|
||||
S3JniNph_mutex_enter;
|
||||
if( !pNC->midCtor ){
|
||||
@ -1826,7 +1818,7 @@ static int udf_args(JNIEnv *env,
|
||||
*jArgv = 0;
|
||||
if( !jcx ) goto error_oom;
|
||||
ja = (*env)->NewObjectArray(
|
||||
env, argc, s3jni_nph(S3JniNph(sqlite3_value))->klazz,
|
||||
env, argc, s3jni_nphop(S3JniNph(sqlite3_value))->klazz,
|
||||
NULL);
|
||||
s3jni_oom_check( ja );
|
||||
if( !ja ) goto error_oom;
|
||||
@ -2113,12 +2105,12 @@ static int s3jni_run_java_auto_extensions(sqlite3 *pDb, const char **pzErr,
|
||||
if( 0==SJG.autoExt.nExt ) return 0;
|
||||
env = s3jni_env();
|
||||
jc = S3JniEnv_get();
|
||||
S3JniAutoExt_mutex_enter;
|
||||
S3JniDb_mutex_enter;
|
||||
ps = jc->pdbOpening ? jc->pdbOpening : S3JniDb_from_c(pDb);
|
||||
if( !ps ){
|
||||
*pzErr = sqlite3_mprintf("Unexpected arrival of null S3JniDb in "
|
||||
"auto-extension runner.");
|
||||
S3JniAutoExt_mutex_leave;
|
||||
S3JniDb_mutex_leave;
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
assert( ps->jDb );
|
||||
@ -2128,7 +2120,7 @@ static int s3jni_run_java_auto_extensions(sqlite3 *pDb, const char **pzErr,
|
||||
ps, 0/* we'll re-set this after open()
|
||||
completes. */);
|
||||
if( rc ){
|
||||
S3JniAutoExt_mutex_leave;
|
||||
S3JniDb_mutex_leave;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@ -2136,7 +2128,7 @@ static int s3jni_run_java_auto_extensions(sqlite3 *pDb, const char **pzErr,
|
||||
assert( ps == jc->pdbOpening );
|
||||
jc->pdbOpening = 0;
|
||||
}
|
||||
S3JniAutoExt_mutex_leave;
|
||||
S3JniDb_mutex_leave;
|
||||
NativePointerHolder_set(S3JniNph(sqlite3), ps->jDb, pDb)
|
||||
/* As of here, the Java/C connection is complete except for the
|
||||
(temporary) lack of finalizer for the ps object. */;
|
||||
@ -4442,10 +4434,12 @@ JniDecl(void,1jni_1internal_1details)(JniArgsEnvClass){
|
||||
SO(S3JniEnv);
|
||||
SO(S3JniHook);
|
||||
SO(S3JniDb);
|
||||
SO(S3JniNphRefs);
|
||||
SO(S3JniNphOps);
|
||||
printf("\t(^^^ %u NativePointerHolder/OutputPointer.T types)\n",
|
||||
(unsigned)S3Jni_NphCache_size);
|
||||
SO(S3JniGlobal);
|
||||
SO(S3JniGlobal.nph);
|
||||
SO(S3JniGlobal.metrics);
|
||||
SO(S3JniAutoExtension);
|
||||
SO(S3JniUdf);
|
||||
#undef SO
|
||||
@ -4457,7 +4451,7 @@ JniDecl(void,1jni_1internal_1details)(JniArgsEnvClass){
|
||||
printf("Mutex entry:"
|
||||
"\n\tglobal = %u"
|
||||
"\n\tenv = %u"
|
||||
"\n\tnph = %u for S3JniNphClass init"
|
||||
"\n\tnph = %u for S3JniNphOp init"
|
||||
"\n\tperDb = %u"
|
||||
"\n\tautoExt list = %u"
|
||||
"\n\tS3JniUdf = %u (free-list)"
|
||||
@ -5034,7 +5028,7 @@ static int s3jni_xTokenize_xToken(void *p, int tFlags, const char* z,
|
||||
** Proxy for Fts5ExtensionApi.xTokenize() and
|
||||
** fts5_tokenizer.xTokenize()
|
||||
*/
|
||||
static jint s3jni_fts5_xTokenize(JniArgsEnvObj, S3JniNphRef const *pRef,
|
||||
static jint s3jni_fts5_xTokenize(JniArgsEnvObj, S3JniNphOp const *pRef,
|
||||
jint tokFlags, jobject jFcx,
|
||||
jbyteArray jbaText, jobject jCallback){
|
||||
Fts5ExtDecl;
|
||||
|
@ -122,7 +122,7 @@ public class Tester1 implements Runnable {
|
||||
affirm(v, "Affirmation failed.");
|
||||
}
|
||||
|
||||
@ManualTest /* because testing this for threading is pointless */
|
||||
@SingleThreadOnly /* because it's thread-agnostic */
|
||||
private void test1(){
|
||||
affirm(sqlite3_libversion_number() == SQLITE_VERSION_NUMBER);
|
||||
}
|
||||
@ -610,7 +610,7 @@ public class Tester1 implements Runnable {
|
||||
affirm( 1 == xDestroyCalled.value );
|
||||
}
|
||||
|
||||
@ManualTest /* because threading is meaningless here */
|
||||
@SingleThreadOnly /* because it's thread-agnostic */
|
||||
private void testToUtf8(){
|
||||
/**
|
||||
https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html
|
||||
@ -978,8 +978,8 @@ public class Tester1 implements Runnable {
|
||||
affirm( 7 == counter.value );
|
||||
}
|
||||
|
||||
@ManualTest /* because threads inherently break this test */
|
||||
private void testBusy(){
|
||||
@SingleThreadOnly /* because threads inherently break this test */
|
||||
private static void testBusy(){
|
||||
final String dbName = "_busy-handler.db";
|
||||
final OutputPointer.sqlite3 outDb = new OutputPointer.sqlite3();
|
||||
final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt();
|
||||
@ -1482,7 +1482,7 @@ public class Tester1 implements Runnable {
|
||||
}
|
||||
|
||||
|
||||
@ManualTest /* we really only want to run this test manually. */
|
||||
@ManualTest /* we really only want to run this test manually */
|
||||
private void testSleep(){
|
||||
out("Sleeping briefly... ");
|
||||
sqlite3_sleep(600);
|
||||
@ -1525,8 +1525,6 @@ public class Tester1 implements Runnable {
|
||||
outln();
|
||||
}
|
||||
}
|
||||
testToUtf8();
|
||||
test1();
|
||||
for(java.lang.reflect.Method m : mlist){
|
||||
nap();
|
||||
try{
|
||||
@ -1536,9 +1534,6 @@ public class Tester1 implements Runnable {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
if( !fromThread ){
|
||||
testBusy();
|
||||
}
|
||||
synchronized( this.getClass() ){
|
||||
++nTestRuns;
|
||||
}
|
||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Further\sJNI\scleanups.
|
||||
D 2023-09-02T08:51:14.022
|
||||
C Remove\sa\ssuperfluous\slevel\sof\sindirection\sin\sthe\sJNI\sinternals.
|
||||
D 2023-09-02T10:18:10.477
|
||||
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 dc6e78f9717470d262b4b3ec17c337834295f9df81717c1539da84106324fd1e
|
||||
F ext/jni/README.md 1332b1fa27918bd5d9ca2d0d4f3ac3a6ab86b9e3699dc5bfe32904a027f3d2a9
|
||||
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
|
||||
F ext/jni/src/c/sqlite3-jni.c d98030bb7f502b42990eeb0f2bd103af0b1f1312ba82892949c5ced85262e036
|
||||
F ext/jni/src/c/sqlite3-jni.c 1ce08538c568ec47ccf9e88e8b6d0e5b8a874520238d809adbfc93feb9f54d27
|
||||
F ext/jni/src/c/sqlite3-jni.h c22f0189254abe26fad3ba132b484785b19a1aa96d34d30d7d8c5ffe6a9b25d1
|
||||
F ext/jni/src/org/sqlite/jni/AbstractCollationCallback.java 95e88ba04f4aac51ffec65693e878e234088b2f21b387f4e4285c8b72b33e436
|
||||
F ext/jni/src/org/sqlite/jni/AggregateFunction.java 7312486bc65fecdb91753c0a4515799194e031f45edbe16a6373cea18f404dc4
|
||||
@ -264,7 +264,7 @@ F ext/jni/src/org/sqlite/jni/SQLFunction.java 544a875d33fd160467d82e2397ac33157b
|
||||
F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 98f8d62492e2d6693336dd42c12267ea7f21eefe219aa85b8dd399bd6b0732bd
|
||||
F ext/jni/src/org/sqlite/jni/ScalarFunction.java 6d387bb499fbe3bc13c53315335233dbf6a0c711e8fa7c521683219b041c614c
|
||||
F ext/jni/src/org/sqlite/jni/TableColumnMetadata.java 54511b4297fa28dcb3f49b24035e34ced10e3fd44fd0e458e784f4d6b0096dab
|
||||
F ext/jni/src/org/sqlite/jni/Tester1.java 93e89c4f72065bf28625cf435c47ed2bd3d937fe5c2431e6e7c3407f09f3f9bc
|
||||
F ext/jni/src/org/sqlite/jni/Tester1.java e62b0e855ef19a703dc53c1eb8395ff49f5dc4c9471627f5ba71b9b831a18b37
|
||||
F ext/jni/src/org/sqlite/jni/TesterFts5.java 2b2d6f3cc9f508358c103b774aee296c0f3d8c2f387d6abae9b8b9055f62c800
|
||||
F ext/jni/src/org/sqlite/jni/TraceV2Callback.java beb0b064c1a5f8bfe585a324ed39a4e33edbe379a3fc60f1401661620d3ca7c0
|
||||
F ext/jni/src/org/sqlite/jni/UpdateHookCallback.java 8376f4a931f2d5612b295c003c9515ba933ee76d8f95610e89c339727376e36c
|
||||
@ -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 f9c1f9cad1ad22f689a4afa13d59bf9969ddaed6624cbc16cb1bf5d1fd0c8a5b
|
||||
R 215167a378a1f1105562740ffd0f1842
|
||||
P 30e38173c3ece0c9f8e7a9710f46cb5e8e8ef101c04531318a7adb070242f5dd
|
||||
R 5b531d67a390c107642befa040c21413
|
||||
U stephan
|
||||
Z 15dc34b47fe3ed21ed7cc58408f87312
|
||||
Z 11b0834dd4cedde9630a4a43d0bbc08f
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
30e38173c3ece0c9f8e7a9710f46cb5e8e8ef101c04531318a7adb070242f5dd
|
||||
8dca6f7660c15eacbda20da1c66c9ef1de36864f78750658226b1a7baf22b726
|
Loading…
Reference in New Issue
Block a user