Commit 383fd81d authored by Thomas Guillem's avatar Thomas Guillem

vlcobject: get rid of java_event thread

Process java events directly from vlc event callback
parent e50fad5f
......@@ -7,7 +7,6 @@ LOCAL_MODULE := libvlcjni
LOCAL_SRC_FILES := libvlcjni.c libvlcjni-util.c libvlcjni-track.c
LOCAL_SRC_FILES += libvlcjni-equalizer.c
LOCAL_SRC_FILES += libvlcjni-vlcobject.c
LOCAL_SRC_FILES += java_event_thread.c
LOCAL_SRC_FILES += libvlcjni-media.c libvlcjni-medialist.c libvlcjni-mediadiscoverer.c
LOCAL_SRC_FILES += vout.c native_crash_handler.c thumbnailer.c
ifneq ($(APP_PLATFORM),android-21)
......
/*****************************************************************************
* java_java_event_thread.c
*****************************************************************************
* Copyright © 2015 VLC authors, VideoLAN and VideoLabs
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <stdlib.h>
#include <sys/queue.h>
#include <pthread.h>
#include "java_event_thread.h"
#include "utils.h"
#define LOG_TAG "JavaEventThread"
#include "log.h"
#define THREAD_NAME "JavaEventThread"
extern JNIEnv *jni_get_env(const char *name);
typedef struct event_queue_elm event_queue_elm;
struct event_queue_elm
{
java_event event;
TAILQ_ENTRY(event_queue_elm) next;
};
typedef TAILQ_HEAD(, event_queue_elm) EVENT_QUEUE;
struct java_event_thread {
bool b_run;
bool b_sync;
pthread_mutex_t lock;
pthread_cond_t cond;
pthread_t thread;
EVENT_QUEUE queue;
jweak jweak;
jobject jweakCompat;
};
static void *
JavaEventThread_thread(void *data)
{
JNIEnv *env = NULL;
event_queue_elm *event_elm, *event_elm_next;
java_event_thread *p_java_event_thread = data;
if (!(env = jni_get_env(THREAD_NAME)))
{
pthread_mutex_lock(&p_java_event_thread->lock);
goto end;
}
pthread_mutex_lock(&p_java_event_thread->lock);
while (p_java_event_thread->b_run)
{
java_event *p_jevent;
while (p_java_event_thread->b_run &&
!(event_elm = TAILQ_FIRST(&p_java_event_thread->queue)))
pthread_cond_wait(&p_java_event_thread->cond,
&p_java_event_thread->lock);
if (!p_java_event_thread->b_run || event_elm == NULL)
continue;
p_jevent = &event_elm->event;
pthread_mutex_unlock(&p_java_event_thread->lock);
if (p_java_event_thread->jweak)
(*env)->CallVoidMethod(env, p_java_event_thread->jweak,
fields.VLCObject.dispatchEventFromNativeID,
p_jevent->type, p_jevent->arg1, p_jevent->arg2);
else
(*env)->CallStaticVoidMethod(env, fields.VLCObject.clazz,
fields.VLCObject.dispatchEventFromWeakNativeID,
p_java_event_thread->jweakCompat,
p_jevent->type, p_jevent->arg1, p_jevent->arg2);
pthread_mutex_lock(&p_java_event_thread->lock);
TAILQ_REMOVE(&p_java_event_thread->queue, event_elm, next);
free(event_elm);
pthread_cond_signal(&p_java_event_thread->cond);
}
end:
p_java_event_thread->b_run = false;
for (event_elm = TAILQ_FIRST(&p_java_event_thread->queue);
event_elm != NULL; event_elm = event_elm_next)
{
event_elm_next = TAILQ_NEXT(event_elm, next);
TAILQ_REMOVE(&p_java_event_thread->queue, event_elm, next);
free(event_elm);
}
pthread_mutex_unlock(&p_java_event_thread->lock);
return NULL;
}
java_event_thread *
JavaEventThread_create(jweak jweak, jobject jweakCompat, bool b_sync)
{
java_event_thread *p_java_event_thread;
if (!jweak && !jweakCompat)
return NULL;
p_java_event_thread = calloc(1, sizeof(java_event_thread));
if (!p_java_event_thread)
return NULL;
pthread_mutex_init(&p_java_event_thread->lock, NULL);
pthread_cond_init(&p_java_event_thread->cond, NULL);
TAILQ_INIT(&p_java_event_thread->queue);
pthread_mutex_lock(&p_java_event_thread->lock);
p_java_event_thread->jweak = jweak;
p_java_event_thread->jweakCompat = jweakCompat;
p_java_event_thread->b_run = true;
p_java_event_thread->b_sync = b_sync;
if (pthread_create(&p_java_event_thread->thread, NULL,
JavaEventThread_thread, p_java_event_thread) != 0)
{
p_java_event_thread->b_run = false;
pthread_mutex_unlock(&p_java_event_thread->lock);
JavaEventThread_destroy(p_java_event_thread);
p_java_event_thread = NULL;
} else
pthread_mutex_unlock(&p_java_event_thread->lock);
return p_java_event_thread;
}
void
JavaEventThread_destroy(java_event_thread *p_java_event_thread)
{
pthread_mutex_lock(&p_java_event_thread->lock);
if (p_java_event_thread->b_run)
{
p_java_event_thread->b_run = false;
pthread_cond_signal(&p_java_event_thread->cond);
pthread_mutex_unlock(&p_java_event_thread->lock);
pthread_join(p_java_event_thread->thread, NULL);
} else
pthread_mutex_unlock(&p_java_event_thread->lock);
pthread_mutex_destroy(&p_java_event_thread->lock);
pthread_cond_destroy(&p_java_event_thread->cond);
free(p_java_event_thread);
}
int
JavaEventThread_add(java_event_thread *p_java_event_thread,
java_event *p_java_event)
{
event_queue_elm *event_elm;
pthread_mutex_lock(&p_java_event_thread->lock);
if (!p_java_event_thread->b_run)
goto error;
event_elm = calloc(1, sizeof(event_queue_elm));
if (!event_elm)
goto error;
event_elm->event = *p_java_event;
if (p_java_event_thread->b_sync)
TAILQ_INSERT_HEAD(&p_java_event_thread->queue, event_elm, next);
else
TAILQ_INSERT_TAIL(&p_java_event_thread->queue, event_elm, next);
pthread_cond_signal(&p_java_event_thread->cond);
if (p_java_event_thread->b_sync) {
while (p_java_event_thread->b_run &&
(event_elm == TAILQ_FIRST(&p_java_event_thread->queue)))
pthread_cond_wait(&p_java_event_thread->cond,
&p_java_event_thread->lock);
}
pthread_mutex_unlock(&p_java_event_thread->lock);
return 0;
error:
pthread_mutex_unlock(&p_java_event_thread->lock);
return -1;
}
/*****************************************************************************
* java_java_event_thread.h
*****************************************************************************
* Copyright © 2015 VLC authors, VideoLAN and VideoLabs
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef JAVA_EVENT_THREAD_H
#define JAVA_EVENT_THREAD_H
#include <jni.h>
#include <vlc/vlc.h>
#include <vlc/libvlc_events.h>
typedef struct java_event_thread java_event_thread;
typedef struct java_event java_event;
struct java_event
{
int type;
long arg1;
long arg2;
};
/* if b_sync is true, calls to JavaEventThread_add will return only when events
* are handled by Java Side */
java_event_thread *JavaEventThread_create(jweak jweak, jobject jweakCompat,
bool b_sync);
void JavaEventThread_destroy(java_event_thread *p_java_event_thread);
int JavaEventThread_add(java_event_thread *p_java_event_thread,
java_event *p_java_event);
#endif // JAVA_EVENT_THREAD_H
......@@ -22,9 +22,11 @@
#include <sys/queue.h>
#include <pthread.h>
#include "java_event_thread.h"
#include "libvlcjni-vlcobject.h"
#define THREAD_NAME "VlcObject"
extern JNIEnv *jni_get_env(const char *name);
struct vlcjni_object_owner
{
jweak weak;
......@@ -33,7 +35,6 @@ struct vlcjni_object_owner
libvlc_event_manager_t *p_event_manager;
const int *p_events;
java_event_thread *p_java_event_thread;
event_cb pf_event_cb;
};
......@@ -154,6 +155,7 @@ VLCJniObject_eventCallback(const libvlc_event_t *ev, void *data)
{
vlcjni_object *p_obj = data;
java_event jevent;
JNIEnv *env = NULL;
jevent.type = -1;
jevent.arg1 = jevent.arg2 = 0;
......@@ -161,15 +163,18 @@ VLCJniObject_eventCallback(const libvlc_event_t *ev, void *data)
if (!p_obj->p_owner->pf_event_cb(p_obj, ev, &jevent))
return;
if (!p_obj->p_owner->p_java_event_thread)
{
p_obj->p_owner->p_java_event_thread =
JavaEventThread_create(p_obj->p_owner->weak,
p_obj->p_owner->weakCompat, true);
if (!p_obj->p_owner->p_java_event_thread)
return;
}
JavaEventThread_add(p_obj->p_owner->p_java_event_thread, &jevent);
if (!(env = jni_get_env(THREAD_NAME)))
return;
if (p_obj->p_owner->weak)
(*env)->CallVoidMethod(env, p_obj->p_owner->weak,
fields.VLCObject.dispatchEventFromNativeID,
jevent.type, jevent.arg1, jevent.arg2);
else
(*env)->CallStaticVoidMethod(env, fields.VLCObject.clazz,
fields.VLCObject.dispatchEventFromWeakNativeID,
p_obj->p_owner->weakCompat,
jevent.type, jevent.arg1, jevent.arg2);
}
void
......@@ -209,7 +214,4 @@ Java_org_videolan_libvlc_VLCObject_nativeDetachEvents(JNIEnv *env, jobject thiz)
VLCJniObject_eventCallback, p_obj);
p_obj->p_owner->p_event_manager = NULL;
p_obj->p_owner->p_events = NULL;
if (p_obj->p_owner->p_java_event_thread)
JavaEventThread_destroy(p_obj->p_owner->p_java_event_thread);
}
......@@ -28,7 +28,6 @@
#include <vlc/libvlc_media_list.h>
#include <vlc/libvlc_media_discoverer.h>
#include "java_event_thread.h"
#include "utils.h"
#define LOG_TAG "VLC/JNI/VLCObject"
#include "log.h"
......@@ -36,6 +35,7 @@
typedef struct vlcjni_object vlcjni_object;
typedef struct vlcjni_object_owner vlcjni_object_owner;
typedef struct vlcjni_object_sys vlcjni_object_sys;
typedef struct java_event java_event;
struct vlcjni_object
{
......@@ -49,6 +49,13 @@ struct vlcjni_object
vlcjni_object_sys *p_sys; // used by media, medialist, mediadiscoverer...
};
struct java_event
{
int type;
long arg1;
long arg2;
};
/* event manager callback dispatched to native struct implementing a
* vlcjni_object. If the callback returns true, the event is dispatched to Java
* */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment