Browse Source

class variables must not be global

JNI-88
Volker Birk 6 years ago
parent
commit
e926d1c669
  1. 4
      src/Makefile
  2. 7
      src/Makefile.conf
  3. 147
      src/org_pEp_jniadapter_AbstractEngine.cc
  4. 3
      test/Makefile

4
src/Makefile

@ -7,13 +7,13 @@ include Makefile.conf
ifneq ($(wildcard local.conf),) ifneq ($(wildcard local.conf),)
$(info ================================================) $(info ================================================)
$(info Overrides in \`local.conf\` are used.) $(info Overrides in `local.conf` are used.)
$(info ================================================) $(info ================================================)
endif endif
ifdef BUILD_CONFIG ifdef BUILD_CONFIG
$(info ================================================) $(info ================================================)
$(info Overrides in \`$(BUILD_CONFIG)\` are used.) $(info Overrides in `$(BUILD_CONFIG)` are used.)
$(info ================================================) $(info ================================================)
endif endif

7
src/Makefile.conf

@ -16,7 +16,8 @@ BUILD_FOR:=$(shell uname)
######### C and C++ ######### ######### C and C++ #########
LDFLAGS=-shared $(ENGINE_LIB) $(AD_LIB) CXXFLAGS+=-g -O0
LDFLAGS+=-shared $(ENGINE_LIB) $(AD_LIB)
LDLIBS=-lstdc++ -lpEpEngine -lpEpAdapter LDLIBS=-lstdc++ -lpEpEngine -lpEpAdapter
@ -29,9 +30,9 @@ else ifeq ($(BUILD_FOR),Darwin)
endif endif
ifeq ($(BUILD_FOR),Linux) ifeq ($(BUILD_FOR),Linux)
CXXFLAGS=-fdiagnostics-color=always -fpermissive -fPIC -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux $(AD_INC) $(ENGINE_INC) -DDISABLE_SYNC CXXFLAGS+=-fdiagnostics-color=always -fpermissive -fPIC -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux $(AD_INC) $(ENGINE_INC)
else ifeq ($(BUILD_FOR),Darwin) else ifeq ($(BUILD_FOR),Darwin)
CXXFLAGS=-fcolor-diagnostics -fpermissive -fPIC -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/darwin $(AD_INC) $(ENGINE_INC) -DDISABLE_SYNC CXXFLAGS+=-fcolor-diagnostics -fpermissive -fPIC -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/darwin $(AD_INC) $(ENGINE_INC)
endif endif

147
src/org_pEp_jniadapter_AbstractEngine.cc

@ -1,10 +1,15 @@
#include "org_pEp_jniadapter_AbstractEngine.h" #include "org_pEp_jniadapter_AbstractEngine.h"
#ifndef ANDROID
#ifndef NDEBUG #ifndef NDEBUG
#include <fstream> #include <iostream>
std::ofstream debug_log("debug.log"); auto& debug_log = std::cerr;
#endif #else
// the compiler should optimize this away
static struct _debug_log {
_debug_log& operator<<(const char*) { return *this; }
_debug_log& operator<<(int) { return *this; }
_debug_log& operator<<(double) { return *this; }
} debug_log;
#endif #endif
#include <stdexcept> #include <stdexcept>
@ -25,22 +30,17 @@ std::ofstream debug_log("debug.log");
#define ATTACH_CURRENT_THREAD(env, args) jvm->AttachCurrentThread((void **) &env, args); #define ATTACH_CURRENT_THREAD(env, args) jvm->AttachCurrentThread((void **) &env, args);
#endif #endif
namespace pEp { namespace pEp {
using namespace pEp::JNIAdapter; using namespace pEp::JNIAdapter;
using namespace pEp::Adapter; using namespace pEp::Adapter;
using namespace utility; using namespace utility;
bool first = true;
JavaVM *jvm= nullptr; JavaVM *jvm= nullptr;
thread_local JNIEnv *thread_env = nullptr;
JNIEnv *first_env = nullptr;
jobject obj = nullptr;
jclass _clazz = nullptr;
jclass messageClass = nullptr; std::mutex mutex_obj;
jclass identityClass = nullptr; jobject obj = nullptr;
jclass signalClass = nullptr;
jclass engineClass = nullptr;
jmethodID messageConstructorMethodID = nullptr; jmethodID messageConstructorMethodID = nullptr;
jmethodID messageToSendMethodID = nullptr; jmethodID messageToSendMethodID = nullptr;
@ -51,78 +51,76 @@ namespace pEp {
public: public:
JNIEnv * env() JNIEnv * env()
{ {
JNIEnv *_env; JNIEnv *thread_env = nullptr;
int status = jvm->GetEnv((void**)&thread_env, JNI_VERSION_1_6);
if (on_sync_thread()) { if (status < 0)
// FIXME: REview if this is the way to go or not status = ATTACH_CURRENT_THREAD(thread_env, nullptr);
int getEnvStat = jvm->GetEnv((void **) &_env, JNI_VERSION_1_6); assert(status >= 0);
if (getEnvStat == JNI_EDETACHED) { return thread_env;
ATTACH_CURRENT_THREAD(_env, nullptr);
}
}
else {
if (!thread_env) {
ATTACH_CURRENT_THREAD(thread_env, nullptr);
}
_env = thread_env;
}
return _env;
} }
void startup_sync() virtual void startup_sync()
{ {
} }
void shutdown_sync() virtual void shutdown_sync()
{ {
env()->DeleteGlobalRef(messageClass);
jvm->DetachCurrentThread(); jvm->DetachCurrentThread();
} }
}; } o;
JNISync *o = nullptr;
PEP_STATUS messageToSend(message *msg) PEP_STATUS messageToSend(message *msg)
{ {
std::lock_guard<std::mutex> l(mutex_obj);
debug_log << "\n############### messageToSend() called\n";
jobject msg_ = nullptr; jobject msg_ = nullptr;
jint result = 0; jint result = 0;
if (!o) jclass messageClass = reinterpret_cast<jclass>(
o = new JNISync(); o.env()->NewGlobalRef(findClass(o.env(), "org/pEp/jniadapter/Message")));
msg_ = o->env()->NewObject(messageClass, messageConstructorMethodID, (jlong) msg); msg_ = o.env()->NewObject(messageClass, messageConstructorMethodID, (jlong) msg);
result = o->env()->CallIntMethod(obj, messageToSendMethodID, msg_); result = o.env()->CallIntMethod(obj, messageToSendMethodID, msg_);
return (PEP_STATUS) result; return (PEP_STATUS) result;
} }
PEP_STATUS notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal) PEP_STATUS notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal)
{ {
std::lock_guard<std::mutex> l(mutex_obj);
debug_log << "\n############### notifyHandshake() called\n";
jobject me_ = nullptr; jobject me_ = nullptr;
jobject partner_ = nullptr; jobject partner_ = nullptr;
me_ = from_identity(o->env(), me, identityClass); jclass identityClass = reinterpret_cast<jclass>(
partner_ = from_identity(o->env(), partner, identityClass); o.env()->NewGlobalRef(findClass(o.env(), "org/pEp/jniadapter/_Identity")));
me_ = from_identity(o.env(), me, identityClass);
partner_ = from_identity(o.env(), partner, identityClass);
jobject signal_ = nullptr; jobject signal_ = nullptr;
{ {
jclass signalClass = reinterpret_cast<jclass>(
o.env()->NewGlobalRef(findClass(o.env(), "org/pEp/jniadapter/SyncHandshakeSignal")));
assert(signalClass); assert(signalClass);
jmethodID method_values = o->env()->GetStaticMethodID(signalClass, "values", jmethodID method_values = o.env()->GetStaticMethodID(signalClass, "values",
"()[Lorg/pEp/jniadapter/SyncHandshakeSignal;"); "()[Lorg/pEp/jniadapter/SyncHandshakeSignal;");
assert(method_values); assert(method_values);
jfieldID field_value = o->env()->GetFieldID(signalClass, "value", "I"); jfieldID field_value = o.env()->GetFieldID(signalClass, "value", "I");
assert(field_value); assert(field_value);
jobjectArray values = (jobjectArray) o->env()->CallStaticObjectMethod(signalClass, jobjectArray values = (jobjectArray) o.env()->CallStaticObjectMethod(signalClass,
method_values); method_values);
assert(values); assert(values);
jsize values_size = o->env()->GetArrayLength(values); jsize values_size = o.env()->GetArrayLength(values);
for (jsize i = 0; i < values_size; i++) { for (jsize i = 0; i < values_size; i++) {
jobject element = o->env()->GetObjectArrayElement(values, i); jobject element = o.env()->GetObjectArrayElement(values, i);
assert(element); assert(element);
jint value = o->env()->GetIntField(element, field_value); jint value = o.env()->GetIntField(element, field_value);
if (value == (jint) signal) { if (value == (jint) signal) {
signal_ = element; signal_ = element;
break; break;
@ -130,7 +128,7 @@ namespace pEp {
} }
} }
jint result = o->env()->CallIntMethod(obj, notifyHandShakeMethodID, me_, partner_, signal_); jint result = o.env()->CallIntMethod(obj, notifyHandShakeMethodID, me_, partner_, signal_);
return (PEP_STATUS) result; return (PEP_STATUS) result;
} }
@ -144,31 +142,18 @@ extern "C" {
jobject me jobject me
) )
{ {
if (!first_env) if (first)
first_env = env; env->GetJavaVM(&jvm);
env->GetJavaVM(&jvm);
thread_env = env;
obj = env->NewGlobalRef(me); obj = env->NewGlobalRef(me);
_clazz = env->GetObjectClass(obj); jclass _clazz = env->GetObjectClass(obj);
if (!o)
o = new JNISync();
if (!messageClass) jclass engineClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Engine")));
messageClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Message")));
if (!identityClass) if (!messageConstructorMethodID) {
identityClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/_Identity"))); jclass messageClass = reinterpret_cast<jclass>(
env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Message")));
if (!signalClass)
signalClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/SyncHandshakeSignal")));
if (!engineClass)
engineClass = reinterpret_cast<jclass>(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Engine")));
if (!messageConstructorMethodID)
messageConstructorMethodID = env->GetMethodID(messageClass, "<init>", "(J)V"); messageConstructorMethodID = env->GetMethodID(messageClass, "<init>", "(J)V");
}
if (!messageToSendMethodID) { if (!messageToSendMethodID) {
messageToSendMethodID = env->GetMethodID( messageToSendMethodID = env->GetMethodID(
@ -196,14 +181,16 @@ extern "C" {
thread_local static PEP_SESSION _session = nullptr; thread_local static PEP_SESSION _session = nullptr;
PEP_STATUS status = PEP_STATUS_OK; PEP_STATUS status = PEP_STATUS_OK;
#ifdef DISABLE_SYNC
#ifdef DISABLE_SYNC _messageToSend = messageToSend;
_messageToSend = messageToSend; session();
session(); #else
if (first) {
#else first = false;
startup<JNISync>(messageToSend, notifyHandshake, o, &JNISync::startup_sync, &JNISync::shutdown_sync); debug_log << "######## starting sync\n";
#endif startup<JNISync>(messageToSend, notifyHandshake, &o, &JNISync::startup_sync, &JNISync::shutdown_sync);
}
#endif
} }
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_release( JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_release(
@ -212,9 +199,8 @@ extern "C" {
) )
{ {
shutdown(); shutdown();
session(pEp::Adapter::release); session(pEp::Adapter::release);
delete o; env->DeleteGlobalRef(obj);
} }
int examine_identity(pEp_identity *ident, void *arg) int examine_identity(pEp_identity *ident, void *arg)
@ -248,7 +234,6 @@ extern "C" {
} }
delete queue; delete queue;
return (void *) status; return (void *) status;
} }

3
test/Makefile

@ -3,7 +3,7 @@ CLASSPATH=.:../src
VM=java -Djava.library.path=../src VM=java -Djava.library.path=../src
test: Testing.class SyncCallbacks.class test: Testing.class SyncCallbacks.class
CLASSPATH=$(CLASSPATH) $(VM) Testing HOME=$(PWD) CLASSPATH=$(CLASSPATH) $(VM) Testing
%.class: %.java %.class: %.java
CLASSPATH=$(CLASSPATH) javac $< CLASSPATH=$(CLASSPATH) javac $<
@ -13,3 +13,4 @@ test: Testing.class SyncCallbacks.class
clean: clean:
rm -f *.class rm -f *.class
rm -f *.log rm -f *.log
rm -f *.pEp_*

Loading…
Cancel
Save