[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