|
From: Tapio V. <aa...@us...> - 2010-09-16 07:01:40
|
Module: performous
Branch: master
Commit: a922772f3863a813cafd60dfcff54271e27cf70f
Author: Tapio Vierros <tap...@gm...>
Date: Thu Sep 16 10:00:10 2010 +0300
Audio now has limited time to shut itself down (anti-hang hack).
---
game/audio.cc | 3 ++-
game/audio.hh | 3 ++-
game/main.cc | 12 ++++++++----
game/screen_audiodevices.cc | 14 +++++++++++---
4 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index ba96a09..111c6f7 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -520,7 +520,8 @@ struct Audio::Impl {
Audio::Audio(): self(new Impl) {}
Audio::~Audio() {}
-void Audio::reset() { self.reset(new Impl); };
+void Audio::restart() { self.reset(new Impl); };
+void Audio::close() { self.reset(); };
bool Audio::isOpen() const {
return !self->devices.empty();
diff --git a/game/audio.hh b/game/audio.hh
index a5c98ae..a8d6650 100644
--- a/game/audio.hh
+++ b/game/audio.hh
@@ -46,7 +46,8 @@ class Audio {
public:
Audio();
~Audio();
- void reset();
+ void restart();
+ void close();
boost::ptr_vector<Analyzer>& analyzers();
boost::ptr_vector<Device>& devices();
bool isOpen() const;
diff --git a/game/main.cc b/game/main.cc
index 3c883ba..08770fc 100644
--- a/game/main.cc
+++ b/game/main.cc
@@ -202,6 +202,12 @@ void mainLoop(std::string const& songlist) {
} catch (QuitNow&) {
std::cout << "Terminated." << std::endl;
}
+ // Give audio a little time to shutdown but then just quit
+ boost::thread audiokiller(boost::bind(&Audio::close, boost::ref(audio)));
+ if (!audiokiller.timed_join(boost::posix_time::milliseconds(2000))) {
+ std::cout << "Audio hung." << std::endl;
+ exit(EXIT_SUCCESS);
+ }
}
/// Simple test utility to make mapping of joystick buttons/axes easier
@@ -299,10 +305,10 @@ int main(int argc, char** argv) try {
}
po::notify(vm);
- // initialize the verbose message sink
+ // Initialize the verbose message sink
//logger::__log_hh_test(); // debug
logger::setup(loglevel_regexp);
-
+ atexit(logger::teardown); // We might exit from many places due to audio hangs
if (vm.count("version")) {
// Already printed the version string in the beginning...
@@ -346,8 +352,6 @@ int main(int argc, char** argv) try {
// Run the game init and main loop
mainLoop(songlist);
- logger::teardown();
-
return EXIT_SUCCESS; // Do not remove. SDL_Main (which this function is called on some platforms) needs return statement.
} catch (std::exception& e) {
std::cerr << "FATAL ERROR: " << e.what() << std::endl;
diff --git a/game/screen_audiodevices.cc b/game/screen_audiodevices.cc
index 4df3663..4e22204 100644
--- a/game/screen_audiodevices.cc
+++ b/game/screen_audiodevices.cc
@@ -5,7 +5,9 @@
#include "theme.hh"
#include "audio.hh"
#include "i18n.hh"
-
+#include <cstdlib>
+#include <boost/thread.hpp>
+#include <boost/bind.hpp>
namespace {
const float yoff = 0.18; // Offset from center where to place top row
@@ -175,8 +177,14 @@ bool ScreenAudioDevices::save(bool skip_ui_config) {
}
writeConfig(); // Save the new config
size_t unassigned_id = m_devs.size();
- // TODO: Make sure this isn't particularly prone to crashes
- m_audio.reset(); // Reload audio to take the new settings into use
+ // Give audio a little time to shutdown but then just quit
+ boost::thread audiokiller(boost::bind(&Audio::close, boost::ref(m_audio)));
+ if (!audiokiller.timed_join(boost::posix_time::milliseconds(4000))) {
+ // FIXME: Notify user
+ std::cout << "Audio hung. Please restart Performous" << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ m_audio.restart(); // Reload audio to take the new settings into use
m_audio.playMusic(getThemePath("menu.ogg"), true); // Start music again
// Check that all went well
bool ret = verify(unassigned_id);
|