prevent a threading access error when the Mix_Chunk vector is deleted
This commit is contained in:
parent
c3b627c6f3
commit
910753f060
2 changed files with 47 additions and 26 deletions
10
src/game.cpp
10
src/game.cpp
|
@ -14,6 +14,7 @@
|
|||
#include "global.hpp"
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_mixer.h"
|
||||
|
||||
#include "about.hpp"
|
||||
#include "config.hpp"
|
||||
|
@ -1614,9 +1615,18 @@ void game_controller::play_replay()
|
|||
}
|
||||
}
|
||||
|
||||
namespace sound {
|
||||
extern std::vector<Mix_Chunk*> *channel_chunks;
|
||||
extern threading::mutex channel_mutex;
|
||||
}
|
||||
game_controller::~game_controller()
|
||||
{
|
||||
delete gui::empty_menu;
|
||||
threading::lock l(sound::channel_mutex);
|
||||
{
|
||||
delete sound::channel_chunks;
|
||||
sound::channel_chunks = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int play_game(int argc, char** argv)
|
||||
|
|
|
@ -32,6 +32,18 @@
|
|||
#define LOG_AUDIO LOG_STREAM(info, audio)
|
||||
#define ERR_AUDIO LOG_STREAM(err, audio)
|
||||
|
||||
namespace sound {
|
||||
// Channel-chunk mapping lets us know, if we can safely free a given chunk
|
||||
std::vector<Mix_Chunk*> *channel_chunks;
|
||||
|
||||
// Channel-id mapping for use with sound sources (to check if given source
|
||||
// is playing on a channel for fading/panning)
|
||||
std::vector<int> channel_ids;
|
||||
|
||||
// Mutex syncing access to channel_chunks and channel_ids vectors
|
||||
threading::mutex channel_mutex;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool mix_ok = false;
|
||||
|
@ -64,17 +76,6 @@ unsigned max_cached_chunks = 256;
|
|||
std::map<std::string,Mix_Chunk*> sound_cache;
|
||||
std::map<std::string,Mix_Music*> music_cache;
|
||||
|
||||
// Channel-chunk mapping lets us know, if we can safely free a given chunk
|
||||
std::vector<Mix_Chunk*> channel_chunks;
|
||||
|
||||
// Channel-id mapping for use with sound sources (to check if given source
|
||||
// is playing on a channel for fading/panning)
|
||||
std::vector<int> channel_ids;
|
||||
|
||||
// Mutex syncing access to channel_chunks and channel_ids vectors
|
||||
threading::mutex channel_mutex;
|
||||
|
||||
|
||||
struct music_track
|
||||
{
|
||||
music_track(const std::string &tname);
|
||||
|
@ -231,20 +232,24 @@ std::string pick_one(const std::string &files)
|
|||
return names[choice];
|
||||
}
|
||||
|
||||
// Removes channel-chunk and channel-id mapping
|
||||
void channel_finished_hook(int channel)
|
||||
{
|
||||
threading::lock l(channel_mutex);
|
||||
channel_chunks[channel] = 0;
|
||||
|
||||
if(channel < source_channels)
|
||||
channel_ids[channel] = -1;
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
|
||||
namespace sound {
|
||||
|
||||
// Removes channel-chunk and channel-id mapping
|
||||
void channel_finished_hook(int channel)
|
||||
{
|
||||
threading::lock l(channel_mutex);
|
||||
if(channel_chunks) {
|
||||
(*channel_chunks)[channel] = 0;
|
||||
}
|
||||
|
||||
if(channel < source_channels) {
|
||||
channel_ids[channel] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
manager::manager()
|
||||
{
|
||||
|
@ -272,7 +277,7 @@ bool init_sound() {
|
|||
Mix_AllocateChannels(n_of_channels);
|
||||
Mix_ReserveChannels(n_reserved_channels);
|
||||
|
||||
channel_chunks.resize(n_of_channels, 0);
|
||||
channel_chunks = new std::vector<Mix_Chunk*>(n_of_channels, 0);
|
||||
channel_ids.resize(source_channels, -1);
|
||||
|
||||
const size_t source_channel_last = source_channels - source_channel_start + 1;
|
||||
|
@ -603,8 +608,11 @@ void play_sound_internal(const std::string& files, int channel, bool sound_on)
|
|||
|
||||
Mix_Chunk *c = (*i).second;
|
||||
|
||||
if(channel_chunks == NULL)
|
||||
return;
|
||||
|
||||
// if it's being played - try again
|
||||
if(std::find(channel_chunks.begin(), channel_chunks.end(), c) != channel_chunks.end())
|
||||
if(std::find((*channel_chunks).begin(), (*channel_chunks).end(), c) != (*channel_chunks).end())
|
||||
continue;
|
||||
|
||||
Mix_FreeChunk(c);
|
||||
|
@ -647,11 +655,14 @@ void play_sound_internal(const std::string& files, int channel, bool sound_on)
|
|||
|
||||
threading::lock l(channel_mutex);
|
||||
if(res < 0) {
|
||||
channel_chunks[res] = 0;
|
||||
if(channel_chunks) {
|
||||
(*channel_chunks)[res] = 0;
|
||||
}
|
||||
ERR_AUDIO << "error playing sound effect: " << Mix_GetError() << "\n";
|
||||
}
|
||||
else
|
||||
channel_chunks[res] = cache;
|
||||
else if(channel_chunks) {
|
||||
(*channel_chunks)[res] = cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue