Hello community,

here is the log from the commit of package gsequencer for openSUSE:Factory 
checked in at 2019-12-18 14:46:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gsequencer (Old)
 and      /work/SRC/openSUSE:Factory/.gsequencer.new.4691 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "gsequencer"

Wed Dec 18 14:46:29 2019 rev:55 rq:757601 version:2.4.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/gsequencer/gsequencer.changes    2019-11-29 
16:02:59.620803539 +0100
+++ /work/SRC/openSUSE:Factory/.gsequencer.new.4691/gsequencer.changes  
2019-12-18 14:48:45.925950885 +0100
@@ -1,0 +2,6 @@
+Tue Dec 17 15:28:00 UTC 2019 - Joël Krähemann <[email protected]>
+
+- fixed potential SIGSEGV as adding AgsBulkMember to AgsFFPlayer.
+- fixed accessing freed memory in ags_effect_bridge.c
+
+-------------------------------------------------------------------

Old:
----
  gsequencer-2.4.1.tar.gz

New:
----
  gsequencer-2.4.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ gsequencer.spec ++++++
--- /var/tmp/diff_new_pack.R5h2mc/_old  2019-12-18 14:48:46.453951127 +0100
+++ /var/tmp/diff_new_pack.R5h2mc/_new  2019-12-18 14:48:46.453951127 +0100
@@ -22,7 +22,7 @@
 # activated with --with run_functional_tests command line switch.
 %bcond_with run_functional_tests
 Name:           gsequencer
-Version:        2.4.1
+Version:        2.4.4
 Release:        0
 Summary:        Audio processing engine
 License:        GPL-3.0-or-later AND AGPL-3.0-or-later AND GFDL-1.3-only

