Browse Source

Acquire global mutex to obtain mutex for java obj

update stress test jni92, add option useSharedEngines
JNI-92
heck 2 years ago
parent
commit
94f2107df1
6 changed files with 226 additions and 82 deletions
  1. +105
    -30
      src/basic_api.cc
  2. +70
    -35
      src/foundation_pEp_jniadapter_AbstractEngine.cc
  3. +7
    -2
      src/gen_cpp_Engine.ysl2
  4. +2
    -1
      src/jniutils.cc
  5. +25
    -11
      test/java/foundation/pEp/jniadapter/test/jni92/TestMain.java
  6. +17
    -3
      test/java/foundation/pEp/jniadapter/test/utils/TestUtils.java

+ 105
- 30
src/basic_api.cc View File

@ -19,8 +19,13 @@ JNIEXPORT jbyteArray JNICALL Java_foundation_pEp_jniadapter_Engine_trustwords(
jobject ident
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
pEp_identity *_ident = to_identity(env, ident);
char *words;
@ -59,8 +64,13 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine_myself(
jobject ident
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
pEp_identity *_ident = to_identity(env, ident);
@ -80,8 +90,13 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine_updateIdentity(
jobject ident
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
pEp_identity *_ident = to_identity(env, ident);
@ -97,8 +112,13 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine_setOwnKey(
jbyteArray fpr
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
pEp_identity *_ident = to_identity(env, ident);
char *_fpr = to_string(env, fpr);
@ -120,8 +140,13 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_keyMistrusted(
jobject ident
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
pEp_identity *_ident = to_identity(env, ident);
@ -146,8 +171,13 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_keyResetTrust(
jobject ident
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
pEp_identity *_ident = to_identity(env, ident);
@ -172,8 +202,13 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_trustPersonalKey(
jobject ident
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
pEp_identity *_ident = to_identity(env, ident);
@ -198,8 +233,13 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_trustOwnKey(
jobject ident
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
pEp_identity *_ident = to_identity(env, ident);
@ -217,8 +257,13 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_importKey(
jbyteArray key
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
size_t _size = (size_t) env->GetArrayLength(key);
char *_key = (char *) env->GetByteArrayElements(key, NULL);
@ -243,8 +288,13 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_config_1passive_1mo
jboolean enable
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
::config_passive_mode(session(), (bool)enable);
}
@ -256,8 +306,13 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_config_1unencrypted
jboolean enable
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
::config_unencrypted_subject(session(), (bool)enable);
}
@ -268,8 +323,13 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_blacklist_1add(
jbyteArray fpr
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
char *_fpr = to_string(env, fpr);
@ -292,8 +352,13 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_blacklist_1delete(
jbyteArray fpr
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
char *_fpr = to_string(env, fpr);
@ -316,8 +381,13 @@ JNIEXPORT jboolean JNICALL Java_foundation_pEp_jniadapter_Engine_blacklist_1is_1
jbyteArray fpr
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
char *_fpr = to_string(env, fpr);
bool _listed = 0;
@ -343,8 +413,13 @@ JNIEXPORT jbyteArray JNICALL Java_foundation_pEp_jniadapter_Engine_getCrashdumpL
jint maxlines
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
int _maxlines = (int) maxlines;
char *_logdata;


+ 70
- 35
src/foundation_pEp_jniadapter_AbstractEngine.cc View File

@ -172,54 +172,64 @@ using namespace pEp;
JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_init(
JNIEnv *env,
jobject me
jobject obj
)
{
pEpLog("called");
std::lock_guard<std::mutex> l(global_mutex); // global mutex for write access to <unordered_map>
pEpLog("called");
if (first) {
pEpLog("first Engine instance");
first = false;
env->GetJavaVM(&jvm);
jni_init();
objj = env->NewGlobalRef(me);
objj = env->NewGlobalRef(obj);
Adapter::_messageToSend = messageToSend;
}
create_engine_java_object_mutex(env, me); // Create a mutex per java object
create_engine_java_object_mutex(env, obj); // Create a mutex per java object
Adapter::session();
}
JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_release(
JNIEnv *env,
jobject me
jobject obj
)
{
pEpLog("called");
std::lock_guard<std::mutex> l(global_mutex); // global mutex for write access to <unordered_map>
release_engine_java_object_mutex(env, me);
pEpLog("called");
release_engine_java_object_mutex(env, obj);
Adapter::session(pEp::Adapter::release);
}
JNIEXPORT jstring JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_getVersion(
JNIEnv *env,
jobject me
jobject obj
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, me));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
return env->NewStringUTF(::get_engine_version());
}
JNIEXPORT jstring JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_getProtocolVersion(
JNIEnv *env,
jobject me
jobject obj
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, me));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
return env->NewStringUTF(::get_protocol_version());
}
@ -263,11 +273,16 @@ static void *keyserver_thread_routine(void *arg)
JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_startKeyserverLookup(
JNIEnv *env,
jobject me
jobject obj
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, me));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
pthread_t *thread = nullptr;
locked_queue< pEp_identity * > *queue = nullptr;
@ -284,16 +299,16 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_startKeyser
return;
}
thread = (pthread_t *) env->GetLongField(me, thread_handle);
thread = (pthread_t *) env->GetLongField(obj, thread_handle);
if (thread)
return;
thread = (pthread_t *) calloc(1, sizeof(pthread_t));
assert(thread);
env->SetLongField(me, thread_handle, (jlong) thread);
env->SetLongField(obj, thread_handle, (jlong) thread);
queue = new locked_queue< pEp_identity * >();
env->SetLongField(me, queue_handle, (jlong) queue);
env->SetLongField(obj, queue_handle, (jlong) queue);
register_examine_function(Adapter::session(), examine_identity, (void *) queue);
@ -302,11 +317,16 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_startKeyser
JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_stopKeyserverLookup(
JNIEnv *env,
jobject me
jobject obj
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, me));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
pthread_t *thread = nullptr;
locked_queue< pEp_identity * > *queue = nullptr;
@ -323,14 +343,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_stopKeyserv
return;
}
thread = (pthread_t *) env->GetLongField(me, thread_handle);
thread = (pthread_t *) env->GetLongField(obj, thread_handle);
if (!thread)
return;
queue = (locked_queue< pEp_identity * > *) env->GetLongField(me, queue_handle);
queue = (locked_queue< pEp_identity * > *) env->GetLongField(obj, queue_handle);
env->SetLongField(me, queue_handle, (jlong) 0);
env->SetLongField(me, thread_handle, (jlong) 0);
env->SetLongField(obj, queue_handle, (jlong) 0);
env->SetLongField(obj, thread_handle, (jlong) 0);
register_examine_function(Adapter::session(), nullptr, nullptr);
@ -341,11 +361,16 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_stopKeyserv
JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_startSync(
JNIEnv *env,
jobject me
jobject obj
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, me));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
pEpLog("######## starting sync");
try {
@ -359,22 +384,32 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_startSync(
JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_stopSync(
JNIEnv *env,
jobject me
jobject obj
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, me));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
Adapter::shutdown();
}
JNIEXPORT jboolean JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_isSyncRunning(
JNIEnv *env,
jobject me
jobject obj
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, me));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
return (jboolean) Adapter::is_sync_running();
}


