changeset 232:e613873c3379

Thread locking now final. All parts, including GTK GUI, should be(?) properly locked and no race conditions should be present.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 21 Dec 2004 13:13:05 +0000
parents 9d7274a11fb1
children 9b5704548219
files src/xmms-sid.c src/xs_fileinfo.c src/xs_init.c src/xs_sidplay1.cc src/xs_sidplay2.cc src/xs_stil.c
diffstat 6 files changed, 182 insertions(+), 117 deletions(-) [+]
line wrap: on
line diff
--- a/src/xmms-sid.c	Tue Dec 21 13:12:04 2004 +0000
+++ b/src/xmms-sid.c	Tue Dec 21 13:13:05 2004 +0000
@@ -112,8 +112,14 @@
  gboolean isInitialized;
  
  /* Stop playing, if we are */
+ XS_MUTEX_LOCK(xs_status);
  if (xs_status.isPlaying)
+ 	{
+ 	XS_MUTEX_UNLOCK(xs_status);
 	xs_stop();
+	} else {
+	XS_MUTEX_UNLOCK(xs_status);
+	}
  
  /* Initialize status */
  xs_memset(&xs_status, 0, sizeof(xs_status));
@@ -201,7 +207,6 @@
 
  xs_tuneinfo_free(xs_status.tuneInfo);
  xs_status.tuneInfo = NULL;
- 
  xs_status.sidPlayer->plrDeleteSID(&xs_status);
  xs_status.sidPlayer->plrClose(&xs_status);
 
@@ -252,7 +257,7 @@
 /*
  * Main playing thread loop
  */
-void *xs_play_loop(void *argPointer)
+void *xs_playthread(void *argPointer)
 {
  t_xs_status myStatus;
  t_xs_tuneinfo *myTune;
@@ -268,7 +273,6 @@
  myTune = xs_status.tuneInfo;
  XS_MUTEX_UNLOCK(xs_status);
 
-
  /*
   * Main player loop: while not stopped, loop here - play subtunes
   */
@@ -278,22 +282,21 @@
  XS_MUTEX_LOCK(xs_status);
  myStatus.currSong = xs_status.currSong;
  XS_MUTEX_UNLOCK(xs_status);
- XS_MUTEX_LOCK(xs_subctrl);
- xs_subctrl_update();
- XS_MUTEX_UNLOCK(xs_subctrl);
 
  XSDEBUG("subtune #%i selected, initializing...\n", myStatus.currSong);
 
+ GDK_THREADS_ENTER(); 
+ xs_subctrl_update();
+ GDK_THREADS_LEAVE();
+
  songLength = myTune->subTunes[myStatus.currSong - 1].tuneLength;
  
  /* Check minimum playtime */
- XS_MUTEX_LOCK(xs_cfg);
  if (xs_cfg.playMinTimeEnable)
  	{
 	if (songLength < xs_cfg.playMinTime)
 		songLength = xs_cfg.playMinTime;
 	}
- XS_MUTEX_UNLOCK(xs_cfg);
 
  /* Initialize song */
  if (!myStatus.sidPlayer->plrInitSong(&myStatus))
@@ -304,15 +307,6 @@
 	}
 
 