++++++ gsequencer-2.4.1.tar.gz -> gsequencer-2.4.4.tar.gz ++++++
++++ 1710 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ChangeLog new/gsequencer-2.4.4/ChangeLog
--- old/gsequencer-2.4.1/ChangeLog      2019-11-28 05:49:09.000000000 +0100
+++ new/gsequencer-2.4.4/ChangeLog      2019-12-17 15:30:55.000000000 +0100
@@ -1,3 +1,19 @@
+ags (2.4.4)
+
+       [ Joël Krähemann (Maintainer of Advanced Gtk+ Sequencer) ]
+       * fixed potential SIGSEGV related to AgsFFPlayer's effect bulk
+       * fixed accessing freed memory of AgsBulkMember
+
+ags (2.4.3)
+
+       [ Joël Krähemann (Maintainer of Advanced Gtk+ Sequencer) ]
+       * fixed potentially freed env pointer
+
+ags (2.4.2)
+
+       [ Joël Krähemann (Maintainer of Advanced Gtk+ Sequencer) ]
+       * implemented AgsPriority to configure RT threads
+
 ags (2.4.1)
 
        [ Joël Krähemann (Maintainer of Advanced Gtk+ Sequencer) ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/Makefile.am new/gsequencer-2.4.4/Makefile.am
--- old/gsequencer-2.4.1/Makefile.am    2019-11-28 05:47:15.000000000 +0100
+++ new/gsequencer-2.4.4/Makefile.am    2019-12-17 09:43:02.000000000 +0100
@@ -619,6 +619,7 @@
        ags/object/ags_mutable.h \
        ags/object/ags_plugin.h \
        ags/object/ags_portlet.h \
+       ags/object/ags_priority.h \
        ags/object/ags_seekable.h \
        ags/object/ags_sequencer.h \
        ags/object/ags_soundcard.h \
@@ -642,6 +643,7 @@
        ags/object/ags_mutable.c \
        ags/object/ags_plugin.c \
        ags/object/ags_portlet.c \
+       ags/object/ags_priority.c \
        ags/object/ags_seekable.c \
        ags/object/ags_sequencer.c \
        ags/object/ags_soundcard.c \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/X/ags_bulk_member.c 
new/gsequencer-2.4.4/ags/X/ags_bulk_member.c
--- old/gsequencer-2.4.1/ags/X/ags_bulk_member.c        2019-11-28 
04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/X/ags_bulk_member.c        2019-12-17 
09:54:34.000000000 +0100
@@ -1493,7 +1493,8 @@
   recall_channel_port = NULL;
   
   /* search channels */
-  channel = NULL;
+  channel =
+    start_channel = NULL;
   
   if(AGS_EFFECT_BULK(effect_bulk)->channel_type == AGS_TYPE_OUTPUT){
     g_object_get(audio,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/X/ags_effect_bulk.c 
new/gsequencer-2.4.4/ags/X/ags_effect_bulk.c
--- old/gsequencer-2.4.1/ags/X/ags_effect_bulk.c        2019-11-28 
04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/X/ags_effect_bulk.c        2019-12-17 
15:30:03.000000000 +0100
@@ -2655,6 +2655,9 @@
   ags_effect_bulk_plugin_free(effect_bulk_plugin);
 
   /* retrieve audio properties and channel */
+  current = 
+    start_channel = NULL;
+  
   pthread_mutex_lock(audio_mutex);
 
   audio_channels = effect_bulk->audio->audio_channels;
@@ -2672,7 +2675,7 @@
     if(current != NULL){
       g_object_ref(current);
     }
-  }else{
+  }else if(effect_bulk->channel_type == AGS_TYPE_INPUT){
     g_object_get(effect_bulk->audio,
                 "input", &start_channel,
                 "input-pads", &pads,
@@ -2741,17 +2744,26 @@
   list =
     start_list = gtk_container_get_children((GtkContainer *) 
effect_bulk->table);
 
-  filename = AGS_BULK_MEMBER(list->data)->filename;
-  effect = AGS_BULK_MEMBER(list->data)->effect;
+  g_object_get(list->data,
+              "filename", &filename,
+              "effect", &effect,
+              NULL);
 
   i = 0;
   
   while(list != NULL && i <= nth){    
     if(AGS_IS_BULK_MEMBER(list->data)){
+      g_message("%s %s", AGS_BULK_MEMBER(list->data)->filename, 
AGS_BULK_MEMBER(list->data)->effect);
+      
       if(!(!g_strcmp0(AGS_BULK_MEMBER(list->data)->filename, filename) &&
           !g_strcmp0(AGS_BULK_MEMBER(list->data)->effect, effect))){
-       filename = AGS_BULK_MEMBER(list->data)->filename;
-       effect = AGS_BULK_MEMBER(list->data)->effect;
+       g_free(filename);
+       g_free(effect);
+
+       g_object_get(list->data,
+                    "filename", &filename,
+                    "effect", &effect,
+                    NULL);
 
        i++;
       }
@@ -2768,8 +2780,7 @@
        }
 
        gtk_widget_destroy(GTK_WIDGET(list->data));
-      }
-      
+      }      
     }
 
     list = list->next;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/X/ags_menu_action_callbacks.c 
new/gsequencer-2.4.4/ags/X/ags_menu_action_callbacks.c
--- old/gsequencer-2.4.1/ags/X/ags_menu_action_callbacks.c      2019-11-28 
04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/X/ags_menu_action_callbacks.c      2019-12-17 
09:43:02.000000000 +0100
@@ -1456,7 +1456,7 @@
 
   static FILE *file = NULL;
   struct stat sb;
-  static gchar *license;
+  static gchar *license = NULL;
   static GdkPixbuf *logo = NULL;
 
   gchar *license_filename;
@@ -1472,7 +1472,7 @@
 
   gchar *authors[] = { "Joël Krähemann", NULL }; 
 
-#if defined AGS_W32API
+#if defined(AGS_W32API)
   app_dir = NULL;
 #endif
   
@@ -1480,7 +1480,7 @@
   license_filename = g_strdup(AGS_LICENSE_FILENAME);
 #else
   if((license_filename = getenv("AGS_LICENSE_FILENAME")) == NULL){
-#if defined (AGS_W32API)
+#if defined(AGS_W32API)
     application_context = ags_application_context_get_instance();
 
     if(strlen(application_context->argv[0]) > strlen("\\gsequencer.exe")){
@@ -1509,6 +1509,8 @@
 #else
     license_filename = g_strdup("/usr/share/common-licenses/GPL-3");
 #endif
+  }else{
+    license_filename = g_strdup(license_filename);
   }
 #endif
   
@@ -1516,23 +1518,26 @@
                 G_FILE_TEST_EXISTS)){
     if(file == NULL){
       file = fopen(license_filename, "r");
-      stat(license_filename, &sb);
-      license = (gchar *) malloc((sb.st_size + 1) * sizeof(gchar));
 
-      n_read = fread(license, sizeof(char), sb.st_size, file);
+      if(file != NULL){
+       stat(license_filename, &sb);
+       license = (gchar *) malloc((sb.st_size + 1) * sizeof(gchar));
+
+       n_read = fread(license, sizeof(char), sb.st_size, file);
 
-      if(n_read != sb.st_size){
-       g_critical("fread() number of bytes returned doesn't match buffer 
size");
+       if(n_read != sb.st_size){
+         g_critical("fread() number of bytes returned doesn't match buffer 
size");
+       }
+      
+       license[sb.st_size] = '\0';
+       fclose(file);
       }
       
-      license[sb.st_size] = '\0';
-      fclose(file);
-
 #ifdef AGS_LOGO_FILENAME
       logo_filename = g_strdup(AGS_LOGO_FILENAME);
 #else
       if((logo_filename = getenv("AGS_LOGO_FILENAME")) == NULL){
-#if defined AGS_W32API
+#if defined(AGS_W32API)
        logo_filename = 
g_strdup_printf("%s\\share\\gsequencer\\images\\ags.png",
                                      g_get_current_dir());
     
@@ -1589,10 +1594,4 @@
                        "title", "Advanced Gtk+ Sequencer",
                        "logo", logo,
                        NULL);
-
-  g_free(license_filename);
-
-#if defined AGS_W32API
-  g_free(app_dir);
-#endif
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/X/machine/ags_ffplayer.c 
new/gsequencer-2.4.4/ags/X/machine/ags_ffplayer.c
--- old/gsequencer-2.4.1/ags/X/machine/ags_ffplayer.c   2019-11-28 
04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/X/machine/ags_ffplayer.c   2019-12-17 
09:43:03.000000000 +0100
@@ -458,9 +458,15 @@
 void
 ags_ffplayer_finalize(GObject *gobject)
 {
+  g_hash_table_remove(ags_ffplayer_sf2_loader_completed,
+                     gobject);
+
   g_hash_table_remove(ags_machine_generic_output_message_monitor,
                      gobject);
 
+  g_hash_table_remove(ags_machine_generic_input_message_monitor,
+                     gobject);
+
   /* call parent */
   G_OBJECT_CLASS(ags_ffplayer_parent_class)->finalize(gobject);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/X/machine/ags_ffplayer_bulk_input.c 
new/gsequencer-2.4.4/ags/X/machine/ags_ffplayer_bulk_input.c
--- old/gsequencer-2.4.1/ags/X/machine/ags_ffplayer_bulk_input.c        
2019-09-17 15:54:48.000000000 +0200
+++ new/gsequencer-2.4.4/ags/X/machine/ags_ffplayer_bulk_input.c        
2019-12-17 09:56:33.000000000 +0100
@@ -128,7 +128,7 @@
 void
 ags_ffplayer_bulk_input_init(AgsFFPlayerBulkInput *ffplayer_bulk_input)
 {
-  //TODO:JK: implement me
+  AGS_EFFECT_BULK(ffplayer_bulk_input)->channel_type = AGS_TYPE_INPUT;
 }
 
 void
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/X/machine/ags_pitch_sampler.c 
new/gsequencer-2.4.4/ags/X/machine/ags_pitch_sampler.c
--- old/gsequencer-2.4.1/ags/X/machine/ags_pitch_sampler.c      2019-11-28 
04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/X/machine/ags_pitch_sampler.c      2019-12-17 
09:43:03.000000000 +0100
@@ -446,6 +446,9 @@
 void
 ags_pitch_sampler_finalize(GObject *gobject)
 {
+  g_hash_table_remove(ags_pitch_sampler_sfz_loader_completed,
+                     gobject);
+  
   g_hash_table_remove(ags_machine_generic_output_message_monitor,
                      gobject);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/X/machine/ags_spectrometer.c 
new/gsequencer-2.4.4/ags/X/machine/ags_spectrometer.c
--- old/gsequencer-2.4.1/ags/X/machine/ags_spectrometer.c       2019-11-28 
04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/X/machine/ags_spectrometer.c       2019-12-17 
09:43:03.000000000 +0100
@@ -378,13 +378,13 @@
   spectrometer = AGS_SPECTROMETER(connectable);
 
   g_object_disconnect(spectrometer,
-                     "resize-audio-channels",
+                     "any_signal::resize-audio-channels",
                      
G_CALLBACK(ags_spectrometer_resize_audio_channels_callback),
                      NULL,
                      NULL);
 
   g_object_disconnect(spectrometer,
-                     "resize-pads",
+                     "any_signal::resize-pads",
                      G_CALLBACK(ags_spectrometer_resize_pads_callback),
                      NULL,
                      NULL);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/audio/thread/ags_audio_loop.c 
new/gsequencer-2.4.4/ags/audio/thread/ags_audio_loop.c
--- old/gsequencer-2.4.1/ags/audio/thread/ags_audio_loop.c      2019-11-28 
05:48:39.000000000 +0100
+++ new/gsequencer-2.4.4/ags/audio/thread/ags_audio_loop.c      2019-12-17 
09:43:05.000000000 +0100
@@ -1010,11 +1010,29 @@
   /* real-time setup */
   if((AGS_THREAD_RT_SETUP & (g_atomic_int_get(&(thread->flags)))) == 0){
 #ifdef AGS_WITH_RT
+    AgsPriority *priority;
+
     struct sched_param param;
+
+    gchar *str;
+    
+    priority = ags_priority_get_instance();
     
     /* Declare ourself as a real time task */
     param.sched_priority = AGS_RT_PRIORITY;
       
+    str = ags_priority_get_value(priority,
+                                AGS_PRIORITY_RT_THREAD,
+                                "default");
+
+    if(str != NULL){
+      param.sched_priority = (int) g_ascii_strtoull(str,
+                                                   NULL,
+                                                   10);
+
+      g_free(str);
+    }
+      
     if(sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
       perror("sched_setscheduler failed");
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/audio/thread/ags_audio_thread.c 
new/gsequencer-2.4.4/ags/audio/thread/ags_audio_thread.c
--- old/gsequencer-2.4.1/ags/audio/thread/ags_audio_thread.c    2019-11-28 
04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/audio/thread/ags_audio_thread.c    2019-12-17 
09:43:05.000000000 +0100
@@ -458,10 +458,28 @@
 
 #ifdef AGS_WITH_RT
   if((AGS_THREAD_RT_SETUP & (g_atomic_int_get(&(thread->flags)))) == 0){
+    AgsPriority *priority;
+
     struct sched_param param;
+
+    gchar *str;
+    
+    priority = ags_priority_get_instance();
     
     /* Declare ourself as a real time task */
     param.sched_priority = AGS_RT_PRIORITY;
+
+    str = ags_priority_get_value(priority,
+                                AGS_PRIORITY_RT_THREAD,
+                                "default");
+
+    if(str != NULL){
+      param.sched_priority = (int) g_ascii_strtoull(str,
+                                                   NULL,
+                                                   10);
+
+      g_free(str);
+    }
       
     if(sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
       perror("sched_setscheduler failed");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/audio/thread/ags_channel_thread.c 
new/gsequencer-2.4.4/ags/audio/thread/ags_channel_thread.c
--- old/gsequencer-2.4.1/ags/audio/thread/ags_channel_thread.c  2019-11-28 
04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/audio/thread/ags_channel_thread.c  2019-12-17 
09:43:05.000000000 +0100
@@ -444,11 +444,29 @@
 
 #ifdef AGS_WITH_RT
   if((AGS_THREAD_RT_SETUP & (g_atomic_int_get(&(thread->flags)))) == 0){
+    AgsPriority *priority;
+
     struct sched_param param;
+
+    gchar *str;
+    
+    priority = ags_priority_get_instance();
     
     /* Declare ourself as a real time task */
     param.sched_priority = AGS_RT_PRIORITY;
       
+    str = ags_priority_get_value(priority,
+                                AGS_PRIORITY_RT_THREAD,
+                                "default");
+
+    if(str != NULL){
+      param.sched_priority = (int) g_ascii_strtoull(str,
+                                                   NULL,
+                                                   10);
+
+      g_free(str);
+    }
+
     if(sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
       perror("sched_setscheduler failed");
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/audio/thread/ags_sequencer_thread.c 
new/gsequencer-2.4.4/ags/audio/thread/ags_sequencer_thread.c
--- old/gsequencer-2.4.1/ags/audio/thread/ags_sequencer_thread.c        
2019-11-28 04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/audio/thread/ags_sequencer_thread.c        
2019-12-17 09:43:05.000000000 +0100
@@ -420,10 +420,28 @@
   /* real-time setup */
 #ifdef AGS_WITH_RT
   if((AGS_THREAD_RT_SETUP & (g_atomic_int_get(&(thread->flags)))) == 0){
+    AgsPriority *priority;
+
     struct sched_param param;
+
+    gchar *str;
     
+    priority = ags_priority_get_instance();    
+        
     /* Declare ourself as a real time task */
     param.sched_priority = AGS_RT_PRIORITY;
+
+    str = ags_priority_get_value(priority,
+                                AGS_PRIORITY_RT_THREAD,
+                                "default");
+
+    if(str != NULL){
+      param.sched_priority = (int) g_ascii_strtoull(str,
+                                                   NULL,
+                                                   10);
+
+      g_free(str);
+    }
       
     if(sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
       perror("sched_setscheduler failed");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/audio/thread/ags_soundcard_thread.c 
new/gsequencer-2.4.4/ags/audio/thread/ags_soundcard_thread.c
--- old/gsequencer-2.4.1/ags/audio/thread/ags_soundcard_thread.c        
2019-11-28 04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/audio/thread/ags_soundcard_thread.c        
2019-12-17 09:43:05.000000000 +0100
@@ -477,10 +477,28 @@
   /* real-time setup */
 #ifdef AGS_WITH_RT
   if((AGS_THREAD_RT_SETUP & (g_atomic_int_get(&(thread->flags)))) == 0){
+    AgsPriority *priority;
+
     struct sched_param param;
+
+    gchar *str;
+    
+    priority = ags_priority_get_instance();    
     
     /* Declare ourself as a real time task */
     param.sched_priority = AGS_RT_PRIORITY;
+
+    str = ags_priority_get_value(priority,
+                                AGS_PRIORITY_RT_THREAD,
+                                "default");
+
+    if(str != NULL){
+      param.sched_priority = (int) g_ascii_strtoull(str,
+                                                   NULL,
+                                                   10);
+
+      g_free(str);
+    }
       
     if(sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
       perror("sched_setscheduler failed");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/gsequencer_main.c 
new/gsequencer-2.4.4/ags/gsequencer_main.c
--- old/gsequencer-2.4.1/ags/gsequencer_main.c  2019-11-28 04:28:49.000000000 
+0100
+++ new/gsequencer-2.4.4/ags/gsequencer_main.c  2019-12-17 09:43:05.000000000 
+0100
@@ -239,13 +239,16 @@
 main(int argc, char **argv)
 {  
   AgsConfig *config;
-
+  AgsPriority *priority;
+  
   gchar *filename;
+  gchar *priority_filename;
 #if defined AGS_W32API
   gchar *app_dir;
   gchar *path;
 #endif
-
+  gchar *str;
+  
   gboolean single_thread_enabled;
   gboolean builtin_theme_disabled;
   guint i;
@@ -266,7 +269,7 @@
 
   gboolean has_file;
   int result;
-
+  
 #ifdef AGS_WITH_RT
   const rlim_t kStackSize = 64L * 1024L * 1024L;   // min stack size = 64 Mb
 #endif
@@ -279,7 +282,26 @@
   builtin_theme_disabled = FALSE;
 
   config = NULL;
+  priority = ags_priority_get_instance();
   
+#if defined (AGS_W32API)
+#else
+  uid = getuid();
+  pw = getpwuid(uid);
+
+  wdir = g_strdup_printf("%s/%s",
+                        pw->pw_dir,
+                        AGS_DEFAULT_DIRECTORY);
+    
+  priority_filename = g_strdup_printf("%s/priority.conf",
+                                     wdir);
+
+  ags_priority_load_from_file(priority,
+                             priority_filename);
+
+  g_free(priority_filename);
+  g_free(wdir);
+#endif
   //  mtrace();
 
 #ifdef AGS_WITH_RT
@@ -298,7 +320,19 @@
   }
 
   param.sched_priority = GSEQUENCER_RT_PRIORITY;
-      
+
+  str = ags_priority_get_value(priority,
+                              AGS_PRIORITY_RT_THREAD,
+                              "gsequencer");
+
+  if(str != NULL){
+    param.sched_priority = (int) g_ascii_strtoull(str,
+                                                 NULL,
+                                                 10);
+
+    g_free(str);
+  }
+  
   if(sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
     perror("sched_setscheduler failed");
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/libags.h new/gsequencer-2.4.4/ags/libags.h
--- old/gsequencer-2.4.1/ags/libags.h   2019-11-28 05:47:16.000000000 +0100
+++ new/gsequencer-2.4.4/ags/libags.h   2019-12-17 09:43:05.000000000 +0100
@@ -54,6 +54,7 @@
 #include <ags/object/ags_mutable.h>
 #include <ags/object/ags_plugin.h>
 #include <ags/object/ags_portlet.h>
+#include <ags/object/ags_priority.h>
 #include <ags/object/ags_seekable.h>
 #include <ags/object/ags_sequencer.h>
 #include <ags/object/ags_soundcard.h>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/object/ags_config.c 
new/gsequencer-2.4.4/ags/object/ags_config.c
--- old/gsequencer-2.4.1/ags/object/ags_config.c        2019-11-28 
04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/object/ags_config.c        2019-12-17 
09:43:06.000000000 +0100
@@ -1105,4 +1105,3 @@
 
   return(config);
 }
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/object/ags_priority.c 
new/gsequencer-2.4.4/ags/object/ags_priority.c
--- old/gsequencer-2.4.1/ags/object/ags_priority.c      1970-01-01 
01:00:00.000000000 +0100
+++ new/gsequencer-2.4.4/ags/object/ags_priority.c      2019-12-17 
09:43:06.000000000 +0100
@@ -0,0 +1,685 @@
+/* GSequencer - Advanced GTK Sequencer
+ * Copyright (C) 2005-2019 Joël Krähemann
+ *
+ * This file is part of GSequencer.
+ *
+ * GSequencer is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSequencer 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSequencer.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <ags/object/ags_priority.h>
+
+#include <ags/object/ags_marshal.h>
+
+#include <gio/gio.h>
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifndef AGS_W32API
+#include <pwd.h>
+#endif
+
+#include <ags/config.h>
+#include <ags/i18n.h>
+
+void ags_priority_class_init(AgsPriorityClass *priority_class);
+void ags_priority_init(AgsPriority *priority);
+void ags_priority_set_property(GObject *gobject,
+                              guint prop_id,
+                              const GValue *value,
+                              GParamSpec *param_spec);
+void ags_priority_get_property(GObject *gobject,
+                              guint prop_id,
+                              GValue *value,
+                              GParamSpec *param_spec);
+void ags_priority_dispose(GObject *gobject);
+void ags_priority_finalize(GObject *gobject);
+
+gchar* ags_priority_get_version(AgsPriority *priority);
+void ags_priority_set_version(AgsPriority *priority, gchar *version);
+gchar* ags_priority_get_build_id(AgsPriority *priority);
+void ags_priority_set_build_id(AgsPriority *priority, gchar *build_id);
+
+void ags_priority_real_load_defaults(AgsPriority *priority);
+void ags_priority_real_set_value(AgsPriority *priority, gchar *group, gchar 
*key, gchar *value);
+gchar* ags_priority_real_get_value(AgsPriority *priority, gchar *group, gchar 
*key);
+
+/**
+ * SECTION:ags_priority
+ * @short_description: Priority Advanced Gtk+ Sequencer
+ * @title: AgsPriority
+ * @section_id:
+ * @include: ags/object/ags_priority.h
+ *
+ * #AgsPriority provides priorities to Advanced Gtk+ Sequencer.
+ */
+
+enum{
+  LOAD_DEFAULTS,
+  SET_VALUE,
+  GET_VALUE,
+  LAST_SIGNAL,
+};
+
+enum{
+  PROP_0,
+};
+
+static gpointer ags_priority_parent_class = NULL;
+static guint priority_signals[LAST_SIGNAL];
+
+AgsPriority *ags_priority = NULL;
+
+static pthread_mutex_t ags_priority_class_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+GType
+ags_priority_get_type (void)
+{
+  static volatile gsize g_define_type_id__volatile = 0;
+
+  if(g_once_init_enter (&g_define_type_id__volatile)){
+    GType ags_type_priority = 0;
+
+    static const GTypeInfo ags_priority_info = {
+      sizeof (AgsPriorityClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) ags_priority_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (AgsPriority),
+      0,    /* n_preallocs */
+      (GInstanceInitFunc) ags_priority_init,
+    };
+
+    ags_type_priority = g_type_register_static(G_TYPE_OBJECT,
+                                              "AgsPriority",
+                                              &ags_priority_info,
+                                              0);
+
+    g_once_init_leave(&g_define_type_id__volatile, ags_type_priority);
+  }
+
+  return g_define_type_id__volatile;
+}
+
+void
+ags_priority_class_init(AgsPriorityClass *priority)
+{
+  GObjectClass *gobject;
+  GParamSpec *param_spec;
+
+  ags_priority_parent_class = g_type_class_peek_parent(priority);
+
+  /* GObjectClass */
+  gobject = (GObjectClass *) priority;
+
+  gobject->set_property = ags_priority_set_property;
+  gobject->get_property = ags_priority_get_property;
+
+  gobject->dispose = ags_priority_dispose;
+  gobject->finalize = ags_priority_finalize;
+
+  /* properties */
+
+  /* AgsPriorityClass */
+  priority->load_defaults = ags_priority_real_load_defaults;
+  priority->set_value = ags_priority_real_set_value;
+  priority->get_value = ags_priority_real_get_value;
+
+  /* signals */
+  /**
+   * AgsPriority::load-defaults:
+   * @priority: the object to resolve
+   *
+   * The ::load-defaults signal notifies about loading defaults
+   *
+   * Since: 2.4.2
+   */
+  priority_signals[LOAD_DEFAULTS] =
+    g_signal_new("load-defaults",
+                G_TYPE_FROM_CLASS (priority),
+                G_SIGNAL_RUN_LAST,
+                G_STRUCT_OFFSET (AgsPriorityClass, load_defaults),
+                NULL, NULL,
+                g_cclosure_marshal_VOID__VOID,
+                G_TYPE_NONE, 0);
+
+
+  /**
+   * AgsPriority::set-value:
+   * @priority: the object to resolve
+   * @group: the group to apply to
+   * @key: the key to set
+   * @value: the value to apply
+   *
+   * The ::set-value signal notifies about value been setting.
+   *
+   * Since: 2.4.2
+   */
+  priority_signals[SET_VALUE] =
+    g_signal_new("set-value",
+                G_TYPE_FROM_CLASS (priority),
+                G_SIGNAL_RUN_LAST,
+                G_STRUCT_OFFSET (AgsPriorityClass, set_value),
+                NULL, NULL,
+                ags_cclosure_marshal_VOID__STRING_STRING_STRING,
+                G_TYPE_NONE, 3,
+                G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+  /**
+   * AgsPriority::get-value:
+   * @priority: the object to resolve
+   * @group: the group to retrieve from
+   * @key: the key to get
+   *
+   * The ::get-value signal notifies about value been getting.
+   *
+   * Returns: the value
+   *
+   * Since: 2.4.2
+   */
+  priority_signals[GET_VALUE] =
+    g_signal_new("get-value",
+                G_TYPE_FROM_CLASS (priority),
+                G_SIGNAL_RUN_LAST,
+                G_STRUCT_OFFSET (AgsPriorityClass, get_value),
+                NULL, NULL,
+                ags_cclosure_marshal_STRING__STRING_STRING,
+                G_TYPE_STRING, 2,
+                G_TYPE_STRING, G_TYPE_STRING);
+}
+
+void
+ags_priority_init(AgsPriority *priority)
+{
+  priority->flags = 0;
+  
+  priority->obj_mutexattr = (pthread_mutexattr_t *) 
malloc(sizeof(pthread_mutexattr_t));
+
+  pthread_mutexattr_init(priority->obj_mutexattr);
+  pthread_mutexattr_settype(priority->obj_mutexattr,
+                           PTHREAD_MUTEX_RECURSIVE);
+
+#ifdef __linux__
+  pthread_mutexattr_setprotocol(priority->obj_mutexattr,
+                               PTHREAD_PRIO_INHERIT);
+#endif
+
+  
+  priority->obj_mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
+  pthread_mutex_init(priority->obj_mutex, priority->obj_mutexattr);
+
+  /* version and build id */
+  priority->version = g_strdup(AGS_PRIORITY_DEFAULT_VERSION);
+  priority->build_id = g_strdup(AGS_PRIORITY_DEFAULT_BUILD_ID);
+
+  priority->key_file = g_key_file_new();
+  g_key_file_ref(priority->key_file);
+}
+
+void
+ags_priority_set_property(GObject *gobject,
+                         guint prop_id,
+                         const GValue *value,
+                         GParamSpec *param_spec)
+{
+  AgsPriority *priority;
+
+  pthread_mutex_t *priority_mutex;
+
+  priority = AGS_PRIORITY(gobject);
+
+  /* get priority mutex */
+  priority_mutex = AGS_PRIORITY_GET_OBJ_MUTEX(priority);
+
+  switch(prop_id){
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+    break;
+  }
+}
+
+void
+ags_priority_get_property(GObject *gobject,
+                         guint prop_id,
+                         GValue *value,
+                         GParamSpec *param_spec)
+{
+  AgsPriority *priority;
+
+  pthread_mutex_t *priority_mutex;
+
+  priority = AGS_PRIORITY(gobject);
+
+  /* get priority mutex */
+  priority_mutex = AGS_PRIORITY_GET_OBJ_MUTEX(priority);
+  
+  switch(prop_id){
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+    break;
+  }
+}
+void
+ags_priority_dispose(GObject *gobject)
+{
+  AgsPriority *priority;
+
+  priority = (AgsPriority *) gobject;
+
+  /* call parent */
+  G_OBJECT_CLASS(ags_priority_parent_class)->dispose(gobject);
+}
+
+void
+ags_priority_finalize(GObject *gobject)
+{
+  AgsPriority *priority;
+
+  priority = (AgsPriority *) gobject;
+
+  /* priority mutex */
+  pthread_mutexattr_destroy(priority->obj_mutexattr);
+  free(priority->obj_mutexattr);
+
+  pthread_mutex_destroy(priority->obj_mutex);
+  free(priority->obj_mutex);
+
+  /* key file */
+  if(priority->key_file != NULL){
+    g_key_file_unref(priority->key_file);
+  }
+
+  /* global variable */
+  if(ags_priority == priority){
+    ags_priority = NULL;
+  }
+
+  /* call parent */
+  G_OBJECT_CLASS(ags_priority_parent_class)->finalize(gobject);
+}
+
+gchar*
+ags_priority_get_version(AgsPriority *priority)
+{
+  gchar *version;
+  
+  pthread_mutex_t *priority_mutex;
+
+  if(!AGS_IS_PRIORITY(priority)){
+    return(NULL);
+  }
+  
+  priority_mutex = AGS_PRIORITY_GET_OBJ_MUTEX(priority);
+
+  /* get version */
+  pthread_mutex_lock(priority_mutex);
+
+  version = priority->version;
+  
+  pthread_mutex_unlock(priority_mutex);
+
+  return(version);
+}
+
+void
+ags_priority_set_version(AgsPriority *priority, gchar *version)
+{
+  pthread_mutex_t *priority_mutex;
+
+  if(!AGS_IS_PRIORITY(priority)){
+    return;
+  }
+  
+  priority_mutex = AGS_PRIORITY_GET_OBJ_MUTEX(priority);
+
+  /* set version */
+  pthread_mutex_lock(priority_mutex);
+
+  priority->version = g_strdup(version);
+  
+  pthread_mutex_unlock(priority_mutex);
+}
+
+gchar*
+ags_priority_get_build_id(AgsPriority *priority)
+{
+  gchar *build_id;
+  
+  pthread_mutex_t *priority_mutex;
+
+  if(!AGS_IS_PRIORITY(priority)){
+    return(NULL);
+  }
+  
+  priority_mutex = AGS_PRIORITY_GET_OBJ_MUTEX(priority);
+
+  /* get build id */
+  pthread_mutex_lock(priority_mutex);
+
+  build_id = priority->build_id;
+  
+  pthread_mutex_unlock(priority_mutex);
+
+  return(build_id);
+}
+
+void
+ags_priority_set_build_id(AgsPriority *priority, gchar *build_id)
+{
+  pthread_mutex_t *priority_mutex;
+
+  if(!AGS_IS_PRIORITY(priority)){
+    return;
+  }
+  
+  priority_mutex = AGS_PRIORITY_GET_OBJ_MUTEX(priority);
+
+  /* set version */
+  pthread_mutex_lock(priority_mutex);
+
+  priority->build_id = g_strdup(build_id);
+  
+  pthread_mutex_unlock(priority_mutex);
+}
+
+/**
+ * ags_priority_get_class_mutex:
+ * 
+ * Use this function's returned mutex to access mutex fields.
+ *
+ * Returns: the class mutex
+ * 
+ * Since: 2.4.2
+ */
+pthread_mutex_t*
+ags_priority_get_class_mutex()
+{
+  return(&ags_priority_class_mutex);
+}
+
+void
+ags_priority_real_load_defaults(AgsPriority *priority)
+{
+
+  pthread_mutex_t *priority_mutex;
+  
+  priority_mutex = AGS_PRIORITY_GET_OBJ_MUTEX(priority);
+
+  /* load defaults */
+  pthread_mutex_lock(priority_mutex);
+
+  ags_priority_set_value(priority, AGS_PRIORITY_RT_THREAD, "gsequencer", "95");
+  ags_priority_set_value(priority, AGS_PRIORITY_RT_THREAD, "default", "45");
+  ags_priority_set_value(priority, AGS_PRIORITY_RT_THREAD, "polling-thread", 
"95");
+  ags_priority_set_value(priority, AGS_PRIORITY_RT_THREAD, "thread-pool", 
"99");
+  ags_priority_set_value(priority, AGS_PRIORITY_RT_THREAD, "task-thread", 
"95");
+
+  pthread_mutex_unlock(priority_mutex);
+}
+
+/**
+ * ags_priority_load_defaults:
+ * @priority: the #AgsPriority
+ *
+ * Load priorities from default values.
+ *
+ * Since: 2.4.2
+ */
+void
+ags_priority_load_defaults(AgsPriority *priority)
+{
+  g_return_if_fail(AGS_IS_PRIORITY(priority));
+
+  g_object_ref(G_OBJECT(priority));
+  g_signal_emit(G_OBJECT(priority),
+               priority_signals[LOAD_DEFAULTS], 0);
+  g_object_unref(G_OBJECT(priority));
+}
+
+/**
+ * ags_priority_load_from_file:
+ * @priority: the #AgsPriority
+ * @filename: the priorityuration file
+ *
+ * Load priorities from @filename.
+ *
+ * Since: 2.4.2
+ */
+void
+ags_priority_load_from_file(AgsPriority *priority, gchar *filename)
+{
+  GFile *file;
+
+  pthread_mutex_t *priority_mutex;
+
+  if(!AGS_IS_PRIORITY(priority)){
+    return;
+  }
+  
+  priority_mutex = AGS_PRIORITY_GET_OBJ_MUTEX(priority);
+
+  file = g_file_new_for_path(filename);
+
+  g_message("loading priorities for: %s", filename);
+
+  if(!g_file_query_exists(file,
+                         NULL)){
+    ags_priority_load_defaults(priority);
+  }else{
+    GKeyFile *key_file;
+
+    gchar **groups, **groups_start;
+    gchar **keys, **keys_start;
+    gchar *value;
+
+    GError *error;
+
+    pthread_mutex_lock(priority_mutex);
+
+    error = NULL;
+    
+    key_file = g_key_file_new();
+    g_key_file_load_from_file(key_file,
+                             filename,
+                             G_KEY_FILE_NONE,
+                             &error);
+
+    if(error != NULL){
+      g_warning("%s", error->message);
+
+      g_error_free(error);
+    }
+
+    groups =
+      groups_start = g_key_file_get_groups(key_file,
+                                          NULL);
+
+    while(*groups != NULL){
+      keys =
+       keys_start = g_key_file_get_keys(key_file,
+                                        *groups,
+                                        NULL,
+                                        NULL);
+
+      while(*keys != NULL){
+       value = g_key_file_get_value(key_file,
+                                    *groups,
+                                    *keys,
+                                    NULL);
+       ags_priority_set_value(priority,
+                              *groups,
+                              *keys,
+                              value);
+       
+       keys++;
+      }
+
+      g_strfreev(keys_start);
+
+      groups++;
+    }
+
+    g_strfreev(groups_start);
+    g_key_file_unref(key_file);
+
+    pthread_mutex_unlock(priority_mutex);
+  }
+
+  g_object_unref(file);
+}
+
+
+void
+ags_priority_real_set_value(AgsPriority *priority, gchar *group, gchar *key, 
gchar *value)
+{
+  pthread_mutex_t *priority_mutex;
+  
+  priority_mutex = AGS_PRIORITY_GET_OBJ_MUTEX(priority);
+
+  /* set value */
+  pthread_mutex_lock(priority_mutex);
+  
+  g_key_file_set_value(priority->key_file, group, key, value);
+
+  pthread_mutex_unlock(priority_mutex);
+}
+
+/**
+ * ags_priority_set_value:
+ * @priority: the #AgsPriority
+ * @group: the priority group identifier
+ * @key: the key of the property
+ * @value: the value to set
+ *
+ * Set priority by @group and @key, applying @value.
+ *
+ * Since: 2.4.2
+ */
+void
+ags_priority_set_value(AgsPriority *priority, gchar *group, gchar *key, gchar 
*value)
+{
+  g_return_if_fail(AGS_IS_PRIORITY(priority));
+
+  g_object_ref(G_OBJECT(priority));
+  g_signal_emit(G_OBJECT(priority),
+               priority_signals[SET_VALUE], 0,
+               group, key, value);
+  g_object_unref(G_OBJECT(priority));
+}
+
+gchar*
+ags_priority_real_get_value(AgsPriority *priority, gchar *group, gchar *key)
+{
+  gchar *str;
+  GError *error;
+  
+  pthread_mutex_t *priority_mutex;
+  
+  priority_mutex = AGS_PRIORITY_GET_OBJ_MUTEX(priority);
+
+  /* get value */
+  pthread_mutex_lock(priority_mutex);
+  
+  error = NULL;
+
+  str = g_key_file_get_value(priority->key_file, group, key, &error);
+
+  if(error != NULL){
+//    g_warning("%s", error->message);
+    
+    g_error_free(error);
+  }
+  
+  pthread_mutex_unlock(priority_mutex);
+
+  return(str);
+}
+
+/**
+ * ags_priority_get_value:
+ * @priority: the #AgsPriority
+ * @group: the priority group identifier
+ * @key: the key of the property
+ *
+ * Retrieve priority by @group and @key.
+ *
+ * Returns: the property's value
+ *
+ * Since: 2.4.2
+ */
+gchar*
+ags_priority_get_value(AgsPriority *priority, gchar *group, gchar *key)
+{
+  gchar *value;
+
+  g_return_val_if_fail(AGS_IS_PRIORITY(priority), NULL);
+
+  g_object_ref(G_OBJECT(priority));
+  g_signal_emit(G_OBJECT(priority),
+               priority_signals[GET_VALUE], 0,
+               group, key,
+               &value);
+  g_object_unref(G_OBJECT(priority));
+
+  return(value);
+}
+
+/**
+ * ags_priority_get_instance:
+ *
+ * Get priority instance.
+ *
+ * Returns: the priority instance
+ *
+ * Since: 2.4.2
+ */
+AgsPriority*
+ags_priority_get_instance()
+{
+  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+  pthread_mutex_lock(&mutex);
+
+  if(ags_priority == NULL){
+    ags_priority = ags_priority_new(NULL);
+  }
+
+  pthread_mutex_unlock(&mutex);
+
+  return(ags_priority);
+}
+
+/**
+ * ags_priority_new:
+ *
+ * Create a new instance of #AgsPriority.
+ *
+ * Returns: the new #AgsPriority.
+ *
+ * Since: 2.4.2
+ */
+AgsPriority*
+ags_priority_new()
+{
+  AgsPriority *priority;
+
+  priority = (AgsPriority *) g_object_new(AGS_TYPE_PRIORITY,
+                                         NULL);
+
+  return(priority);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/object/ags_priority.h 
new/gsequencer-2.4.4/ags/object/ags_priority.h
--- old/gsequencer-2.4.1/ags/object/ags_priority.h      1970-01-01 
01:00:00.000000000 +0100
+++ new/gsequencer-2.4.4/ags/object/ags_priority.h      2019-12-17 
09:43:06.000000000 +0100
@@ -0,0 +1,94 @@
+/* GSequencer - Advanced GTK Sequencer
+ * Copyright (C) 2005-2019 Joël Krähemann
+ *
+ * This file is part of GSequencer.
+ *
+ * GSequencer is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GSequencer 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GSequencer.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __AGS_PRIORITY_H__
+#define __AGS_PRIORITY_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <pthread.h>
+
+#define AGS_TYPE_PRIORITY                (ags_priority_get_type ())
+#define AGS_PRIORITY(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), 
AGS_TYPE_PRIORITY, AgsPriority))
+#define AGS_PRIORITY_CLASS(class)        (G_TYPE_CHECK_CLASS_CAST((class), 
AGS_TYPE_PRIORITY, AgsPriorityClass))
+#define AGS_IS_PRIORITY(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj), 
AGS_TYPE_PRIORITY))
+#define AGS_IS_PRIORITY_CLASS(class)     (G_TYPE_CHECK_CLASS_TYPE((class), 
AGS_TYPE_PRIORITY))
+#define AGS_PRIORITY_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS((obj), 
AGS_TYPE_PRIORITY, AgsPriorityClass))
+
+#define AGS_PRIORITY_GET_OBJ_MUTEX(obj) (((AgsPriority *) obj)->obj_mutex)
+
+#define AGS_PRIORITY_DEFAULT_VERSION "2.4.2"
+#define AGS_PRIORITY_DEFAULT_BUILD_ID "Mon Dec  2 08:15:02 UTC 2019"
+
+#define AGS_PRIORITY_RT_THREAD "rt-thread"
+
+typedef struct _AgsPriority AgsPriority;
+typedef struct _AgsPriorityClass AgsPriorityClass;
+
+/**
+ * AgsPriorityFlags:
+ * @AGS_PRIORITY_CONNECTED: the priority was connected by calling 
#AgsConnectable::connect()
+ * 
+ * Enum values to control the behavior or indicate internal state of 
#AgsPriority by
+ * enable/disable as flags.
+ */
+typedef enum{
+  AGS_PRIORITY_CONNECTED    = 1,
+}AgsPriorityFlags;
+
+struct _AgsPriority
+{
+  GObject gobject;
+
+  guint flags;
+
+  pthread_mutex_t *obj_mutex;
+  pthread_mutexattr_t *obj_mutexattr;
+  
+  gchar *version;
+  gchar *build_id;
+
+  GKeyFile *key_file;
+};
+
+struct _AgsPriorityClass
+{
+  GObjectClass gobject;
+
+  void (*load_defaults)(AgsPriority *priority);
+
+  void (*set_value)(AgsPriority *priority, gchar *group, gchar *key, gchar 
*value);
+  gchar* (*get_value)(AgsPriority *priority, gchar *group, gchar *key);
+};
+
+GType ags_priority_get_type();
+
+pthread_mutex_t* ags_priority_get_class_mutex();
+
+void ags_priority_load_defaults(AgsPriority *priority);
+void ags_priority_load_from_file(AgsPriority *priority, gchar *filename);
+
+void ags_priority_set_value(AgsPriority *priority, gchar *group, gchar *key, 
gchar *value);
+gchar* ags_priority_get_value(AgsPriority *priority, gchar *group, gchar *key);
+
+AgsPriority* ags_priority_get_instance();
+AgsPriority* ags_priority_new();
+
+#endif /*__AGS_PRIORITY_H__*/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/thread/ags_polling_thread.c 
new/gsequencer-2.4.4/ags/thread/ags_polling_thread.c
--- old/gsequencer-2.4.1/ags/thread/ags_polling_thread.c        2019-11-28 
04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/thread/ags_polling_thread.c        2019-12-17 
09:43:06.000000000 +0100
@@ -20,6 +20,7 @@
 #include <ags/thread/ags_polling_thread.h>
 
 #include <ags/object/ags_connectable.h>
+#include <ags/object/ags_priority.h>
 
 #include <ags/thread/ags_poll_fd.h>
 
@@ -216,10 +217,28 @@
   /* real-time setup */
 #ifdef AGS_WITH_RT
   if((AGS_THREAD_RT_SETUP & (g_atomic_int_get(&(thread->flags)))) == 0){
+    AgsPriority *priority;
+
     struct sched_param param;
+
+    gchar *str;
+
+    priority = ags_priority_get_instance();
     
     /* Declare ourself as a real time task */
     param.sched_priority = AGS_POLLING_THREAD_RT_PRIORITY;
+
+    str = ags_priority_get_value(priority,
+                                AGS_PRIORITY_RT_THREAD,
+                                "polling-thread");
+
+    if(str != NULL){
+      param.sched_priority = (int) g_ascii_strtoull(str,
+                                                   NULL,
+                                                   10);
+
+      g_free(str);
+    }
       
     if(sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
       perror("sched_setscheduler failed");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/thread/ags_task_thread.c 
new/gsequencer-2.4.4/ags/thread/ags_task_thread.c
--- old/gsequencer-2.4.1/ags/thread/ags_task_thread.c   2019-11-28 
04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/thread/ags_task_thread.c   2019-12-17 
09:43:06.000000000 +0100
@@ -20,6 +20,7 @@
 #include <ags/thread/ags_task_thread.h>
 
 #include <ags/object/ags_connectable.h>
+#include <ags/object/ags_priority.h>
 #include <ags/object/ags_main_loop.h>
 #include <ags/object/ags_async_queue.h>
 
@@ -573,11 +574,29 @@
   /* real-time setup */
 #ifdef AGS_WITH_RT
   if((AGS_THREAD_RT_SETUP & (g_atomic_int_get(&(thread->flags)))) == 0){
+    AgsPriority *priority;
+
     struct sched_param param;
+
+    gchar *str;
+    
+    priority = ags_priority_get_instance();
     
     /* Declare ourself as a real time task */
     param.sched_priority = AGS_TASK_THREAD_RT_PRIORITY;
       
+    str = ags_priority_get_value(priority,
+                                AGS_PRIORITY_RT_THREAD,
+                                "task-thread");
+
+    if(str != NULL){
+      param.sched_priority = (int) g_ascii_strtoull(str,
+                                                   NULL,
+                                                   10);
+
+      g_free(str);
+    }
+      
     if(sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
       perror("sched_setscheduler failed");
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/ags/thread/ags_thread_pool.c 
new/gsequencer-2.4.4/ags/thread/ags_thread_pool.c
--- old/gsequencer-2.4.1/ags/thread/ags_thread_pool.c   2019-11-28 
04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/ags/thread/ags_thread_pool.c   2019-12-17 
09:43:06.000000000 +0100
@@ -21,6 +21,7 @@
 
 #include <ags/object/ags_connectable.h>
 #include <ags/object/ags_config.h>
+#include <ags/object/ags_priority.h>
 
 #include <ags/thread/ags_returnable_thread.h>
 
@@ -393,11 +394,29 @@
   /* real-time setup */
 #ifdef AGS_WITH_RT
   if((AGS_THREAD_POOL_RT_SETUP & (g_atomic_int_get(&(thread_pool->flags)))) == 
0){
+    AgsPriority *priority;
+
     struct sched_param param;
+
+    gchar *str;
     
+    priority = ags_priority_get_instance();
+
     /* Declare ourself as a real time task */
     param.sched_priority = AGS_THREAD_POOL_RT_PRIORITY;
       
+    str = ags_priority_get_value(priority,
+                                AGS_PRIORITY_RT_THREAD,
+                                "thread-pool");
+
+    if(str != NULL){
+      param.sched_priority = (int) g_ascii_strtoull(str,
+                                                   NULL,
+                                                   10);
+
+      g_free(str);
+    }
+
     if(sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
       perror("sched_setscheduler failed");
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/configure.ac new/gsequencer-2.4.4/configure.ac
--- old/gsequencer-2.4.1/configure.ac   2019-11-28 04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/configure.ac   2019-12-17 15:34:31.000000000 +0100
@@ -8,7 +8,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.69])
-AC_INIT([gsequencer],[2.4.1],[[email protected]])
+AC_INIT([gsequencer],[2.4.4],[[email protected]])
 AM_INIT_AUTOMAKE([subdir-objects])
 AC_CONFIG_SRCDIR([ags/config.h.in])
 AC_CONFIG_HEADERS([ags/config.h])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/libags.sym new/gsequencer-2.4.4/libags.sym
--- old/gsequencer-2.4.1/libags.sym     2019-11-28 06:07:19.000000000 +0100
+++ new/gsequencer-2.4.4/libags.sym     2019-12-17 15:37:11.000000000 +0100
@@ -321,6 +321,14 @@
 ags_application_context_quit
 ags_application_context_get_instance
 ags_application_context_new
+ags_priority_get_type
+ags_priority_get_class_mutex
+ags_priority_load_defaults
+ags_priority_load_from_file
+ags_priority_set_value
+ags_priority_get_value
+ags_priority_get_instance
+ags_priority_new
 ags_mutable_get_type
 ags_mutable_set_muted
 ags_plugin_get_type
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/libags.sym.in new/gsequencer-2.4.4/libags.sym.in
--- old/gsequencer-2.4.1/libags.sym.in  2019-11-28 04:28:49.000000000 +0100
+++ new/gsequencer-2.4.4/libags.sym.in  2019-12-17 09:43:06.000000000 +0100
@@ -339,6 +339,14 @@
 ags_application_context_quit
 ags_application_context_get_instance
 ags_application_context_new
+ags_priority_get_type
+ags_priority_get_class_mutex
+ags_priority_load_defaults
+ags_priority_load_from_file
+ags_priority_set_value
+ags_priority_get_value
+ags_priority_get_instance
+ags_priority_new
 ags_mutable_get_type
 ags_mutable_set_muted
 ags_plugin_get_type
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/gsequencer-2.4.1/org.nongnu.gsequencer.gsequencer.appdata.xml 
new/gsequencer-2.4.4/org.nongnu.gsequencer.gsequencer.appdata.xml
--- old/gsequencer-2.4.1/org.nongnu.gsequencer.gsequencer.appdata.xml   
2019-10-21 23:55:27.000000000 +0200
+++ new/gsequencer-2.4.4/org.nongnu.gsequencer.gsequencer.appdata.xml   
2019-12-17 15:34:15.000000000 +0100
@@ -35,6 +35,19 @@
   <url type="homepage">https://nongnu.org/gsequencer</url>
 
   <releases>
+    <release version="2.4.4" date="2019-12-17">
+      <description>
+       <p>Fixed potential SIGSEGV of AgsFFPlayer adding plugin.</p>
+       <p>Fixed accessing freed memory of AgsBulkMember.</p>
+      </description>
+    </release>
+
+    <release version="2.4.3" date="2019-12-07">
+      <description>
+       <p>Minor improvements.</p>
+      </description>
+    </release>
+    
     <release version="2.3.15" date="2019-10-20">
       <description>
        <p>Fixed AgsAudiorec open audio files with different samplerate.</p>


Reply via email to