+ 7
- 2
src/gen_cpp_Engine.ysl2 View File

@ -47,8 +47,13 @@ tstylesheet {
jobject obj`apply "parm[in|inout]", mode=sig`
)
{
pEpLog("called with lock_guard");
std::lock_guard<std::mutex> l(*get_engine_java_object_mutex(env, obj));
std::mutex *mutex_local = nullptr;
{
std::lock_guard<std::mutex> l(global_mutex);
pEpLog("called with lock_guard");
mutex_local = get_engine_java_object_mutex(env, obj);
}
std::lock_guard<std::mutex> l(*mutex_local);
||


+ 2
- 1
src/jniutils.cc View File

@ -21,8 +21,9 @@ namespace pEp {
{
long engine_obj_id = (long)callLongMethod(env, obj, "getId");
assert(engine_obj_id);
pEpLog("for java object id: " << engine_obj_id);
std::mutex *engine_obj_mutex = engine_objid_mutex.at(engine_obj_id);
pEpLog(engine_obj_mutex << " with native_handle: " << engine_obj_mutex->native_handle() << " for java object id: " << engine_obj_id);
pEpLog("found mutex: " << engine_obj_mutex << " with native_handle: " << engine_obj_mutex->native_handle());
assert(engine_obj_mutex);
return engine_obj_mutex;
}


+ 25
- 11
test/java/foundation/pEp/jniadapter/test/jni92/TestMain.java View File

@ -16,19 +16,23 @@ https://pep.foundation/jira/browse/JNI-81
class TestThread extends Thread {
int nrEngines = 1;
TestThread(String threadName, int nrEngines) {
boolean useSharedEngines = false;
TestThread(String threadName, int nrEngines, boolean useSharedEngines) {
Thread.currentThread().setName(threadName);
this.nrEngines = nrEngines;
this.useSharedEngines = useSharedEngines;
}
public void run() {
TestUtils.logH1( "Thread Starting");
TestMain.TestMainRun(nrEngines);
TestMain.TestMainRun(nrEngines, useSharedEngines);
}
}
class TestMain {
static Vector<Engine> sharedEngines;
public static Engine createNewEngine() throws pEpException {
Engine e;
TestUtils.logH2("Creating new Engine");
@ -52,8 +56,7 @@ class TestMain {
});
}
public static void TestMainRun(int nrEngines) {
Vector<Engine> engineVector = TestMain.createEngines(nrEngines);
public static void TestMainRun(int nrEngines, boolean useSharedEngines) {
Consumer<Engine> c = (e) -> {
Vector<Identity> v = e.own_identities_retrieve();
@ -64,27 +67,38 @@ class TestMain {
e.getVersion();
e.OpenPGP_list_keyinfo("");
};
TestMain.engineConsumer(engineVector, c);
if(useSharedEngines) {
TestMain.engineConsumer(sharedEngines, c);
} else {
Vector<Engine> threadLocalEngines = TestMain.createEngines(nrEngines);
TestMain.engineConsumer(threadLocalEngines, c);
}
}
public static void main(String[] args) {
TestUtils.logH1("JNI-92 Starting");
int nrTestruns = 100;
TestUtils.setLoggingEnabled(false);
int nrTestruns = 1000;
boolean multiThreaded = true;
int nrThreads = 200;
int nrEnginesPerThread = 100;
boolean useSharedEngines = true;
int nrThreads = 100;
int nrEnginesPerThread = 1;
if(useSharedEngines) {
sharedEngines = TestMain.createEngines(nrEnginesPerThread);
}
for (int run = 0; run < nrTestruns; run++ ) {
TestUtils.logH1("Testrun Nr: " + run);
if (!multiThreaded) {
// Single Threaded
TestMainRun(nrEnginesPerThread);
TestMainRun(nrEnginesPerThread, useSharedEngines);
} else {
// Mutli Threaded
Vector<TestThread> tts = new Vector<TestThread>();
for (int i = 0; i < nrThreads; i++) {
tts.add(new TestThread("TestThread-" + i, nrEnginesPerThread));
tts.add(new TestThread("TestThread-" + i, nrEnginesPerThread, useSharedEngines));
}
tts.forEach(t -> {


+ 17
- 3
test/java/foundation/pEp/jniadapter/test/utils/TestUtils.java View File

@ -22,10 +22,24 @@ public class TestUtils {
return ret;
}
// ------------------------ Logging ------------------------
private static boolean logEnabled = true;
public static void setLoggingEnabled(boolean enabled) {
logEnabled = enabled;
}
public static boolean isLoggingEnabled() {
return logEnabled;
}
public static void log(String msg) {
String threadNameFmt = String.format("%-10s", Thread.currentThread().getName());
String msgOut = threadNameFmt + ": " + msg;
System.out.println(msgOut);
if(logEnabled) {
String threadNameFmt = String.format("%-10s", Thread.currentThread().getName());
String msgOut = threadNameFmt + ": " + msg;
System.out.println(msgOut);
}
}
public static void logH1(String msg) {


Loading…
Cancel
Save