# HG changeset patch # User Matti Hamalainen # Date 1103634785 0 # Node ID e613873c3379d0a2d6e098bed2429c24df69424b # Parent 9d7274a11fb10e9064555e7a2c0f2e9c956c0f8d Thread locking now final. All parts, including GTK GUI, should be(?) properly locked and no race conditions should be present. diff -r 9d7274a11fb1 -r e613873c3379 src/xmms-sid.c --- 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) -{ -} diff -r 9d7274a11fb1 -r e613873c3379 src/xs_fileinfo.c --- 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 #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(); } diff -r 9d7274a11fb1 -r e613873c3379 src/xs_init.c --- 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 */ }; diff -r 9d7274a11fb1 -r e613873c3379 src/xs_sidplay1.cc --- 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, diff -r 9d7274a11fb1 -r e613873c3379 src/xs_sidplay2.cc --- 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); } diff -r 9d7274a11fb1 -r e613873c3379 src/xs_stil.c --- 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);