diff --git a/src/basic_api.cc b/src/basic_api.cc index 86be576..d16553b 100644 --- a/src/basic_api.cc +++ b/src/basic_api.cc @@ -1,6 +1,5 @@ #include #include -#include #include #ifndef ANDROID @@ -20,7 +19,14 @@ JNIEXPORT jbyteArray JNICALL Java_foundation_pEp_jniadapter_Engine_trustwords( jobject ident ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + pEp_identity *_ident = to_identity(env, ident); char *words; size_t wsize; @@ -58,7 +64,14 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine_myself( jobject ident ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + pEp_identity *_ident = to_identity(env, ident); PEP_STATUS status = ::myself(session(), _ident); @@ -77,7 +90,14 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine_updateIdentity( jobject ident ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + pEp_identity *_ident = to_identity(env, ident); ::update_identity(session(), _ident); @@ -92,7 +112,14 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine_setOwnKey( jbyteArray fpr ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + pEp_identity *_ident = to_identity(env, ident); char *_fpr = to_string(env, fpr); @@ -113,7 +140,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_keyMistrusted( jobject ident ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + pEp_identity *_ident = to_identity(env, ident); if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -137,7 +171,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_keyResetTrust( jobject ident ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + pEp_identity *_ident = to_identity(env, ident); if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -161,7 +202,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_trustPersonalKey( jobject ident ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + pEp_identity *_ident = to_identity(env, ident); if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -185,7 +233,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_trustOwnKey( jobject ident ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + pEp_identity *_ident = to_identity(env, ident); if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -202,7 +257,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_importKey( jbyteArray key ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + size_t _size = (size_t) env->GetArrayLength(key); char *_key = (char *) env->GetByteArrayElements(key, NULL); @@ -226,7 +288,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_config_1passive_1mo jboolean enable ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + ::config_passive_mode(session(), (bool)enable); } @@ -237,7 +306,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_config_1unencrypted jboolean enable ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + ::config_unencrypted_subject(session(), (bool)enable); } @@ -247,7 +323,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_blacklist_1add( jbyteArray fpr ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + char *_fpr = to_string(env, fpr); if(_fpr == NULL){ @@ -269,7 +352,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine_blacklist_1delete( jbyteArray fpr ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + char *_fpr = to_string(env, fpr); if(_fpr == NULL){ @@ -291,7 +381,14 @@ JNIEXPORT jboolean JNICALL Java_foundation_pEp_jniadapter_Engine_blacklist_1is_1 jbyteArray fpr ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + char *_fpr = to_string(env, fpr); bool _listed = 0; @@ -316,7 +413,14 @@ JNIEXPORT jbyteArray JNICALL Java_foundation_pEp_jniadapter_Engine_getCrashdumpL jint maxlines ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + int _maxlines = (int) maxlines; char *_logdata; diff --git a/src/foundation/pEp/jniadapter/AbstractEngine.java b/src/foundation/pEp/jniadapter/AbstractEngine.java index 0550aaa..f882fce 100644 --- a/src/foundation/pEp/jniadapter/AbstractEngine.java +++ b/src/foundation/pEp/jniadapter/AbstractEngine.java @@ -8,7 +8,7 @@ import foundation.pEp.jniadapter.Sync.DefaultCallback; import java.io.UnsupportedEncodingException; import java.text.Normalizer; -abstract class AbstractEngine implements AutoCloseable { +abstract class AbstractEngine extends UniquelyIdentifiable implements AutoCloseable { static { System.loadLibrary("pEpJNI"); } diff --git a/src/foundation/pEp/jniadapter/UniquelyIdentifiable.java b/src/foundation/pEp/jniadapter/UniquelyIdentifiable.java new file mode 100644 index 0000000..d599e9c --- /dev/null +++ b/src/foundation/pEp/jniadapter/UniquelyIdentifiable.java @@ -0,0 +1,11 @@ +package foundation.pEp.jniadapter; +import java.util.concurrent.atomic.AtomicLong; + +abstract class UniquelyIdentifiable { + static final AtomicLong NEXT_ID = new AtomicLong(1); + final long id = NEXT_ID.getAndIncrement(); + + public long getId() { + return id; + } +} diff --git a/src/foundation_pEp_jniadapter_AbstractEngine.cc b/src/foundation_pEp_jniadapter_AbstractEngine.cc index 6f2c8ad..beb06ef 100644 --- a/src/foundation_pEp_jniadapter_AbstractEngine.cc +++ b/src/foundation_pEp_jniadapter_AbstractEngine.cc @@ -1,8 +1,5 @@ #include "foundation_pEp_jniadapter_AbstractEngine.h" -#include #include -#include -#include #include #include #include @@ -28,7 +25,7 @@ jmethodID notifyHandShakeMethodID = nullptr; jmethodID needsFastPollMethodID = nullptr; jmethodID method_values = nullptr; -jobject obj = nullptr; +jobject objj = nullptr; jclass messageClass = nullptr; jclass identityClass = nullptr;; @@ -96,15 +93,15 @@ void jni_init() { PEP_STATUS messageToSend(message *msg) { std::lock_guard l(mutex_obj); - pEpLog("############### messageToSend() called"); + pEpLog("############### messageToSend() called"); jobject msg_ = nullptr; - assert(messageClass && messageConstructorMethodID && obj && messageToSendMethodID); + assert(messageClass && messageConstructorMethodID && objj && messageToSendMethodID); msg_ = o.env()->NewObject(messageClass, messageConstructorMethodID, (jlong) msg); - PEP_STATUS status = (PEP_STATUS) o.env()->CallIntMethod(obj, messageToSendMethodID, msg_); + PEP_STATUS status = (PEP_STATUS) o.env()->CallIntMethod(objj, messageToSendMethodID, msg_); if (o.env()->ExceptionCheck()) { o.env()->ExceptionDescribe(); status = PEP_UNKNOWN_ERROR; @@ -118,8 +115,8 @@ PEP_STATUS messageToSend(message *msg) PEP_STATUS notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal) { std::lock_guard l(mutex_obj); - pEpLog("############### notifyHandshake() called"); + pEpLog("############### notifyHandshake() called"); jobject me_ = nullptr; jobject partner_ = nullptr; @@ -152,9 +149,9 @@ PEP_STATUS notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handsha } } - assert(obj && notifyHandShakeMethodID); + assert(objj && notifyHandShakeMethodID); - PEP_STATUS status = (PEP_STATUS) o.env()->CallIntMethod(obj, notifyHandShakeMethodID, me_, partner_, signal_); + PEP_STATUS status = (PEP_STATUS) o.env()->CallIntMethod(objj, notifyHandShakeMethodID, me_, partner_, signal_); if (o.env()->ExceptionCheck()) { o.env()->ExceptionClear(); return PEP_UNKNOWN_ERROR; @@ -169,45 +166,65 @@ using namespace pEp; JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_init( JNIEnv *env, - jobject me + jobject obj ) { + std::lock_guard l(global_mutex); // global mutex for write access to pEpLog("called"); + if (first) { pEpLog("first Engine instance"); first = false; env->GetJavaVM(&jvm); jni_init(); - obj = env->NewGlobalRef(me); + objj = env->NewGlobalRef(obj); Adapter::_messageToSend = messageToSend; } + + 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 ) { + std::lock_guard l(global_mutex); // global mutex for write access to 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 + jobject obj ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + return env->NewStringUTF(::get_engine_version()); } JNIEXPORT jstring JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_getProtocolVersion( JNIEnv *env, - jobject + jobject obj ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + return env->NewStringUTF(::get_protocol_version()); } @@ -248,10 +265,17 @@ static void *keyserver_thread_routine(void *arg) JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_startKeyserverLookup( JNIEnv *env, - jobject me + jobject obj ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + pthread_t *thread = nullptr; locked_queue< pEp_identity * > *queue = nullptr; @@ -267,16 +291,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); @@ -285,10 +309,17 @@ 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"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + pthread_t *thread = nullptr; locked_queue< pEp_identity * > *queue = nullptr; @@ -304,14 +335,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); @@ -322,9 +353,17 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_stopKeyserv JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_startSync( JNIEnv *env, - jobject me + jobject obj ) { + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + pEpLog("######## starting sync"); try { Adapter::startup(messageToSend, notifyHandshake, &o, &JNISync::onSyncStartup, &JNISync::onSyncShutdown); @@ -337,19 +376,33 @@ 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"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + Adapter::shutdown(); } JNIEXPORT jboolean JNICALL Java_foundation_pEp_jniadapter_AbstractEngine_isSyncRunning( JNIEnv *env, - jobject me + jobject obj ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + return (jboolean) Adapter::is_sync_running(); } diff --git a/src/foundation_pEp_jniadapter__Blob.cc b/src/foundation_pEp_jniadapter__Blob.cc index 730a957..e677997 100644 --- a/src/foundation_pEp_jniadapter__Blob.cc +++ b/src/foundation_pEp_jniadapter__Blob.cc @@ -1,11 +1,6 @@ -#include #include #include #include -#include -#include -#include - #include "jniutils.hh" #include "throw_pEp_exception.hh" #include "foundation_pEp_jniadapter__Blob.h" diff --git a/src/gen_cpp_Engine.ysl2 b/src/gen_cpp_Engine.ysl2 index 76bb6d2..eef8111 100644 --- a/src/gen_cpp_Engine.ysl2 +++ b/src/gen_cpp_Engine.ysl2 @@ -9,8 +9,6 @@ tstylesheet { template "interface" document("foundation_pEp_jniadapter_{@name}.cc", "text") || - #include - #include #include #include #include @@ -50,7 +48,14 @@ tstylesheet { jobject obj`apply "parm[in|inout]", mode=sig` ) { - pEpLog("called"); + std::mutex *mutex_local = nullptr; + { + std::lock_guard l(global_mutex); + pEpLog("called with lock_guard"); + mutex_local = get_engine_java_object_mutex(env, obj); + } + std::lock_guard l(*mutex_local); + || apply "parm[in|inout]", mode=in; diff --git a/src/gen_cpp_Message.ysl2 b/src/gen_cpp_Message.ysl2 index 5296207..ecefa1e 100644 --- a/src/gen_cpp_Message.ysl2 +++ b/src/gen_cpp_Message.ysl2 @@ -12,15 +12,8 @@ tstylesheet { document("foundation_pEp_jniadapter_{$jname}.cc", "text") { || - #include - #include - #include - #include - #include - #include #include #include - #include "jniutils.hh" #include "throw_pEp_exception.hh" #include "foundation_pEp_jniadapter_«$jname».h" diff --git a/src/identity_api.cc b/src/identity_api.cc index e2450f3..eb364d0 100644 --- a/src/identity_api.cc +++ b/src/identity_api.cc @@ -1,7 +1,4 @@ -#include #include -#include "jniutils.hh" - extern "C" { diff --git a/src/jniutils.cc b/src/jniutils.cc index f2d67ed..b3eb89a 100644 --- a/src/jniutils.cc +++ b/src/jniutils.cc @@ -1,11 +1,5 @@ #include "jniutils.hh" -#include -#include -#include -#include -#include -#include - +#include #ifndef __LP64__ #include #define time_t time64_t @@ -17,6 +11,54 @@ namespace pEp { namespace JNIAdapter { + std::mutex global_mutex; + std::unordered_map engine_objid_mutex; + + std::mutex* get_engine_java_object_mutex( + JNIEnv *env, + jobject obj + ) + { + 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("found mutex: " << engine_obj_mutex << " with native_handle: " << engine_obj_mutex->native_handle()); + assert(engine_obj_mutex); + return engine_obj_mutex; + } + + void create_engine_java_object_mutex( + JNIEnv *env, + jobject obj + ) + { + long engine_obj_id = (long)callLongMethod(env, obj, "getId"); + assert(engine_obj_id); + std::mutex *engine_obj_mutex = new std::mutex(); + pEpLog(engine_obj_mutex << " with native_handle: " << engine_obj_mutex->native_handle() << " for java object id: " << engine_obj_id); + assert(engine_obj_mutex); + if(engine_objid_mutex.count(engine_obj_id) > 0) { + pEpLog("Fatal: mutex already existing for object id: " << engine_obj_id); + assert(0); + } + engine_objid_mutex.insert(std::make_pair(engine_obj_id, engine_obj_mutex )); + } + + void release_engine_java_object_mutex( + JNIEnv *env, + jobject obj + ) + { + long engine_obj_id = (long)callLongMethod(env, obj, "getId"); + assert(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); + assert(engine_obj_mutex); + engine_objid_mutex.erase(engine_obj_id); + delete engine_obj_mutex; + } + jclass findClass(JNIEnv *env, const char *classname) { jclass clazz = env->FindClass(classname); diff --git a/src/jniutils.hh b/src/jniutils.hh index 88597de..a9cf9a0 100644 --- a/src/jniutils.hh +++ b/src/jniutils.hh @@ -1,8 +1,6 @@ #pragma once - -#include -#include -#include +#include +#include #include #include #include @@ -15,11 +13,42 @@ #define LOG_TAG "pEpJNIAdapter" #define LOGD(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #else -#define LOGD(...) +#define LOGD(...) do{}while(0) #endif namespace pEp { namespace JNIAdapter { + + // Global mutex needs to be locked in all constructors which insert their own mutex object + // into the unordered_map (which is thread safe for read, but not for write) + extern std::mutex global_mutex; + + // Stores mutex per java object + extern std::unordered_map engine_objid_mutex; + + // needs to be called after create_engine_java_object_mutex() + // and before release_engine_java_object_mutex() + // Thread safe + std::mutex* get_engine_java_object_mutex( + JNIEnv *env, + jobject me + ); + + // Needs to be called exactly once per obj, in the constructor of the obj + // You need to lock a global mutex before calling this function (write to unordered_map) + void create_engine_java_object_mutex( + JNIEnv *env, + jobject me + ); + + // Needs to be called exactly once per obj, in the destructor of this obj + // You need to lock a global mutex before calling this function (write to unordered_map) + void release_engine_java_object_mutex( + JNIEnv *env, + jobject me + ); + + jclass findClass(JNIEnv *env, const char *classname); jfieldID getFieldID( diff --git a/test/java/foundation/pEp/jniadapter/test/jni88/TestMain.java b/test/java/foundation/pEp/jniadapter/test/jni88/TestMain.java index 4b27f39..bc53fb5 100644 --- a/test/java/foundation/pEp/jniadapter/test/jni88/TestMain.java +++ b/test/java/foundation/pEp/jniadapter/test/jni88/TestMain.java @@ -89,8 +89,8 @@ class TestThread extends Thread { class TestMain { public static void main(String[] args) { // Test parameters - boolean useSharedEngine = true; - int numThreads = 2; + boolean useSharedEngine = false; + int numThreads = 200; int numIters = 1000000000; Engine sharedEngine = null; diff --git a/test/java/foundation/pEp/jniadapter/test/jni92/TestMain.java b/test/java/foundation/pEp/jniadapter/test/jni92/TestMain.java index aaff4e9..a646590 100644 --- a/test/java/foundation/pEp/jniadapter/test/jni92/TestMain.java +++ b/test/java/foundation/pEp/jniadapter/test/jni92/TestMain.java @@ -4,6 +4,7 @@ import foundation.pEp.jniadapter.*; import java.lang.Thread; import java.util.Vector; +import java.util.function.Consumer; /* @@ -14,24 +15,29 @@ https://pep.foundation/jira/browse/JNI-81 */ class TestThread extends Thread { - TestThread(String threadName) { + int nrEngines = 1; + 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(2); + TestMain.TestMainRun(nrEngines, useSharedEngines); } } class TestMain { + static Vector sharedEngines; public static Engine createNewEngine() throws pEpException { Engine e; TestUtils.logH2("Creating new Engine"); e = new Engine(); - TestUtils.log("Engine created\n"); + TestUtils.log("Engine created with java object ID: " + e.getId()); return e; } @@ -43,51 +49,73 @@ class TestMain { return ev; } - public static void own_identities_retrieve_on_EngineVector(Vector ev) { + public static void engineConsumer(Vector ev, Consumer ec) { ev.forEach(e -> { - TestUtils.logH2("own_identities_retrieve()"); - e.own_identities_retrieve(); - TestUtils.log("\n"); + TestUtils.logH2("engineConsumer: on engine java object ID: " + e.getId()); + ec.accept(e); }); } + public static void TestMainRun(int nrEngines, boolean useSharedEngines) { + Consumer c = (e) -> { + Vector v = e.own_identities_retrieve(); + TestUtils.log("own idents: " + v.size()); + v.forEach( i -> { + TestUtils.log(TestUtils.identityToString(i)); + }); + e.getVersion(); + e.OpenPGP_list_keyinfo(""); + }; - public static void TestMainRun(int nrEngines) { - Vector engineVector = TestMain.createEngines(nrEngines); -// TestUtils.sleep(200); - TestMain.own_identities_retrieve_on_EngineVector(engineVector); + if(useSharedEngines) { + TestMain.engineConsumer(sharedEngines, c); + } else { + Vector threadLocalEngines = TestMain.createEngines(nrEngines); + TestMain.engineConsumer(threadLocalEngines, c); + } } - public static void main(String[] args) throws Exception { + public static void main(String[] args) { TestUtils.logH1("JNI-92 Starting"); + TestUtils.setLoggingEnabled(false); + int nrTestruns = 1000; boolean multiThreaded = true; - int nrEngines = 3; - - if (!multiThreaded) { - // Single Threaded - TestMainRun(nrEngines); - } else { - // Mutli Threaded - Vector tts = new Vector(); - int nrThreads = nrEngines; - for (int i = 0; i < nrThreads; i++) { - tts.add(new TestThread("TestThread-" + i)); -// TestUtils.sleep(200); - } + boolean useSharedEngines = true; + int nrThreads = 100; + int nrEnginesPerThread = 1; - tts.forEach(t -> { - t.start(); -// TestUtils.sleep(2000); - }); + if(useSharedEngines) { + sharedEngines = TestMain.createEngines(nrEnginesPerThread); + } - tts.forEach(t -> { - try { - t.join(); - } catch (Exception e) { - TestUtils.log("Exception joining thread" + e.toString()); + for (int run = 0; run < nrTestruns; run++ ) { + TestUtils.logH1("Testrun Nr: " + run); + if (!multiThreaded) { + // Single Threaded + TestMainRun(nrEnginesPerThread, useSharedEngines); + } else { + // Mutli Threaded + Vector tts = new Vector(); + for (int i = 0; i < nrThreads; i++) { + tts.add(new TestThread("TestThread-" + i, nrEnginesPerThread, useSharedEngines)); } - }); + + tts.forEach(t -> { + t.start(); + }); + + tts.forEach(t -> { + try { + t.join(); + } catch (Exception e) { + TestUtils.log("Exception joining thread" + e.toString()); + } + }); + } + TestUtils.logH1("Testrun DONE" ); + System.gc(); +// TestUtils.sleep(2000); } } } diff --git a/test/java/foundation/pEp/jniadapter/test/utils/TestUtils.java b/test/java/foundation/pEp/jniadapter/test/utils/TestUtils.java index 83d7d75..3833b18 100644 --- a/test/java/foundation/pEp/jniadapter/test/utils/TestUtils.java +++ b/test/java/foundation/pEp/jniadapter/test/utils/TestUtils.java @@ -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) {