[SCM] gsequencer/upstream: added locking support to ags_devout.c and ags_audio.c
jkraehemann-guest at users.alioth.debian.org
jkraehemann-guest at users.alioth.debian.org
Sun Jun 14 16:06:59 UTC 2015
The following commit has been merged in the upstream branch:
commit 786d78b2086a9d5d17c2c218dbd853715231591e
Author: Joël Krähemann <weedlight at gmail.com>
Date: Thu Apr 9 21:01:50 2015 +0000
added locking support to ags_devout.c and ags_audio.c
diff --git a/.deps/ags-ags_audio.Po b/.deps/ags-ags_audio.Po
index 9bad617..f631e5e 100644
--- a/.deps/ags-ags_audio.Po
+++ b/.deps/ags-ags_audio.Po
@@ -603,10 +603,10 @@ ags-ags_audio.o: src/ags/audio/ags_audio.c /usr/include/stdc-predef.h \
src/ags/X/ags_performance_preferences.h \
src/ags/X/ags_server_preferences.h src/ags/lib/ags_list.h \
src/ags/object/ags_dynamic_connectable.h src/ags/object/ags_marshal.h \
- src/ags/audio/ags_output.h src/ags/audio/ags_input.h \
- /usr/include/glib-2.0/glib/gstdio.h /usr/include/glib-2.0/glib/gprintf.h \
- /usr/include/sys/stat.h src/ags/audio/ags_recall_audio.h \
- src/ags/audio/file/ags_audio_file.h \
+ src/ags/thread/ags_mutex_manager.h src/ags/audio/ags_output.h \
+ src/ags/audio/ags_input.h /usr/include/glib-2.0/glib/gstdio.h \
+ /usr/include/glib-2.0/glib/gprintf.h /usr/include/sys/stat.h \
+ src/ags/audio/ags_recall_audio.h src/ags/audio/file/ags_audio_file.h \
src/ags/audio/task/ags_audio_set_recycling.h
/usr/include/stdc-predef.h:
@@ -2117,6 +2117,8 @@ src/ags/object/ags_dynamic_connectable.h:
src/ags/object/ags_marshal.h:
+src/ags/thread/ags_mutex_manager.h:
+
src/ags/audio/ags_output.h:
src/ags/audio/ags_input.h:
diff --git a/.deps/ags-ags_devout.Po b/.deps/ags-ags_devout.Po
index 23c3865..6460f8d 100644
--- a/.deps/ags-ags_devout.Po
+++ b/.deps/ags-ags_devout.Po
@@ -586,8 +586,8 @@ ags-ags_devout.o: src/ags/audio/ags_devout.c /usr/include/stdc-predef.h \
/usr/include/libxml2/libxml/xlink.h /usr/include/libxml2/libxml/SAX2.h \
src/ags/thread/ags_timestamp_thread.h src/ags/audio/ags_timestamp.h \
src/ags/audio/ags_note.h src/ags-lib/object/ags_connectable.h \
- src/ags/main.h src/ags/lib/ags_log.h src/ags/server/ags_server.h \
- /usr/include/netinet/in.h \
+ src/ags/thread/ags_mutex_manager.h src/ags/main.h src/ags/lib/ags_log.h \
+ src/ags/server/ags_server.h /usr/include/netinet/in.h \
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/include/stdint.h \
/usr/include/stdint.h /usr/include/bits/wchar.h \
/usr/include/sys/socket.h /usr/include/sys/uio.h /usr/include/bits/uio.h \
@@ -2036,6 +2036,8 @@ src/ags/audio/ags_note.h:
src/ags-lib/object/ags_connectable.h:
+src/ags/thread/ags_mutex_manager.h:
+
src/ags/main.h:
src/ags/lib/ags_log.h:
diff --git a/src/ags/audio/ags_audio.c b/src/ags/audio/ags_audio.c
index c82e63e..af4f758 100644
--- a/src/ags/audio/ags_audio.c
+++ b/src/ags/audio/ags_audio.c
@@ -27,6 +27,7 @@
#include <ags/object/ags_dynamic_connectable.h>
#include <ags/object/ags_marshal.h>
+#include <ags/thread/ags_mutex_manager.h>
#include <ags/thread/ags_audio_loop.h>
#include <ags/thread/ags_task_thread.h>
@@ -41,6 +42,8 @@
#include <ags/audio/task/ags_audio_set_recycling.h>
+#include <pthread.h>
+
#include <stdlib.h>
#include <stdio.h>
@@ -105,6 +108,8 @@ static gpointer ags_audio_parent_class = NULL;
static guint audio_signals[LAST_SIGNAL];
+extern pthread_mutex_t ags_application_mutex;
+
GType
ags_audio_get_type (void)
{
@@ -293,6 +298,30 @@ ags_audio_connectable_interface_init(AgsConnectableInterface *connectable)
void
ags_audio_init(AgsAudio *audio)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+ pthread_mutexattr_t attr;
+
+ //FIXME:JK: memory leak
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr,
+ PTHREAD_MUTEX_RECURSIVE);
+
+ mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
+ pthread_mutex_init(mutex,
+ &attr);
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ ags_mutex_manager_insert(mutex_manager,
+ audio,
+ mutex);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
audio->flags = 0;
audio->devout = NULL;
@@ -379,6 +408,17 @@ ags_audio_finalize(GObject *gobject)
AgsAudio *audio;
AgsChannel *channel;
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ ags_mutex_manager_remove(mutex_manager,
+ gobject);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
audio = AGS_AUDIO(gobject);
if(audio->devout != NULL)
@@ -493,6 +533,7 @@ ags_audio_connect(AgsConnectable *connectable)
{
AgsAudio *audio;
AgsChannel *channel;
+
GList *list;
audio = AGS_AUDIO(connectable);
@@ -1454,13 +1495,33 @@ ags_audio_real_set_audio_channels(AgsAudio *audio,
void
ags_audio_set_audio_channels(AgsAudio *audio, guint audio_channels)
{
- g_return_if_fail(AGS_IS_AUDIO(audio));
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
+ if(!AGS_IS_AUDIO(audio)){
+ pthread_mutex_unlock(mutex);
+ return;
+ }
g_object_ref((GObject *) audio);
g_signal_emit(G_OBJECT(audio),
audio_signals[SET_AUDIO_CHANNELS], 0,
audio_channels, audio->audio_channels);
g_object_unref((GObject *) audio);
+
+ pthread_mutex_unlock(mutex);
}
/*
@@ -2161,9 +2222,27 @@ ags_audio_real_set_pads(AgsAudio *audio,
void
ags_audio_set_pads(AgsAudio *audio, GType type, guint pads)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
guint pads_old;
- g_return_if_fail(AGS_IS_AUDIO(audio));
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
+ if(!AGS_IS_AUDIO(audio)){
+ pthread_mutex_unlock(mutex);
+ return;
+ }
g_object_ref((GObject *) audio);
pads_old = ((g_type_is_a(type, AGS_TYPE_OUTPUT)) ? audio->output_pads: audio->input_pads);
@@ -2171,6 +2250,8 @@ ags_audio_set_pads(AgsAudio *audio, GType type, guint pads)
audio_signals[SET_PADS], 0,
type, pads, pads_old);
g_object_unref((GObject *) audio);
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2187,14 +2268,33 @@ AgsRecallID*
ags_audio_init_run(AgsAudio *audio)
{
AgsRecallID *recall_id;
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
- g_return_if_fail(AGS_IS_AUDIO(audio));
+ if(!AGS_IS_AUDIO(audio)){
+ pthread_mutex_unlock(mutex);
+ return;
+ }
g_object_ref((GObject *) audio);
g_signal_emit(G_OBJECT(audio),
audio_signals[INIT_RUN], 0,
&recall_id);
g_object_unref((GObject *) audio);
+
+ pthread_mutex_unlock(mutex);
return(recall_id);
}
@@ -2211,13 +2311,33 @@ ags_audio_init_run(AgsAudio *audio)
void
ags_audio_tact(AgsAudio *audio, AgsRecallID *recall_id)
{
- g_return_if_fail(AGS_IS_AUDIO(audio));
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
+ if(!AGS_IS_AUDIO(audio)){
+ pthread_mutex_unlock(mutex);
+ return;
+ }
g_object_ref((GObject *) audio);
g_signal_emit(G_OBJECT(audio),
audio_signals[TACT], 0,
recall_id);
g_object_unref((GObject *) audio);
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2232,13 +2352,33 @@ ags_audio_tact(AgsAudio *audio, AgsRecallID *recall_id)
void
ags_audio_done(AgsAudio *audio, AgsRecallID *recall_id)
{
- g_return_if_fail(AGS_IS_AUDIO(audio));
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+ pthread_mutex_lock(mutex);
+
+ if(!AGS_IS_AUDIO(audio)){
+ pthread_mutex_unlock(mutex);
+ return;
+ }
+
g_object_ref((GObject *) audio);
g_signal_emit(G_OBJECT(audio),
audio_signals[DONE], 0,
recall_id);
g_object_unref((GObject *) audio);
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2268,8 +2408,25 @@ ags_audio_set_sequence_length(AgsAudio *audio, guint sequence_length)
void
ags_audio_add_recycling_container(AgsAudio *audio, GObject *recycling_container)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
g_object_ref(recycling_container);
audio->recycling_container = g_list_prepend(audio->recycling_container, recycling_container);
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2284,8 +2441,25 @@ ags_audio_add_recycling_container(AgsAudio *audio, GObject *recycling_container)
void
ags_audio_remove_recycling_container(AgsAudio *audio, GObject *recycling_container)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
audio->recycling_container = g_list_remove(audio->recycling_container, recycling_container);
g_object_unref(recycling_container);
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2300,11 +2474,28 @@ ags_audio_remove_recycling_container(AgsAudio *audio, GObject *recycling_contain
void
ags_audio_add_recall_id(AgsAudio *audio, GObject *recall_id)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
/*
* TODO:JK: thread synchronisation
*/
g_object_ref(recall_id);
audio->recall_id = g_list_prepend(audio->recall_id, recall_id);
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2319,12 +2510,29 @@ ags_audio_add_recall_id(AgsAudio *audio, GObject *recall_id)
void
ags_audio_remove_recall_id(AgsAudio *audio, GObject *recall_id)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
/*
* TODO:JK: thread synchronisation
*/
audio->recall_id = g_list_remove(audio->recall_id, recall_id);
g_object_unref(recall_id);
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2339,12 +2547,29 @@ ags_audio_remove_recall_id(AgsAudio *audio, GObject *recall_id)
void
ags_audio_add_recall_container(AgsAudio *audio, GObject *recall_container)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
/*
* TODO:JK: thread synchronisation
*/
g_object_ref(recall_container);
audio->container = g_list_prepend(audio->container, recall_container);
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2359,12 +2584,29 @@ ags_audio_add_recall_container(AgsAudio *audio, GObject *recall_container)
void
ags_audio_remove_recall_container(AgsAudio *audio, GObject *recall_container)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
/*
* TODO:JK: thread synchronisation
*/
audio->container = g_list_remove(audio->container, recall_container);
g_object_unref(recall_container);
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2380,6 +2622,21 @@ ags_audio_remove_recall_container(AgsAudio *audio, GObject *recall_container)
void
ags_audio_add_recall(AgsAudio *audio, GObject *recall, gboolean play)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
/*
* TODO:JK: thread synchronisation
*/
@@ -2391,6 +2648,8 @@ ags_audio_add_recall(AgsAudio *audio, GObject *recall, gboolean play)
}else{
audio->recall = g_list_append(audio->recall, recall);
}
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2406,6 +2665,21 @@ ags_audio_add_recall(AgsAudio *audio, GObject *recall, gboolean play)
void
ags_audio_remove_recall(AgsAudio *audio, GObject *recall, gboolean play)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
/*
* TODO:JK: thread synchronisation
*/
@@ -2417,6 +2691,8 @@ ags_audio_remove_recall(AgsAudio *audio, GObject *recall, gboolean play)
}
g_object_unref(G_OBJECT(recall));
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2435,6 +2711,21 @@ ags_audio_duplicate_recall(AgsAudio *audio,
AgsRecall *recall, *copy;
GList *list_recall_start, *list_recall;
gboolean playback, sequencer, notation;
+
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
//#ifdef AGS_DEBUG
g_message("ags_audio_duplicate_recall: %s - audio.lines[%u,%u]\n\0", G_OBJECT_TYPE_NAME(audio->machine), audio->output_lines, audio->input_lines);
@@ -2474,6 +2765,7 @@ ags_audio_duplicate_recall(AgsAudio *audio,
list_recall = list_recall->next;
}
+ pthread_mutex_unlock(mutex);
return;
}else{
//TODO:JK: optimize tree see deprecated AgsRunOrder
@@ -2526,6 +2818,8 @@ ags_audio_duplicate_recall(AgsAudio *audio,
/* iterate */
list_recall = list_recall->next;
}
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2542,9 +2836,24 @@ void ags_audio_resolve_recall(AgsAudio *audio,
{
AgsRecall *recall;
GList *list_recall;
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
/* return if already duplicated */
if((AGS_RECALL_ID_RESOLVE & (recall_id->flags)) != 0){
+ pthread_mutex_unlock(mutex);
return;
}
@@ -2563,6 +2872,8 @@ void ags_audio_resolve_recall(AgsAudio *audio,
list_recall = list_recall->next;
}
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2581,21 +2892,38 @@ ags_audio_init_recall(AgsAudio *audio, gint stage,
{
AgsRecall *recall;
GList *list_recall;
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
/* return if already initialized */
switch(stage){
case 0:
if((AGS_RECALL_ID_INIT_PRE & (recall_id->flags)) != 0){
+ pthread_mutex_unlock(mutex);
return;
}
break;
case 1:
if((AGS_RECALL_ID_INIT_INTER & (recall_id->flags)) != 0){
+ pthread_mutex_unlock(mutex);
return;
}
break;
case 2:
if((AGS_RECALL_ID_INIT_POST & (recall_id->flags)) != 0){
+ pthread_mutex_unlock(mutex);
return;
}
break;
@@ -2634,6 +2962,8 @@ ags_audio_init_recall(AgsAudio *audio, gint stage,
list_recall = list_recall->next;
}
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2652,6 +2982,20 @@ ags_audio_is_playing(AgsAudio *audio)
AgsChannel *output;
AgsRecallID *recall_id;
AgsDevoutPlay *devout_play;
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
output = audio->output;
@@ -2661,11 +3005,16 @@ ags_audio_is_playing(AgsAudio *audio)
if((AGS_DEVOUT_PLAY_PLAYBACK & (devout_play->flags)) != 0 ||
(AGS_DEVOUT_PLAY_SEQUENCER & (devout_play->flags)) != 0 ||
(AGS_DEVOUT_PLAY_NOTATION & (devout_play->flags)) != 0){
+
+ pthread_mutex_unlock(mutex);
+
return(TRUE);
}
output = output->next;
}
+
+ pthread_mutex_unlock(mutex);
return(FALSE);
}
@@ -2687,6 +3036,20 @@ ags_audio_play(AgsAudio *audio,
{
AgsRecall *recall;
GList *list, *list_next;
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
/* return if already played */
switch(stage){
@@ -2752,6 +3115,8 @@ ags_audio_play(AgsAudio *audio,
list = list_next;
}
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2776,6 +3141,20 @@ ags_audio_recursive_play_init(AgsAudio *audio,
GList *list, *list_start;
gint stage;
gboolean arrange_recall_id, duplicate_templates, resolve_dependencies;
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
list = NULL;
list_start = NULL;
@@ -2817,6 +3196,8 @@ ags_audio_recursive_play_init(AgsAudio *audio,
channel = channel->next;
}
}
+
+ pthread_mutex_unlock(mutex);
return(list_start);
}
@@ -2837,11 +3218,25 @@ ags_audio_remove(AgsAudio *audio,
AgsRecall *recall;
GList *list, *list_next;
gboolean play;
+ AgsMutexManager *mutex_manager;
+ pthread_mutex_t *mutex;
+
if(recall_id == NULL){
return;
}
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
if(recall_id->recycling_container->parent == NULL){
list = audio->play;
play = TRUE;
@@ -2874,6 +3269,8 @@ ags_audio_remove(AgsAudio *audio,
audio->recall_id = g_list_remove(audio->recall_id,
recall_id);
g_object_unref(recall_id);
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2891,11 +3288,25 @@ ags_audio_cancel(AgsAudio *audio,
{
AgsRecall *recall;
GList *list, *list_next;
-
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
if(recall_id == NULL){
return;
}
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
if(recall_id->recycling_container->parent == NULL)
list = audio->play;
else
@@ -2922,6 +3333,8 @@ ags_audio_cancel(AgsAudio *audio,
list = list_next;
}
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -2938,10 +3351,26 @@ ags_audio_set_devout(AgsAudio *audio, GObject *devout)
{
AgsChannel *channel;
GList *list;
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
/* audio */
- if(audio->devout == devout)
+ if(audio->devout == devout){
+ pthread_mutex_unlock(mutex);
return;
+ }
if(audio->devout != NULL)
g_object_unref(audio->devout);
@@ -2993,6 +3422,8 @@ ags_audio_set_devout(AgsAudio *audio, GObject *devout)
channel = channel->next;
}
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -3019,6 +3450,20 @@ ags_audio_open_files(AgsAudio *audio,
guint i, j;
guint list_length;
GError *error;
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
channel = audio->input;
@@ -3121,6 +3566,8 @@ ags_audio_open_files(AgsAudio *audio,
filenames = filenames->next;
}
}
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -3138,6 +3585,20 @@ ags_audio_find_port(AgsAudio *audio)
{
GList *recall;
GList *list;
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ audio);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
list = NULL;
@@ -3180,6 +3641,8 @@ ags_audio_find_port(AgsAudio *audio)
/* */
list = g_list_reverse(list);
+ pthread_mutex_unlock(mutex);
+
return(list);
}
diff --git a/src/ags/audio/ags_devout.c b/src/ags/audio/ags_devout.c
index cc96e89..d1e9953 100644
--- a/src/ags/audio/ags_devout.c
+++ b/src/ags/audio/ags_devout.c
@@ -20,6 +20,8 @@
#include <ags-lib/object/ags_connectable.h>
+#include <ags/thread/ags_mutex_manager.h>
+
#include <ags/main.h>
#include <sys/stat.h>
@@ -33,6 +35,8 @@
#include <math.h>
#include <time.h>
+#include <pthread.h>
+
#include <ags/audio/ags_config.h>
#include <ags/audio/ags_notation.h>
@@ -102,6 +106,8 @@ static guint devout_signals[LAST_SIGNAL];
/* dangerous - produces a lot of output */
static gboolean DEBUG_DEVOUT = FALSE;
+extern pthread_mutex_t ags_application_mutex;
+
GType
ags_devout_get_type (void)
{
@@ -372,11 +378,35 @@ ags_devout_connectable_interface_init(AgsConnectableInterface *connectable)
void
ags_devout_init(AgsDevout *devout)
{
+ AgsMutexManager *mutex_manager;
+
gdouble delay;
guint default_tact_frames;
guint default_period;
guint i;
+
+ pthread_mutex_t *mutex;
+ pthread_mutexattr_t attr;
+
+ //FIXME:JK: memory leak
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr,
+ PTHREAD_MUTEX_RECURSIVE);
+
+ mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
+ pthread_mutex_init(mutex,
+ &attr);
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ ags_mutex_manager_insert(mutex_manager,
+ devout,
+ mutex);
+ pthread_mutex_unlock(&(ags_application_mutex));
+
/* flags */
devout->flags = (AGS_DEVOUT_ALSA);
@@ -669,10 +699,22 @@ void
ags_devout_finalize(GObject *gobject)
{
AgsDevout *devout;
+
+ AgsMutexManager *mutex_manager;
+
GList *list, *list_next;
devout = AGS_DEVOUT(gobject);
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ ags_mutex_manager_remove(mutex_manager,
+ gobject);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
/* free output buffer */
free(devout->buffer[0]);
free(devout->buffer[1]);
@@ -684,7 +726,7 @@ ags_devout_finalize(GObject *gobject)
/* free AgsAttack */
free(devout->attack);
-
+
/* call parent */
G_OBJECT_CLASS(ags_devout_parent_class)->finalize(gobject);
}
@@ -693,8 +735,9 @@ void
ags_devout_connect(AgsConnectable *connectable)
{
AgsDevout *devout;
- GList *list;
+ GList *list;
+
devout = AGS_DEVOUT(connectable);
list = devout->audio;
@@ -988,6 +1031,21 @@ ags_devout_pcm_info(char *card_id,
void
ags_devout_add_audio(AgsDevout *devout, GObject *audio)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ devout);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
if(g_list_find(devout->audio,
audio) != NULL){
return;
@@ -996,6 +1054,8 @@ ags_devout_add_audio(AgsDevout *devout, GObject *audio)
g_object_ref(G_OBJECT(audio));
devout->audio = g_list_prepend(devout->audio,
audio);
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -1010,9 +1070,26 @@ ags_devout_add_audio(AgsDevout *devout, GObject *audio)
void
ags_devout_remove_audio(AgsDevout *devout, GObject *audio)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ devout);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
devout->audio = g_list_remove(devout->audio,
audio);
g_object_unref(G_OBJECT(audio));
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -1026,7 +1103,24 @@ ags_devout_remove_audio(AgsDevout *devout, GObject *audio)
void
ags_devout_tic(AgsDevout *devout)
{
- g_return_if_fail(AGS_IS_DEVOUT(devout));
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ devout);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
+ if(!AGS_IS_DEVOUT(devout)){
+ pthread_mutex_unlock(mutex);
+ }
if((AGS_DEVOUT_PLAY & devout->flags) == 0){
g_message("ags_devout_tic: not playing\0");
@@ -1037,6 +1131,8 @@ ags_devout_tic(AgsDevout *devout)
g_signal_emit(G_OBJECT(devout),
devout_signals[TIC], 0);
g_object_unref((GObject *) devout);
+
+ pthread_mutex_unlock(mutex);
}
/**
@@ -1050,6 +1146,21 @@ ags_devout_tic(AgsDevout *devout)
void
ags_devout_switch_buffer_flag(AgsDevout *devout)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ devout);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
if((AGS_DEVOUT_BUFFER0 & (devout->flags)) != 0){
devout->flags &= (~AGS_DEVOUT_BUFFER0);
devout->flags |= AGS_DEVOUT_BUFFER1;
@@ -1063,12 +1174,16 @@ ags_devout_switch_buffer_flag(AgsDevout *devout)
devout->flags &= (~AGS_DEVOUT_BUFFER3);
devout->flags |= AGS_DEVOUT_BUFFER0;
}
+
+ pthread_mutex_unlock(mutex);
}
void
ags_devout_alsa_init(AgsDevout *devout,
GError **error)
{
+ AgsMutexManager *mutex_manager;
+
static unsigned int period_time = 100000;
static snd_pcm_format_t format = SND_PCM_FORMAT_S16;
@@ -1086,6 +1201,19 @@ ags_devout_alsa_init(AgsDevout *devout,
snd_pcm_sw_params_t *swparams;
int period_event = 0;
int err, dir;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ devout);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
/* Open PCM device for playback. */
if ((err = snd_pcm_open(&handle, devout->out.alsa.device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
@@ -1219,14 +1347,31 @@ ags_devout_alsa_init(AgsDevout *devout,
devout->out.alsa.handle = handle;
devout->delay_counter = 0.0;
devout->tic_counter = 0;
+
+ pthread_mutex_unlock(mutex);
}
void
ags_devout_alsa_play(AgsDevout *devout,
GError **error)
{
+ AgsMutexManager *mutex_manager;
+
gdouble delay;
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ devout);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
/* */
if((AGS_DEVOUT_BUFFER0 & (devout->flags)) != 0){
memset(devout->buffer[3], 0, (size_t) devout->dsp_channels * devout->buffer_size * sizeof(signed short));
@@ -1392,14 +1537,33 @@ ags_devout_alsa_play(AgsDevout *devout,
ags_devout_switch_buffer_flag(devout);
snd_pcm_prepare(devout->out.alsa.handle);
+
+ pthread_mutex_unlock(mutex);
}
void
ags_devout_alsa_free(AgsDevout *devout)
{
+ AgsMutexManager *mutex_manager;
+
+ pthread_mutex_t *mutex;
+
+ pthread_mutex_lock(&(ags_application_mutex));
+
+ mutex_manager = ags_mutex_manager_get_instance();
+
+ mutex = ags_mutex_manager_lookup(mutex_manager,
+ devout);
+
+ pthread_mutex_unlock(&(ags_application_mutex));
+
+ pthread_mutex_lock(mutex);
+
snd_pcm_drain(devout->out.alsa.handle);
snd_pcm_close(devout->out.alsa.handle);
devout->out.alsa.handle = NULL;
+
+ pthread_mutex_unlock(mutex);
}
/**
diff --git a/src/ags/thread/ags_mutex_manager.c b/src/ags/thread/ags_mutex_manager.c
index a68105c..bf0e26c 100644
--- a/src/ags/thread/ags_mutex_manager.c
+++ b/src/ags/thread/ags_mutex_manager.c
@@ -58,9 +58,9 @@ ags_mutex_manager_get_type()
};
ags_type_mutex_manager = g_type_register_static(G_TYPE_OBJECT,
- "AgsMutexManager\0",
- &ags_mutex_manager_info,
- 0);
+ "AgsMutexManager\0",
+ &ags_mutex_manager_info,
+ 0);
g_type_add_interface_static(ags_type_mutex_manager,
AGS_TYPE_CONNECTABLE,
--
gsequencer packaging
More information about the pkg-multimedia-commits
mailing list