Resolved telecom framework conflicts

Cleaned thread handling
More synchonizations
This commit is contained in:
Juha Heinanen
2026-05-25 10:40:41 +03:00
parent a54d79591e
commit 78aed2660c
4 changed files with 173 additions and 116 deletions

View File

@ -7,11 +7,6 @@
#include <baresip.h>
#include "logger.h"
enum
{
ASYNC_WORKERS = 4
};
typedef struct baresip_context
{
JavaVM *javaVM;
@ -22,6 +17,36 @@ typedef struct baresip_context
BaresipContext g_ctx;
enum
{
ASYNC_WORKERS = 4
};
static pthread_key_t g_thread_key;
static void detach_thread(void *env)
{
(void)env;
LOGD("detaching thread from JVM\n");
(*g_ctx.javaVM)->DetachCurrentThread(g_ctx.javaVM);
}
static JNIEnv *get_jni_env(void)
{
JNIEnv *env;
jint res = (*g_ctx.javaVM)->GetEnv(g_ctx.javaVM, (void**)&env, JNI_VERSION_1_6);
if (res != JNI_OK) {
res = (*g_ctx.javaVM)->AttachCurrentThread(g_ctx.javaVM, &env, NULL);
if (res == JNI_OK) {
pthread_setspecific(g_thread_key, env);
} else {
LOGE("failed to AttachCurrentThread, ErrorCode = %d\n", res);
return NULL;
}
}
return env;
}
static int vprintf_null(const char *p, size_t size, void *arg)
{
(void)p;
@ -257,23 +282,23 @@ static void event_handler(enum bevent_ev ev, struct bevent *event, void *arg)
return;
}
JavaVM *javaVM = g_ctx.javaVM;
JNIEnv *env;
jint res = (*javaVM)->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_6);
if (res != JNI_OK) {
LOGD("failed to get javaVM environment, ErrorCode = %d\n", res);
res = (*javaVM)->AttachCurrentThread(javaVM, &env, NULL);
if (JNI_OK != res) {
LOGE("failed to AttachCurrentThread, ErrorCode = %d\n", res);
return;
}
}
JNIEnv *env = get_jni_env();
if (!env) return;
if (!g_ctx.mainActivityClz || !g_ctx.mainActivityObj) return;
jmethodID methodId =
(*env)->GetMethodID(env, g_ctx.mainActivityClz, "uaEvent", "(Ljava/lang/String;JJ)V");
jstring jEvent = (*env)->NewStringUTF(env, event_buf);
LOGD("sending ua/call %ld/%ld event %s\n", (long)ua, (long)call, event_buf);
(*env)->CallVoidMethod(env, g_ctx.mainActivityObj, methodId, jEvent, (jlong)ua, (jlong)call);
if (methodId) {
(*env)->CallVoidMethod(env, g_ctx.mainActivityObj, methodId, jEvent, (jlong)ua, (jlong)call);
if ((*env)->ExceptionCheck(env)) {
LOGE("uaEvent method call failed\n");
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
}
(*env)->DeleteLocalRef(env, jEvent);
}
@ -291,16 +316,10 @@ static void message_handler(
return;
}
JavaVM *javaVM = g_ctx.javaVM;
JNIEnv *env;
jint res = (*javaVM)->GetEnv(javaVM, (void **)&env, JNI_VERSION_1_6);
if (res != JNI_OK) {
res = (*javaVM)->AttachCurrentThread(javaVM, &env, NULL);
if (JNI_OK != res) {
LOGE("failed to AttachCurrentThread, ErrorCode = %d\n", res);
return;
}
}
JNIEnv *env = get_jni_env();
if (!env) return;
if (!g_ctx.mainActivityClz || !g_ctx.mainActivityObj) return;
jmethodID methodId = (*env)->GetMethodID(env, g_ctx.mainActivityClz, "messageEvent",
"(JLjava/lang/String;Ljava/lang/String;[B)V");
@ -319,7 +338,14 @@ static void message_handler(
(*env)->ReleasePrimitiveArrayCritical(env, jMsg, temp, 0);
LOGD("sending message %ld/%s/%s/%.*s\n", (long)ua, peer_buf, ctype_buf, (int)size,
mbuf_buf(body));
(*env)->CallVoidMethod(env, g_ctx.mainActivityObj, methodId, (jlong)ua, jPeer, jCtype, jMsg);
if (methodId) {
(*env)->CallVoidMethod(env, g_ctx.mainActivityObj, methodId, (jlong)ua, jPeer, jCtype, jMsg);
if ((*env)->ExceptionCheck(env)) {
LOGE("messageEvent method call failed\n");
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
}
(*env)->DeleteLocalRef(env, jCtype);
(*env)->DeleteLocalRef(env, jPeer);
(*env)->DeleteLocalRef(env, jMsg);
@ -341,24 +367,30 @@ static void send_resp_handler(int err, const struct sip_msg *msg, void *arg)
LOGD("send_response_handler received response '%u %s' at %s\n", msg->scode, reason_buf,
native_time);
JavaVM *javaVM = g_ctx.javaVM;
JNIEnv *env;
jint res = (*javaVM)->GetEnv(javaVM, (void **)&env, JNI_VERSION_1_6);
if (res != JNI_OK) {
res = (*javaVM)->AttachCurrentThread(javaVM, &env, NULL);
if (JNI_OK != res) {
LOGE("failed to AttachCurrentThread, ErrorCode = %d\n", res);
mem_deref(native_time);
return;
}
JNIEnv *env = get_jni_env();
if (!env) {
mem_deref(native_time);
return;
}
if (!g_ctx.mainActivityClz || !g_ctx.mainActivityObj) {
mem_deref(native_time);
return;
}
jmethodID methodId = (*env)->GetMethodID(env, g_ctx.mainActivityClz, "messageResponse",
"(ILjava/lang/String;Ljava/lang/String;)V");
jstring javaReason = (*env)->NewStringUTF(env, reason_buf);
jstring javaTime = (*env)->NewStringUTF(env, native_time);
if (methodId)
(*env)->CallVoidMethod(env, g_ctx.mainActivityObj, methodId, msg->scode, javaReason, javaTime);
if (methodId) {
(*env)->CallVoidMethod(env, g_ctx.mainActivityObj, methodId, msg->scode, javaReason,
javaTime);
if ((*env)->ExceptionCheck(env)) {
LOGE("uaEvent messageResponse method call failed\n");
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
}
(*env)->DeleteLocalRef(env, javaReason);
(*env)->DeleteLocalRef(env, javaTime);
@ -435,6 +467,10 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
g_ctx.mainActivityClz = NULL;
g_ctx.mainActivityObj = NULL;
if (pthread_key_create(&g_thread_key, detach_thread) != 0) {
LOGE("failed to create pthread key\n");
}
return JNI_VERSION_1_6;
}