- /* Get song information for current subtune */
- xs_plugin_ip.set_info(
- 	myTune->subTunes[myStatus.currSong - 1].tuneTitle,
- 	(songLength > 0) ? (songLength * 1000) : -1,
- 	(myTune->subTunes[myStatus.currSong - 1].tuneSpeed > 0) ? (myTune->subTunes[myStatus.currSong - 1].tuneSpeed * 1000) : -1,
-	myStatus.audioFrequency,
-	myStatus.audioChannels);
-
-
  /* Open the audio output */
  if (!xs_plugin_ip.output->open_audio(myStatus.audioFormat, myStatus.audioFrequency, myStatus.audioChannels))
 	{
@@ -327,6 +321,17 @@
 
  audioOpen = TRUE;
 
+ /* Set song information for current subtune */
+ xs_plugin_ip.set_info(
+ 	myTune->subTunes[myStatus.currSong - 1].tuneTitle,
+ 	(songLength > 0) ? (songLength * 1000) : -1,
+ 	(myTune->subTunes[myStatus.currSong - 1].tuneSpeed > 0) ? (myTune->subTunes[myStatus.currSong - 1].tuneSpeed * 1000) : -1,
+	myStatus.audioFrequency,
+	myStatus.audioChannels);
+
+
+ XSDEBUG("playing\n");
+
  /*
   * Play the subtune
   */
@@ -345,14 +350,13 @@
 	while (xs_status.isPlaying &&
 		(xs_status.currSong == myStatus.currSong) &&
 		((guint) xs_plugin_ip.output->buffer_free() < audioGot))
-		xmms_usleep(10000);
+		xmms_usleep(5000);
 
 	/* Output audio */
 	if (xs_status.isPlaying && (xs_status.currSong == myStatus.currSong))
 		xs_plugin_ip.output->write_audio(audioBuffer, audioGot);
 
 	/* Check if we have played enough */
-	XS_MUTEX_LOCK(xs_cfg);
 	if (xs_cfg.playMaxTimeEnable)
 		{
 		if (xs_cfg.playMaxTimeUnknown)
@@ -365,7 +369,6 @@
 				myStatus.isPlaying = FALSE;
 			}
 		}
-	XS_MUTEX_UNLOCK(xs_cfg);
 
 	if (songLength > 0)
 		{
@@ -402,6 +405,7 @@
  XS_MUTEX_LOCK(xs_status);
  xs_status.isPlaying = FALSE;
  XS_MUTEX_UNLOCK(xs_status);
+ 
  pthread_exit(NULL);
 }
 
@@ -438,7 +442,7 @@
  xs_status.currSong	= xs_status.tuneInfo->startTune;
  
  /* Start the playing thread! */
- if (pthread_create(&xs_decode_thread, NULL, xs_play_loop, NULL) < 0)
+ if (pthread_create(&xs_decode_thread, NULL, xs_playthread, NULL) < 0)
 	{
 	XSERR("Couldn't start playing thread! Possible reason reported by system: %s\n", strerror(errno));
  	xs_tuneinfo_free(xs_status.tuneInfo);
@@ -464,24 +468,24 @@
  XSDEBUG("STOP_REQ\n");
 
  xs_subctrl_close();
+ xs_fileinfo_update();
 
+ XS_MUTEX_LOCK(xs_status);
  if (xs_status.isPlaying)
 	{
 	/* Stop playing */
 	XSDEBUG("stopping...\n");
-	XS_MUTEX_LOCK(xs_status);
 	xs_status.isPlaying = FALSE;
 	XS_MUTEX_UNLOCK(xs_status);
 	pthread_join(xs_decode_thread, NULL);
+	} else {
+	XS_MUTEX_UNLOCK(xs_status);
 	}
 
  /* Free tune information */
  xs_status.sidPlayer->plrDeleteSID(&xs_status);
  xs_tuneinfo_free(xs_status.tuneInfo);
  xs_status.tuneInfo = NULL;
-
- /* Update subtune control */
- xs_subctrl_update();
 }
 
 
