get rid of open/close context

This commit is contained in:
B. Petersen 2020-05-25 16:59:13 +02:00
parent 4782d18824
commit d42eb1d920
No known key found for this signature in database
GPG key ID: 3B88E92DEA8E9AFC
4 changed files with 43 additions and 96 deletions

View file

@ -173,14 +173,6 @@ static uint32_t* jintArray2uint32Pointer(JNIEnv* env, jintArray ja, int* ret_icn
******************************************************************************/
typedef struct dc_jnicontext_t {
JavaVM* jvm; // JNIEnv cannot be shared between threads, so we share the JavaVM object
jclass cls;
jobject obj;
jmethodID methodId;
} dc_jnicontext_t;
static dc_context_t* get_dc_context(JNIEnv *env, jobject obj)
{
static jfieldID fid = 0;
@ -195,42 +187,12 @@ static dc_context_t* get_dc_context(JNIEnv *env, jobject obj)
}
static uintptr_t s_context_callback_(dc_context_t* context, int event, uintptr_t data1, uintptr_t data2)
JNIEXPORT jlong Java_com_b44t_messenger_DcContext_createContextCPtr(JNIEnv *env, jobject obj, jstring osname, jstring dbfile)
{
jlong l;
JNIEnv* env;
dc_jnicontext_t* jnicontext = dc_get_userdata(context);
if (jnicontext==NULL || jnicontext->jvm==NULL || jnicontext->cls==NULL || jnicontext->obj==NULL || jnicontext->methodId==NULL) {
return 0; /* may happen on startup */
}
(*jnicontext->jvm)->GetEnv(jnicontext->jvm, (void**)&env, JNI_VERSION_1_6); // as this function may be called from _any_ thread, we cannot use a static pointer to JNIEnv
if (env==NULL) {
return 0; /* may happen on startup */
}
l = (*env)->CallLongMethod(env, jnicontext->obj, jnicontext->methodId, (jint)event, (jlong)data1, (jlong)data2);
return (uintptr_t)l;
}
JNIEXPORT jlong Java_com_b44t_messenger_DcContext_createContextCPtr(JNIEnv *env, jobject obj, jstring osname)
{
jclass cls = (*env)->GetObjectClass(env, obj);
dc_jnicontext_t* jnicontext = calloc(1, sizeof(dc_jnicontext_t));
if (cls==NULL || jnicontext==NULL) {
return 0;
}
(*env)->GetJavaVM(env, &jnicontext->jvm);
jnicontext->cls = (*env)->NewGlobalRef(env, cls);
jnicontext->obj = (*env)->NewGlobalRef(env, obj);
jnicontext->methodId = (*env)->GetMethodID(env, jnicontext->cls, "handleEvent","(IJJ)J" /*signature as "(param)ret" with I=int, J=long*/);
CHAR_REF(osname);
jlong contextCPtr = (jlong)dc_context_new(s_context_callback_, jnicontext, osnamePtr);
CHAR_REF(dbfile)
jlong contextCPtr = (jlong)dc_context_new(osnamePtr, dbfilePtr, NULL);
CHAR_UNREF(dbfile)
CHAR_UNREF(osname);
return contextCPtr;
}
@ -244,21 +206,6 @@ JNIEXPORT void Java_com_b44t_messenger_DcContact_unrefContextCPtr(JNIEnv *env, j
/* DcContext - open/configure/connect/fetch */
JNIEXPORT jint Java_com_b44t_messenger_DcContext_open(JNIEnv *env, jobject obj, jstring dbfile)
{
CHAR_REF(dbfile);
jint ret = dc_open(get_dc_context(env, obj), dbfilePtr, NULL);
CHAR_UNREF(dbfile)
return ret;
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_close(JNIEnv *env, jobject obj)
{
dc_close(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_setStockTranslation(JNIEnv *env, jobject obj, jint stock_id, jstring translation)
{
CHAR_REF(translation);
@ -303,93 +250,79 @@ JNIEXPORT jint Java_com_b44t_messenger_DcContext_isConfigured(JNIEnv *env, jobje
}
// TODO-ASYNC: delete these functions, also in the java-part
JNIEXPORT void Java_com_b44t_messenger_DcContext_performImapJobs(JNIEnv *env, jobject obj)
{
dc_perform_imap_jobs(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_performImapIdle(JNIEnv *env, jobject obj)
{
dc_perform_imap_idle(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_performImapFetch(JNIEnv *env, jobject obj)
{
dc_perform_imap_fetch(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_interruptImapIdle(JNIEnv *env, jobject obj)
{
dc_interrupt_imap_idle(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSentboxJobs(JNIEnv *env, jobject obj)
{
dc_perform_sentbox_jobs(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSentboxFetch(JNIEnv *env, jobject obj)
{
dc_perform_sentbox_fetch(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSentboxIdle(JNIEnv *env, jobject obj)
{
dc_perform_sentbox_idle(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_interruptSentboxIdle(JNIEnv *env, jobject obj)
{
dc_interrupt_sentbox_idle(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_performMvboxJobs(JNIEnv *env, jobject obj)
{
dc_perform_mvbox_jobs(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_performMvboxFetch(JNIEnv *env, jobject obj)
{
dc_perform_mvbox_fetch(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_performMvboxIdle(JNIEnv *env, jobject obj)
{
dc_perform_mvbox_idle(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_interruptMvboxIdle(JNIEnv *env, jobject obj)
{
dc_interrupt_mvbox_idle(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSmtpJobs(JNIEnv *env, jobject obj)
{
dc_perform_smtp_jobs(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_performSmtpIdle(JNIEnv *env, jobject obj)
{
dc_perform_smtp_idle(get_dc_context(env, obj));
}
JNIEXPORT void Java_com_b44t_messenger_DcContext_interruptSmtpIdle(JNIEnv *env, jobject obj)
{
dc_interrupt_smtp_idle(get_dc_context(env, obj));
}

View file

@ -72,20 +72,27 @@ public class DcContext {
public final static int DC_EMPTY_MVBOX = 0x01;
public final static int DC_EMPTY_INBOX = 0x02;
public DcContext(String osName) {
handleEvent(0,0,0); // call handleEvent() to make sure it is not optimized away and JNI won't find it
contextCPtr = createContextCPtr(osName);
public DcContext(String osName, String dbfile) {
contextCPtr = createContextCPtr(osName, dbfile);
}
public boolean isOk() {
return contextCPtr != 0;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
unref();
}
public void unref() {
if (contextCPtr != 0) {
unrefContextCPtr();
contextCPtr = 0;
}
}
public native int open (String dbfile);
public native void close ();
public native void setStockTranslation (int stockId, String translation);
public native String getBlobdir ();
public native void configure ();
@ -189,11 +196,6 @@ public class DcContext {
*/
public native boolean setLocation (float latitude, float longitude, float accuracy);
// event handling - you should @Override this function in derived classes
public long handleEvent(int event, long data1, long data2) {
return 0;
}
// helper to get/return strings from/to handleEvent()
public native static boolean data1IsString(int event);
public native static boolean data2IsString(int event);
@ -201,7 +203,7 @@ public class DcContext {
// working with raw c-data
private long contextCPtr; // CAVE: the name is referenced in the JNI
private native long createContextCPtr(String osName);
private native long createContextCPtr(String osName, String dbfile);
private native void unrefContextCPtr ();
public native long createMsgCPtr (int viewtype);
private native long getChatlistCPtr (int listflags, String query, int queryId);

View file

@ -65,8 +65,8 @@ public class AccountManager {
private @Nullable Account maybeGetAccount(File file) {
try {
if (!file.isDirectory() && file.getName().endsWith(".db")) {
DcContext testContext = new DcContext(null);
if (testContext.open(file.getAbsolutePath()) != 0) {
DcContext testContext = new DcContext(null, file.getAbsolutePath());
if (testContext.isOk()) {
Account ret = new Account();
ret.dbName = file.getName();
ret.displayname = testContext.getConfig("displayname");
@ -99,7 +99,7 @@ public class AccountManager {
// getSelectedAccount()
ApplicationContext appContext = (ApplicationContext)context.getApplicationContext();
appContext.dcContext.stopThreads();
appContext.dcContext.close();
appContext.dcContext.unref();
appContext.dcContext = new ApplicationDcContext(context);
}
@ -243,10 +243,10 @@ public class AccountManager {
if (deleteDbName!=null) {
// used to delete the previous account, however, as a resilience check, make sure,
// we do not delete already configured accounts (just in case sth. changes the flow of activities)
DcContext testContext = new DcContext(null);
if (testContext.open(new File(activity.getFilesDir(), deleteDbName).getAbsolutePath()) != 0) {
DcContext testContext = new DcContext(null, new File(activity.getFilesDir(), deleteDbName).getAbsolutePath());
if (testContext.isOk()) {
if (testContext.isConfigured() == 0) {
testContext.close();
testContext.unref();
AccountManager.getInstance().deleteAccount(activity, deleteDbName);
PreferenceManager.getDefaultSharedPreferences(activity)
.edit().putString("prev_account_db_name", "").apply();

View file

@ -56,12 +56,9 @@ public class ApplicationDcContext extends DcContext {
public NotificationCenter notificationCenter;
public ApplicationDcContext(Context context) {
super("Android "+BuildConfig.VERSION_NAME);
super("Android "+BuildConfig.VERSION_NAME, AccountManager.getInstance().getSelectedAccount(context).getAbsolutePath());
this.context = context;
File dbfile = AccountManager.getInstance().getSelectedAccount(context);
open(dbfile.getAbsolutePath());
// migration, can be removed after some versions (added 5/2020)
// (this will convert only for one account, but that is fine, multi-account is experimental anyway)
try {
@ -341,6 +338,10 @@ public class ApplicationDcContext extends DcContext {
public boolean run = true;
public void startThreads(int flags) {
// TODO-ASYNC: remove this function, handle the flags differently
/*
synchronized (threadsCritical) {
if (imapThread == null || !imapThread.isAlive()) {
@ -432,9 +433,14 @@ public class ApplicationDcContext extends DcContext {
smtpThread.start();
}
}
*/
}
public void waitForThreadsExecutedOnce() {
// TODO-ASYNC
/*
while(true) {
synchronized (incLoopsCritical) {
if(inboxLoops>0 && mvboxLoops>0 && smtpLoops>0) {
@ -443,10 +449,15 @@ public class ApplicationDcContext extends DcContext {
}
Util.sleep(500);
}
*/
}
public void stopThreads() {
notificationCenter.removeAllNotifiations();
// TODO-ASYNC
/*
run = false;
synchronized (threadsCritical) {
while (true) {
@ -470,6 +481,7 @@ public class ApplicationDcContext extends DcContext {
}
}
Log.i(TAG, "!!!!!!!!!!!! threads stopped");
*/
}
@ -557,7 +569,7 @@ public class ApplicationDcContext extends DcContext {
});
}
@Override
// TODO-ASYNC: make this work again
public long handleEvent(final int event, long data1, long data2) {
switch (event) {
case DC_EVENT_INFO: