You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
5.0 KiB
171 lines
5.0 KiB
/*****************************************************************************
|
|
* 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 int jni_attach_thread(JNIEnv **env, const char *thread_name);
|
|
extern void jni_detach_thread();
|
|
extern int jni_get_env(JNIEnv **env);
|
|
|
|
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;
|
|
pthread_mutex_t lock;
|
|
pthread_cond_t cond;
|
|
pthread_t thread;
|
|
EVENT_QUEUE queue;
|
|
jweak jobj;
|
|
};
|
|
|
|
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 (jni_attach_thread(&env, THREAD_NAME) < 0)
|
|
{
|
|
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;
|
|
TAILQ_REMOVE(&p_java_event_thread->queue, event_elm, next);
|
|
|
|
pthread_mutex_unlock(&p_java_event_thread->lock);
|
|
|
|
(*env)->CallVoidMethod(env, p_java_event_thread->jobj,
|
|
fields.VLCObject.dispatchEventFromNativeID,
|
|
p_jevent->type, p_jevent->arg1, p_jevent->arg2);
|
|
|
|
free(event_elm);
|
|
|
|
pthread_mutex_lock(&p_java_event_thread->lock);
|
|
}
|
|
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);
|
|
|
|
if (env)
|
|
jni_detach_thread();
|
|
|
|
return NULL;
|
|
}
|
|
|
|
java_event_thread *
|
|
JavaEventThread_create(jweak jobj)
|
|
{
|
|
java_event_thread *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);
|
|
|
|
p_java_event_thread->jobj = jobj;
|
|
p_java_event_thread->b_run = true;
|
|
pthread_create(&p_java_event_thread->thread, NULL,
|
|
JavaEventThread_thread, p_java_event_thread);
|
|
|
|
return p_java_event_thread;
|
|
}
|
|
|
|
void
|
|
JavaEventThread_destroy(java_event_thread *p_java_event_thread)
|
|
{
|
|
pthread_mutex_lock(&p_java_event_thread->lock);
|
|
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);
|
|
|
|
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;
|
|
|
|
TAILQ_INSERT_TAIL(&p_java_event_thread->queue, event_elm, next);
|
|
pthread_cond_signal(&p_java_event_thread->cond);
|
|
pthread_mutex_unlock(&p_java_event_thread->lock);
|
|
return 0;
|
|
error:
|
|
pthread_mutex_unlock(&p_java_event_thread->lock);
|
|
return -1;
|
|
}
|
|
|