@@ -491,104 +495,109 @@
 void xs_pause(short pauseState)
 {
  xs_subctrl_close();
+ xs_fileinfo_update();
  xs_plugin_ip.output->pause(pauseState);
 }
 
 
 /*
- * Set or change sub-tune
- */
-void xs_set_subtune(int n)
-{
- XS_MUTEX_LOCK(xs_status);
- 
- if (xs_status.tuneInfo && xs_status.isPlaying)
- 	{
- 	if ((n >= 1) && (n <= xs_status.tuneInfo->nsubTunes))
- 		xs_status.currSong = n;
-	}
-
- XS_MUTEX_UNLOCK(xs_status);
-
- xs_subctrl_update();
-}
-
-
-void xs_change_subtune(int n)
-{
- XS_MUTEX_LOCK(xs_status);
- 
- if (xs_status.tuneInfo && xs_status.isPlaying)
- 	{
- 	n += xs_status.currSong;
- 	
- 	if ((n >= 1) && (n <= xs_status.tuneInfo->nsubTunes))
- 		xs_status.currSong = n;
-	}
-
- XS_MUTEX_UNLOCK(xs_status);
-
- xs_subctrl_update();
-}
-
-
-/*
  * Pop-up subtune selector
  */
 void xs_subctrl_setsong(void)
 {
- xs_set_subtune(GTK_ADJUSTMENT(xs_subctrl_adj)->value);
+ gint n;
+ 
+ XS_MUTEX_LOCK(xs_status);
+ XS_MUTEX_LOCK(xs_subctrl);
+ 
+ if (xs_status.tuneInfo && xs_status.isPlaying)
+ 	{
+ 	n = GTK_ADJUSTMENT(xs_subctrl_adj)->value;
+ 	if ((n >= 1) && (n <= xs_status.tuneInfo->nsubTunes))
+ 		xs_status.currSong = n;
+	}
+
+ XS_MUTEX_UNLOCK(xs_subctrl);
+ XS_MUTEX_UNLOCK(xs_status);
 }
 
 
 void xs_subctrl_prevsong(void)
 {
- xs_change_subtune(-1);
+ XS_MUTEX_LOCK(xs_status);
+ 
+ if (xs_status.tuneInfo && xs_status.isPlaying)
+ 	{
+ 	if (xs_status.currSong > 1)
+ 		xs_status.currSong--;
+	}
+
+ XS_MUTEX_UNLOCK(xs_status);
+
+ xs_subctrl_update();
 }
 
 
 void xs_subctrl_nextsong(void)
 {
- xs_change_subtune( 1);
+ XS_MUTEX_LOCK(xs_status);
+ 
+ if (xs_status.tuneInfo && xs_status.isPlaying)
+ 	{
+ 	if (xs_status.currSong < xs_status.tuneInfo->nsubTunes)
+ 		xs_status.currSong++;
+	}
+
+ XS_MUTEX_UNLOCK(xs_status);
+
+ xs_subctrl_update();
 }
 
 
 void xs_subctrl_update(void)
 {
  GtkAdjustment *tmpAdj;
- gboolean isEnabled;
  
  XS_MUTEX_LOCK(xs_status);
+ XS_MUTEX_LOCK(xs_subctrl);
  
  /* Check if control window exists, we are currently playing and have a tune */
  if (xs_subctrl)
 	{
 	if (xs_status.tuneInfo && xs_status.isPlaying)
 		{
-		XS_MUTEX_LOCK(xs_subctrl);
 	 	tmpAdj = GTK_ADJUSTMENT(xs_subctrl_adj);
  	
  		tmpAdj->value = xs_status.currSong;
  		tmpAdj->lower = 1;
 		tmpAdj->upper = xs_status.tuneInfo->nsubTunes;
+		XS_MUTEX_UNLOCK(xs_status);
+		XS_MUTEX_UNLOCK(xs_subctrl);
  		gtk_adjustment_value_changed(tmpAdj);
+ 		} else {
+ 		XS_MUTEX_UNLOCK(xs_status);
  		XS_MUTEX_UNLOCK(xs_subctrl);
- 		} else
  		xs_subctrl_close();
- 	}
+ 		}
+ 	} else {
+	XS_MUTEX_UNLOCK(xs_subctrl);
+	XS_MUTEX_UNLOCK(xs_status);
+	}
 
- XS_MUTEX_UNLOCK(xs_status);
+ xs_fileinfo_update();
 }
 
 
 void xs_subctrl_close(void)
 {
  XS_MUTEX_LOCK(xs_subctrl);
+
  if (xs_subctrl)
  	{
 	gtk_widget_destroy(xs_subctrl);
 	xs_subctrl = NULL;
 	}
+
  XS_MUTEX_UNLOCK(xs_subctrl);
 }
 
@@ -607,7 +616,6 @@
  GtkWidget *frame25, *hbox15, *subctrl_prev, *subctrl_current, *subctrl_next;
 
  XS_MUTEX_LOCK(xs_subctrl);
- 
  if (!xs_status.tuneInfo || !xs_status.isPlaying ||
     xs_subctrl || (xs_status.tuneInfo->nsubTunes <= 1))
     {
@@ -698,14 +706,18 @@
  	}
 
  /* Act according to settings */
