#define JBA_RELEASE(ARG,VAR) if(VAR) (*env)->ReleaseByteArrayElements(env, ARG, VAR, JNI_ABORT)
/* Marker for code which needs(?) to be made thread-safe. */
-#define FIXME_THREADING
+#define FIXME_THREADING(REASON)
enum {
/**
insofar as possible. Calls (*env)->FatalError() if allocation of
an entry fails. That's hypothetically possible but "shouldn't happen."
*/
-FIXME_THREADING
+FIXME_THREADING(S3JniEnvCache)
static S3JniEnvCache * S3JniGlobal_env_cache(JNIEnv * const env){
struct S3JniEnvCache * row = S3JniGlobal.envCache.aHead;
for( ; row; row = row->pNext ){
System.out.println(e.getMessage()); // Hi
}
*/
+FIXME_THREADING(S3JniEnvCache)
static char * s3jni_exception_error_msg(JNIEnv * const env, jthrowable jx ){
S3JniEnvCache * const jc = S3JniGlobal_env_cache(env);
jmethodID mid;
/**
Clears s's state and moves it to the free-list.
*/
-FIXME_THREADING
+FIXME_THREADING(perDb)
static void S3JniDb_set_aside(S3JniDb * const s){
if(s){
JNIEnv * const env = s->env;
Results are undefined if a Java-side db uses the API
from the given JNIEnv after this call.
*/
-FIXME_THREADING
+FIXME_THREADING(perDb)
static void S3JniDb_free_for_env(JNIEnv *env){
S3JniDb * ps = S3JniGlobal.perDb.aUsed;
S3JniDb * pNext = 0;
This simple cache catches >99% of searches in the current
(2023-07-31) tests.
*/
-FIXME_THREADING
+FIXME_THREADING(S3JniEnvCache)
static S3JniNphCache * S3JniGlobal_nph_cache(JNIEnv * const env, const char *zClassName){
/**
According to:
required for functions, like sqlite3_context_db_handle(), which
return a (sqlite3*) but do not take one as an argument.
*/
-FIXME_THREADING
+FIXME_THREADING(S3JniEnvCache)
+FIXME_THREADING(perDb)
static S3JniDb * S3JniDb_for_db(JNIEnv * const env, jobject jDb,
sqlite3 *pDb, int allocIfNeeded){
S3JniDb * s = S3JniGlobal.perDb.aUsed;
called from the context of a separate JNIEnv than the one mapped
to in the returned object. Returns 0 if no match is found.
*/
-FIXME_THREADING
+FIXME_THREADING(perDb)
static S3JniDb * S3JniDb_for_db2(sqlite3 *pDb){
S3JniDb * s = S3JniGlobal.perDb.aUsed;
for( ; pDb && s; s = s->pNext){
#if S3JNI_ENABLE_AUTOEXT
/* Central auto-extension handler. */
-FIXME_THREADING
+FIXME_THREADING(autoExt)
static int s3jni_auto_extension(sqlite3 *pDb, const char **pzErr,
const struct sqlite3_api_routines *ignored){
S3JniAutoExtension const * pAX = S3JniGlobal.autoExt.pHead;
return rc;
}
+FIXME_THREADING(autoExt)
JDECL(jint,1auto_1extension)(JENV_OSELF, jobject jAutoExt){
static int once = 0;
S3JniAutoExtension * ax;
}
#endif /* S3JNI_ENABLE_AUTOEXT */
+FIXME_THREADING(S3JniEnvCache)
JDECL(jint,1bind_1blob)(JENV_CSELF, jobject jpStmt,
jint ndx, jbyteArray baData, jint nMax){
int rc;
return (jint)rc;
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jint,1bind_1double)(JENV_CSELF, jobject jpStmt,
jint ndx, jdouble val){
return (jint)sqlite3_bind_double(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, (double)val);
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jint,1bind_1int)(JENV_CSELF, jobject jpStmt,
jint ndx, jint val){
return (jint)sqlite3_bind_int(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, (int)val);
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jint,1bind_1int64)(JENV_CSELF, jobject jpStmt,
jint ndx, jlong val){
return (jint)sqlite3_bind_int64(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, (sqlite3_int64)val);
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jint,1bind_1null)(JENV_CSELF, jobject jpStmt,
jint ndx){
return (jint)sqlite3_bind_null(PtrGet_sqlite3_stmt(jpStmt), (int)ndx);
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jint,1bind_1parameter_1index)(JENV_CSELF, jobject jpStmt, jbyteArray jName){
int rc = 0;
jbyte * const pBuf = JBA_TOC(jName);
return rc;
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jint,1bind_1text)(JENV_CSELF, jobject jpStmt,
jint ndx, jbyteArray baData, jint nMax){
if(baData){
}
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jint,1bind_1zeroblob)(JENV_CSELF, jobject jpStmt,
jint ndx, jint n){
return (jint)sqlite3_bind_zeroblob(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, (int)n);
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jint,1bind_1zeroblob64)(JENV_CSELF, jobject jpStmt,
jint ndx, jlong n){
return (jint)sqlite3_bind_zeroblob(PtrGet_sqlite3_stmt(jpStmt), (int)ndx, (sqlite3_uint64)n);
return rc;
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jint,1busy_1handler)(JENV_CSELF, jobject jDb, jobject jBusy){
S3JniDb * const ps = S3JniDb_for_db(env, jDb, 0, 0);
int rc = 0;
: sqlite3_busy_handler(ps->pDb, 0, 0);
}
+FIXME_THREADING(S3JniEnvCache)
+FIXME_THREADING(perDb)
JDECL(jint,1busy_1timeout)(JENV_CSELF, jobject jDb, jint ms){
S3JniDb * const ps = S3JniDb_for_db(env, jDb, 0, 0);
if( ps ){
}
#if S3JNI_ENABLE_AUTOEXT
-JDECL(jboolean,1cancel_1auto_1extension)(JENV_OSELF, jobject jAutoExt){
+FIXME_THREADING(autoExt)
+JDECL(jboolean,1cancel_1auto_1extension)(JENV_CSELF, jobject jAutoExt){
S3JniAutoExtension * ax;;
if( S3JniGlobal.autoExt.isRunning ) return JNI_FALSE;
for( ax = S3JniGlobal.autoExt.pHead; ax; ax = ax->pNext ){
return (jint)rc;
}
+FIXME_THREADING(S3JniEnvCache)
+FIXME_THREADING(perDb)
JDECL(jint,1close_1v2)(JENV_CSELF, jobject pDb){
return s3jni_close_db(env, pDb, 2);
}
+FIXME_THREADING(S3JniEnvCache)
+FIXME_THREADING(perDb)
JDECL(jint,1close)(JENV_CSELF, jobject pDb){
return s3jni_close_db(env, pDb, 1);
}
UNREF_L(jName);
}
+FIXME_THREADING(S3JniEnvCache)
+FIXME_THREADING(perDb)
JDECL(jint,1collation_1needed)(JENV_CSELF, jobject jDb, jobject jHook){
S3JniDb * const ps = S3JniDb_for_db(env, jDb, 0, 0);
jclass klazz;
return rc;
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jbyteArray,1column_1blob)(JENV_CSELF, jobject jpStmt,
jint ndx){
sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt);
}
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jdouble,1column_1double)(JENV_CSELF, jobject jpStmt,
jint ndx){
return (jdouble)sqlite3_column_double(PtrGet_sqlite3_stmt(jpStmt), (int)ndx);
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jint,1column_1int)(JENV_CSELF, jobject jpStmt,
jint ndx){
return (jint)sqlite3_column_int(PtrGet_sqlite3_stmt(jpStmt), (int)ndx);
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jlong,1column_1int64)(JENV_CSELF, jobject jpStmt,
jint ndx){
return (jlong)sqlite3_column_int64(PtrGet_sqlite3_stmt(jpStmt), (int)ndx);
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jbyteArray,1column_1text)(JENV_CSELF, jobject jpStmt,
jint ndx){
sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt);
return s3jni_new_jbyteArray(env, p, n);
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jstring,1column_1text16)(JENV_CSELF, jobject jpStmt,
jint ndx){
sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt);
return s3jni_text16_to_jstring(env, p, n);
}
+FIXME_THREADING(S3JniEnvCache)
JDECL(jobject,1column_1value)(JENV_CSELF, jobject jpStmt,
jint ndx){
sqlite3_value * const sv = sqlite3_column_value(PtrGet_sqlite3_stmt(jpStmt), (int)ndx);
(void)s3jni_commit_rollback_hook_impl(0, pP);
}
+FIXME_THREADING(perDb)
static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env,jobject jDb,
jobject jHook){
S3JniDb * const ps = S3JniDb_for_db(env, jDb, 0, 0);
return rc;
}
+FIXME_THREADING(perDb)
/* sqlite3_db_config() for (int,int*) */
/* ACHTUNG: openjdk v19 creates a different mangled name for this
function than openjdk v8 does. */
);
}
+FIXME_THREADING(perDb)
JDECL(jobject,1context_1db_1handle)(JENV_CSELF, jobject jpCx){
sqlite3 * const pDb = sqlite3_context_db_handle(PtrGet_sqlite3_context(jpCx));
S3JniDb * const ps = pDb ? S3JniDb_for_db(env, 0, pDb, 0) : 0;
MUTF-8 incompatibility */;
}
+JDECL(jstring,1expanded_1sql)(JENV_CSELF, jobject jpStmt){
+ sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt);
+ jstring rv = 0;
+ if( pStmt ){
+ S3JniEnvCache * const jc = S3JniGlobal_env_cache(env);
+ char * zSql = sqlite3_expanded_sql(pStmt);
+ OOM_CHECK(zSql);
+ if( zSql ){
+ rv = s3jni_utf8_to_jstring(jc, zSql, -1);
+ sqlite3_free(zSql);
+ }
+ }
+ return rv;
+}
+
JDECL(jboolean,1extended_1result_1codes)(JENV_CSELF, jobject jpDb,
jboolean onoff){
int const rc = sqlite3_extended_result_codes(PtrGet_sqlite3(jpDb), onoff ? 1 : 0);
return sqlite3_shutdown();
}
+JDECL(jstring,1sql)(JENV_CSELF, jobject jpStmt){
+ sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt);
+ jstring rv = 0;
+ if( pStmt ){
+ const char * zSql = 0;
+ S3JniEnvCache * const jc = S3JniGlobal_env_cache(env);
+ zSql = sqlite3_sql(pStmt);
+ rv = s3jni_utf8_to_jstring(jc, zSql, -1);
+ OOM_CHECK(rv);
+ }
+ return rv;
+}
+
JDECL(jint,1step)(JENV_CSELF,jobject jStmt){
int rc = SQLITE_MISUSE;
sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jStmt);
printf("\tJNIEnv cache %u misses, %u hits\n",
S3JniGlobal.metrics.envCacheMisses,
S3JniGlobal.metrics.envCacheHits);
- puts("UDF calls:");
+ puts("Java-side UDF calls:");
#define UDF(T) printf("\t%-8s = %u\n", "x" #T, S3JniGlobal.metrics.udf.n##T)
UDF(Func); UDF(Step); UDF(Final); UDF(Value); UDF(Inverse);
#undef UDF
-C Mark\s_all_\sJNI\sbinding\sfuncs\sas\ssynchronized\sso\sthat\sJava\scan\slock\sthem\sand\sprotect\sour\sglobal-state\saccess.\sThe\salternative\sis\swriting\sa\smountain\sof\sC-side\scode\sto\sdo\sthe\ssame\sthing.
-D 2023-08-10T21:50:52.042
+C Bind\ssqlite3_sql()\sand\ssqlite3_expanded_sql()\sto\sJNI.\sStart\smarking\sC-side\sfunctions\swhich\swould\sneed\sexplicit\smutex\ssupport\sif\swe\sremove\s'synchronized'\sfrom\stheir\sJava\sentry\spoints\s(but\sthere\sare\smany\smore\sleft\sto\smark).
+D 2023-08-11T18:04:53.620
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/jni/GNUmakefile d228f18de85e7f2f80e05edce3cc4f32da3c45a308e4e921807ca88279010871
F ext/jni/README.md 7a614a2fa6c561205f7a53fd8626cf93a7b5711ff454fc1814517f796df398eb
F ext/jni/jar-dist.make f90a553203a57934bf275bed86479485135a52f48ac5c1cfe6499ae07b0b35a4
-F ext/jni/src/c/sqlite3-jni.c 709205926615161bcd9f657a7ee29f7348da1811ed2d64fc45d7ae62aa3ab8c9
-F ext/jni/src/c/sqlite3-jni.h 471da2a2ded8425a38a01111ea04a800e9035ae87450045fc7a945be78210d7b
+F ext/jni/src/c/sqlite3-jni.c 478c168346b6ee0b600433c8d1b1c59b357fdd7418a1dd18498ce9e73742d685
+F ext/jni/src/c/sqlite3-jni.h 8f9e03016fea584627219eb4a14c6b1a6ba9fffbd7bc0df9e14220a6af8cfe18
F ext/jni/src/org/sqlite/jni/Authorizer.java 1308988f7f40579ea0e4deeaec3c6be971630566bd021c31367fe3f5140db892
F ext/jni/src/org/sqlite/jni/AutoExtension.java 18e83f6f463e306df60b2dceb65247d32af1f78af4bbbae9155411a8c6cdb093
F ext/jni/src/org/sqlite/jni/BusyHandler.java 1b1d3e5c86cd796a0580c81b6af6550ad943baa25e47ada0dcca3aff3ebe978c
F ext/jni/src/org/sqlite/jni/ResultCode.java 7cdf993f2037ab7bd244c9a34dbaef2ace3beb5da5d7e7fda5c6f67634ceb647
F ext/jni/src/org/sqlite/jni/RollbackHook.java b04c8abcc6ade44a8a57129e33765793f69df0ba909e49ba18d73f4268d92564
F ext/jni/src/org/sqlite/jni/SQLFunction.java 09ce81c1c637e31c3a830d4c859cce95d65f5e02ff45f8bd1985b3479381bc46
-F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 836822ecf2f346d2218609fa68ddb3b595361663890493271635726e776cb57b
-F ext/jni/src/org/sqlite/jni/Tester1.java c45ab1895774851dec30824157d4c390f49e17729588c02cd88172854ee97e74
+F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 23dec2c267ef1882bb0bfc12a2c771e13e091885942344abbde90861f7b795fa
+F ext/jni/src/org/sqlite/jni/Tester1.java 7716949ae434308e698da505549e751478a03f40f2775d6b5486b754ded37a79
F ext/jni/src/org/sqlite/jni/TesterFts5.java cf2d687baafffdeba219b77cf611fd47a0556248820ea794ae3e8259bfbdc5ee
F ext/jni/src/org/sqlite/jni/Tracer.java a5cece9f947b0af27669b8baec300b6dd7ff859c3e6a6e4a1bd8b50f9714775d
F ext/jni/src/org/sqlite/jni/UpdateHook.java e58645a1727f8a9bbe72dc072ec5b40d9f9362cb0aa24acfe93f49ff56a9016d
F ext/jni/src/org/sqlite/jni/sqlite3_context.java d26573fc7b309228cb49786e9078597d96232257defa955a3425d10897bca810
F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc
F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a
-F ext/jni/src/org/sqlite/jni/tester/SQLTester.java ecb989115a421088e2772d6125cd872cd345d0c422c50aa1ce1221c61fcd1f88
+F ext/jni/src/org/sqlite/jni/tester/SQLTester.java 5aa16634120dea614ebe3c127c69da87ba207cb658b09f600a8e8f9d2dc91e15
F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e
F ext/jni/src/tests/000-000-sanity.test cfe6dc1b950751d6096e3f5695becaadcdaa048bfe9567209d6eb676e693366d
F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 746894c3c043c47f8b4c231de8921df81c5d0634260d299359bea73132dc7867
-R e1ccd8a6a6627664a18e71218906f2ad
+P afe190a940441de9bef8835c2dc6d278f861a772c3b7c7a2d399b2eabd4872e3
+R 2143ed5f6ccc929f2efe052657302ea3
U stephan
-Z 898733fffb725ecf1391b4a8e291674e
+Z 2327e5c9841d1baf8b0f3e308e996b38
# Remove this line to create a well-formed Fossil manifest.