ch->sfx-> to use a local variable holding the unchanging value of sfx
(the crash occurs when the mixer thread clears ch->sfx while the main
thread is deciding whether to merge a sound onto an existing channel -
if the channel dies during this code, the sfx pointer must be preserved)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11161
d7cf8633-e32d-0410-b094-
e92efae38249
int first_to_die;
int first_life_left, life_left;
channel_t* ch;
int first_to_die;
int first_life_left, life_left;
channel_t* ch;
+ sfx_t *sfx; // use this instead of ch->sfx->, because that is volatile.
// Check for replacement sound, or find the best one to replace
first_to_die = -1;
// Check for replacement sound, or find the best one to replace
first_to_die = -1;
for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++)
{
ch = &channels[ch_idx];
for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++)
{
ch = &channels[ch_idx];
+ sfx = ch->sfx; // fetch the volatile variable
+ if (!sfx)
{
// no sound on this channel
first_to_die = ch_idx;
{
// no sound on this channel
first_to_die = ch_idx;
continue;
// don't override looped sounds
continue;
// don't override looped sounds
- if ((ch->flags & CHANNELFLAG_FORCELOOP) || ch->sfx->loopstart < ch->sfx->total_length)
+ if ((ch->flags & CHANNELFLAG_FORCELOOP) || sfx->loopstart < sfx->total_length)
- life_left = ch->sfx->total_length - ch->pos;
+ life_left = sfx->total_length - ch->pos;
if (life_left < first_life_left)
{
if (life_left < first_life_left)
{
int ambient_channel;
channel_t *chan;
unsigned char ambientlevels[NUM_AMBIENTS];
int ambient_channel;
channel_t *chan;
unsigned char ambientlevels[NUM_AMBIENTS];
memset(ambientlevels, 0, sizeof(ambientlevels));
if (cl.worldmodel && cl.worldmodel->brush.AmbientSoundLevelsForPoint)
memset(ambientlevels, 0, sizeof(ambientlevels));
if (cl.worldmodel && cl.worldmodel->brush.AmbientSoundLevelsForPoint)
for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)
{
chan = &channels[ambient_channel];
for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)
{
chan = &channels[ambient_channel];
- if (chan->sfx == NULL || chan->sfx->fetcher == NULL)
+ sfx = chan->sfx; // fetch the volatile variable
+ if (sfx == NULL || sfx->fetcher == NULL)
continue;
vol = (int)ambientlevels[ambient_channel];
continue;
vol = (int)ambientlevels[ambient_channel];
{
int listener_volume [SND_LISTENERS]; // 0-65536 volume per speaker
int master_vol; // 0-65536 master volume
{
int listener_volume [SND_LISTENERS]; // 0-65536 volume per speaker
int master_vol; // 0-65536 master volume
- sfx_t *sfx; // sfx number
+ sfx_t *sfx; // pointer to sound sample being used
unsigned int flags; // cf CHANNELFLAG_* defines
int pos; // sample position in sfx, negative values delay the start of the sound playback
int entnum; // to allow overriding a specific sound
unsigned int flags; // cf CHANNELFLAG_* defines
int pos; // sample position in sfx, negative values delay the start of the sound playback
int entnum; // to allow overriding a specific sound
int vol[SND_LISTENERS];
const snd_buffer_t *sb;
unsigned int i, sb_offset;
int vol[SND_LISTENERS];
const snd_buffer_t *sb;
unsigned int i, sb_offset;
+ sfx_t *sfx;
+
+ sfx = ch->sfx; // fetch the volatile variable
+ if (!sfx) // given that this is called by the mixer thread, this never happens, but...
+ return false;
// move to the stack (do we need to?)
for (i = 0;i < SND_LISTENERS;i++)
// move to the stack (do we need to?)
for (i = 0;i < SND_LISTENERS;i++)
return false;
sb_offset = ch->pos;
return false;
sb_offset = ch->pos;
- sb = ch->sfx->fetcher->getsb (ch->sfx->fetcher_data, &ch->fetcher_data, &sb_offset, count);
+ sb = sfx->fetcher->getsb (sfx->fetcher_data, &ch->fetcher_data, &sb_offset, count);
if (sb == NULL)
{
Con_DPrintf("SND_PaintChannel: ERROR: can't get sound buffer from sfx \"%s\"\n",
if (sb == NULL)
{
Con_DPrintf("SND_PaintChannel: ERROR: can't get sound buffer from sfx \"%s\"\n",
- ch->sfx->name); // , count); // or add this? FIXME
+ sfx->name); // , count); // or add this? FIXME