- XS_MUTEX_LOCK(xs_cfg); 
  switch (xs_cfg.subsongControl) {
  case XS_SSC_SEEK:
 	if (iTime < xs_status.lastTime)
-		xs_change_subtune(-1);
-		else
+		{
+	 	if (xs_status.currSong > 1)
+ 			xs_status.currSong--;
+		} else
 	if (iTime > xs_status.lastTime)
-		xs_change_subtune(1);
+		{
+	 	if (xs_status.currSong < xs_status.tuneInfo->nsubTunes)
+ 			xs_status.currSong++;
+		}
 	break;
 
  case XS_SSC_POPUP:
@@ -715,13 +727,12 @@
  /* If we have song-position patch, check settings */
 #ifdef HAVE_SONG_POSITION
  case XS_SSC_PATCH:
-	if ((iTime > 0) && (iTime <= xs_status.tuneInfo->nsubTunes))
+	if ((iTime >= 1) && (iTime <= xs_status.tuneInfo->nsubTunes))
 		xs_status.currSong = iTime;
 	break;
 #endif
  }
 
- XS_MUTEX_UNLOCK(xs_cfg);
  XS_MUTEX_UNLOCK(xs_status);
 }
 
@@ -737,7 +748,6 @@
 {
  /* If errorflag is set, return -2 to signal it to XMMS's idle callback */
  XS_MUTEX_LOCK(xs_status);
- 
  if (xs_status.isError)
  	{
  	XS_MUTEX_UNLOCK(xs_status);
@@ -759,7 +769,6 @@
 	}
 
  /* Let's see what we do */
- XS_MUTEX_LOCK(xs_cfg);
  switch (xs_cfg.subsongControl) {
  case XS_SSC_SEEK:
  	xs_status.lastTime = (xs_plugin_ip.output->output_time() / 1000);
@@ -772,7 +781,6 @@
 #endif
  }
  
- XS_MUTEX_UNLOCK(xs_cfg);
  XS_MUTEX_UNLOCK(xs_status);
 
  /* Return output time reported by audio output plugin */
@@ -869,7 +877,3 @@
  g_free(pTune);
 }
 
-
-void xs_fileinfo_ok(void)
-{
-}
--- a/src/xs_fileinfo.c	Tue Dec 21 13:12:04 2004 +0000
+++ b/src/xs_fileinfo.c	Tue Dec 21 13:13:05 2004 +0000
@@ -23,6 +23,7 @@
 #include <gtk/gtk.h>
 
 #include "xmms-sid.h"
+#include "xs_support.h"
 #include "xs_stil.h"
 #include "xs_config.h"
 #include "xs_interface.h"
@@ -30,11 +31,49 @@
 
 static GtkWidget		*xs_fileinfowin = NULL;
 static t_xs_stil_node		*xs_fileinfostil = NULL;
-static t_xs_tuneinfo		*xs_fileinfotune = NULL;
+XS_MUTEX(xs_fileinfowin);
 
 #define LUW(x...)	lookup_widget(xs_fileinfowin, ## x)
 
 
+void xs_fileinfo_update(void)
+{
+ gboolean isEnabled;
+ GtkAdjustment *tmpAdj;
+ 
+ XS_MUTEX_LOCK(xs_status);
+ XS_MUTEX_LOCK(xs_fileinfowin);
+ 
+ /* Check if control window exists, we are currently playing and have a tune */
+ if (xs_fileinfowin)
+	{
+	if (xs_status.tuneInfo && xs_status.isPlaying && (xs_status.tuneInfo->nsubTunes > 1))
+		{
+		tmpAdj = gtk_range_get_adjustment(GTK_RANGE(LUW("fileinfo_subctrl_adj")));
+ 	
+ 		tmpAdj->value = xs_status.currSong;
+ 		tmpAdj->lower = 1;
+		tmpAdj->upper = xs_status.tuneInfo->nsubTunes;
+		XS_MUTEX_UNLOCK(xs_status);
+		XS_MUTEX_UNLOCK(xs_fileinfowin);
+ 		gtk_adjustment_value_changed(tmpAdj);
+		XS_MUTEX_LOCK(xs_status);
+		XS_MUTEX_LOCK(xs_fileinfowin); 		
+ 		isEnabled = TRUE;
+ 		} else
+ 		isEnabled = FALSE;
+
+	/* Enable or disable subtune-control in fileinfo window */
+	gtk_widget_set_sensitive(LUW("fileinfo_subctrl_prev"), isEnabled);
+	gtk_widget_set_sensitive(LUW("fileinfo_subctrl_adj"), isEnabled);
+	gtk_widget_set_sensitive(LUW("fileinfo_subctrl_next"), isEnabled); 		
+ 	}
+
+ XS_MUTEX_UNLOCK(xs_status);
+ XS_MUTEX_UNLOCK(xs_fileinfowin);
+}
+
+
 void xs_fileinfo_setsong(void)
 {
 }
@@ -42,8 +81,13 @@
 
 void xs_fileinfo_ok(void)
 {
- gtk_widget_destroy(xs_fileinfowin);
- xs_fileinfowin = NULL;
+ XS_MUTEX_LOCK(xs_fileinfowin);
+ if (xs_fileinfowin)
+ 	{
+ 	gtk_widget_destroy(xs_fileinfowin);
+ 	xs_fileinfowin = NULL;
+ 	}
+ XS_MUTEX_UNLOCK(xs_fileinfowin);
 }
 
 
@@ -96,23 +140,27 @@
 void xs_fileinfo(gchar *pcFilename)
 {
  GtkWidget *tmpMenuItem, *tmpMenu, *tmpOptionMenu;
+ t_xs_tuneinfo *tmpInfo;
  t_xs_stil_subnode *tmpNode;
  gchar tmpStr[32], *tmpS;
  gint n;
 
- /* Free old info, if set */
- if (xs_fileinfotune)
- 	xs_tuneinfo_free(xs_fileinfotune);
- 
+ /* Current implementation leaves old fileinfo window untouched if
+  * no information can be found for the new file. Hmm...
+  */
+
  /* Get new tune information */
- if ((xs_fileinfotune = xs_player->plrGetSIDInfo(pcFilename)) == NULL)
+ XS_MUTEX_LOCK(xs_fileinfowin);
+ XS_MUTEX_LOCK(xs_status);
+ if ((tmpInfo = xs_status.sidPlayer->plrGetSIDInfo(pcFilename)) == NULL)
+ 	{
+ 	XS_MUTEX_UNLOCK(xs_fileinfowin);
+ 	XS_MUTEX_UNLOCK(xs_status);
  	return;
+ 	}
+ XS_MUTEX_UNLOCK(xs_status);
 
- if (xs_cfg.stilDBEnable)
-	xs_fileinfostil = xs_stil_get(pcFilename);
-	else
-	xs_fileinfostil = NULL;
- 
+ xs_fileinfostil = xs_stil_get(pcFilename);
 
  /* Check if there already is an open fileinfo window */
  if (xs_fileinfowin)
@@ -137,9 +185,9 @@
 
  /* Set the generic song information */
  gtk_entry_set_text(GTK_ENTRY(LUW("fileinfo_filename")), pcFilename);
- gtk_entry_set_text(GTK_ENTRY(LUW("fileinfo_songname")), xs_fileinfotune->tuneName);
- gtk_entry_set_text(GTK_ENTRY(LUW("fileinfo_composer")), xs_fileinfotune->tuneComposer);
- gtk_entry_set_text(GTK_ENTRY(LUW("fileinfo_copyright")), xs_fileinfotune->tuneCopyright);
+ gtk_entry_set_text(GTK_ENTRY(LUW("fileinfo_songname")), tmpInfo->sidName);
+ gtk_entry_set_text(GTK_ENTRY(LUW("fileinfo_composer")), tmpInfo->sidComposer);
+ gtk_entry_set_text(GTK_ENTRY(LUW("fileinfo_copyright")), tmpInfo->sidCopyright);
 
 
  /* Main tune - the pseudo tune */
@@ -153,7 +201,7 @@
 		GTK_SIGNAL_FUNC (xs_fileinfo_subtune), tmpMenu);
 
  /* Other menu items */
- for (n = 1; n <= xs_fileinfotune->nsubTunes; n++)
+ for (n = 1; n <= tmpInfo->nsubTunes; n++)
 	{
 	if (xs_fileinfostil)
 		{
@@ -181,7 +229,14 @@
  /* Set the subtune information */
  xs_fileinfo_subtune(NULL, tmpMenu);
 
+ /* Free temporary tuneinfo */
+ xs_tuneinfo_free(tmpInfo);
+
  /* Show the window */
  gtk_widget_show(xs_fileinfowin);
+
+ XS_MUTEX_UNLOCK(xs_fileinfowin);
+
+ xs_fileinfo_update();
 }
 
--- a/src/xs_init.c	Tue Dec 21 13:12:04 2004 +0000
+++ b/src/xs_init.c	Tue Dec 21 13:13:05 2004 +0000
@@ -46,7 +46,7 @@
 	NULL,			/* Send data to Visualization plugin */
 	NULL, NULL,		/* FILLED BY XMMS */
 	xs_get_song_info,	/* Get song title and length */
-	NULL, /*xs_fileinfo,		Show file-information dialog */
+	xs_fileinfo,		/* Show file-information dialog */
 	NULL			/* FILLED BY XMMS */
 };
 
--- a/src/xs_sidplay1.cc	Tue Dec 21 13:12:04 2004 +0000
+++ b/src/xs_sidplay1.cc	Tue Dec 21 13:13:05 2004 +0000
@@ -151,7 +151,7 @@
 {
  t_xs_sidplay1 *myEngine = (t_xs_sidplay1 *) myStatus->sidEngine;
 
- if (!myEngine) return FALSE;
+ if (!myEngine) return 0;
 
  sidEmuFillBuffer(
 	*myEngine->currEng,
--- a/src/xs_sidplay2.cc	Tue Dec 21 13:12:04 2004 +0000
+++ b/src/xs_sidplay2.cc	Tue Dec 21 13:13:05 2004 +0000
@@ -197,6 +197,8 @@
 {
  t_xs_sidplay2 *myEngine = (t_xs_sidplay2 *) myStatus->sidEngine;
 
+ if (!myEngine) return 0;
+
  return myEngine->currEng->play(audioBuffer, audioBufSize);
 }
 
--- a/src/xs_stil.c	Tue Dec 21 13:12:04 2004 +0000
+++ b/src/xs_stil.c	Tue Dec 21 13:13:05 2004 +0000
@@ -457,23 +457,27 @@
  XS_MUTEX_LOCK(xs_stildb_db);
  XS_MUTEX_LOCK(xs_cfg);
 
- if (xs_cfg.hvscPath)
+ if (xs_cfg.stilDBEnable && xs_stildb_db)
  	{
- 	/* Remove postfixed directory separator from HVSC-path */
- 	tmpFilename = xs_strrchr(xs_cfg.hvscPath, '/');
- 	if (tmpFilename && (tmpFilename[1] == 0))
- 		tmpFilename[0] = 0;
+	if (xs_cfg.hvscPath)
+ 		{
+ 		/* Remove postfixed directory separator from HVSC-path */
+ 		tmpFilename = xs_strrchr(xs_cfg.hvscPath, '/');
+ 		if (tmpFilename && (tmpFilename[1] == 0))
+ 			tmpFilename[0] = 0;
  
-	/* Remove HVSC location-prefix from filename */
-	tmpFilename = strstr(pcFilename, xs_cfg.hvscPath);
-	if (tmpFilename)
-		tmpFilename += strlen(xs_cfg.hvscPath);
-		else
-		tmpFilename = pcFilename; 
+		/* Remove HVSC location-prefix from filename */
+		tmpFilename = strstr(pcFilename, xs_cfg.hvscPath);
+		if (tmpFilename)
+			tmpFilename += strlen(xs_cfg.hvscPath);
+			else
+			tmpFilename = pcFilename; 
+		} else
+		tmpFilename = pcFilename;
+	
+	pResult = xs_stildb_get_node(xs_stildb_db, tmpFilename);
 	} else
-	tmpFilename = pcFilename;
-	
- pResult = xs_stildb_get_node(xs_stildb_db, tmpFilename);
+	pResult = NULL;
 
  XS_MUTEX_UNLOCK(xs_stildb_db);
  XS_MUTEX_UNLOCK(xs_cfg);