Corrected race condition in positional effects.
authorRyan C. Gordon <icculus@icculus.org>
Sun, 11 Oct 2009 02:59:12 +0000
changeset 442884a700fb3ff
parent 441 f86cc112a195
child 443 d842a759e68a
Corrected race condition in positional effects.

Fixes Bugzilla #651.
effect_position.c
effects_internal.h
mixer.c
     1.1 --- a/effect_position.c	Sat Oct 10 17:05:45 2009 +0000
     1.2 +++ b/effect_position.c	Sun Oct 11 02:59:12 2009 +0000
     1.3 @@ -1427,6 +1427,8 @@
     1.4      int channels;
     1.5      Uint16 format;
     1.6      position_args *args = NULL;
     1.7 +    int retval = 1;
     1.8 +
     1.9      Mix_QuerySpec(NULL, &format, &channels);
    1.10  
    1.11      if (channels != 2 && channels != 4 && channels != 6)    /* it's a no-op; we call that successful. */
    1.12 @@ -1449,16 +1451,22 @@
    1.13      if (f == NULL)
    1.14          return(0);
    1.15  
    1.16 +    SDL_LockAudio();
    1.17      args = get_position_arg(channel);
    1.18 -    if (!args)
    1.19 +    if (!args) {
    1.20 +        SDL_UnlockAudio();
    1.21          return(0);
    1.22 +    }
    1.23  
    1.24          /* it's a no-op; unregister the effect, if it's registered. */
    1.25      if ((args->distance_u8 == 255) && (left == 255) && (right == 255)) {
    1.26          if (args->in_use) {
    1.27 -            return(Mix_UnregisterEffect(channel, f));
    1.28 +            retval = _Mix_UnregisterEffect_locked(channel, f);
    1.29 +            SDL_UnlockAudio();
    1.30 +            return(retval);
    1.31          } else {
    1.32 -	  return(1);
    1.33 +            SDL_UnlockAudio();
    1.34 +            return(1);
    1.35          }
    1.36      }
    1.37  
    1.38 @@ -1470,10 +1478,11 @@
    1.39  
    1.40      if (!args->in_use) {
    1.41          args->in_use = 1;
    1.42 -        return(Mix_RegisterEffect(channel, f, _Eff_PositionDone, (void *) args));
    1.43 +        retval=_Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void*)args);
    1.44      }
    1.45  
    1.46 -    return(1);
    1.47 +    SDL_UnlockAudio();
    1.48 +    return(retval);
    1.49  }
    1.50  
    1.51  
    1.52 @@ -1483,23 +1492,30 @@
    1.53      Uint16 format;
    1.54      position_args *args = NULL;
    1.55      int channels;
    1.56 +    int retval = 1;
    1.57  
    1.58      Mix_QuerySpec(NULL, &format, &channels);
    1.59      f = get_position_effect_func(format, channels);
    1.60      if (f == NULL)
    1.61          return(0);
    1.62  
    1.63 +    SDL_LockAudio();
    1.64      args = get_position_arg(channel);
    1.65 -    if (!args)
    1.66 +    if (!args) {
    1.67 +        SDL_UnlockAudio();
    1.68          return(0);
    1.69 +    }
    1.70  
    1.71      distance = 255 - distance;  /* flip it to our scale. */
    1.72  
    1.73          /* it's a no-op; unregister the effect, if it's registered. */
    1.74      if ((distance == 255) && (args->left_u8 == 255) && (args->right_u8 == 255)) {
    1.75          if (args->in_use) {
    1.76 -            return(Mix_UnregisterEffect(channel, f));
    1.77 +            retval = _Mix_UnregisterEffect_locked(channel, f);
    1.78 +            SDL_UnlockAudio();
    1.79 +            return(retval);
    1.80          } else {
    1.81 +            SDL_UnlockAudio();
    1.82              return(1);
    1.83          }
    1.84      }
    1.85 @@ -1508,10 +1524,11 @@
    1.86      args->distance_f = ((float) distance) / 255.0f;
    1.87      if (!args->in_use) {
    1.88          args->in_use = 1;
    1.89 -        return(Mix_RegisterEffect(channel, f, _Eff_PositionDone, (void *) args));
    1.90 +        retval = _Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void *) args);
    1.91      }
    1.92  
    1.93 -    return(1);
    1.94 +    SDL_UnlockAudio();
    1.95 +    return(retval);
    1.96  }
    1.97  
    1.98  
    1.99 @@ -1522,6 +1539,7 @@
   1.100      int channels;
   1.101      position_args *args = NULL;
   1.102      Sint16 room_angle = 0;
   1.103 +    int retval = 1;
   1.104  
   1.105      Mix_QuerySpec(NULL, &format, &channels);
   1.106      f = get_position_effect_func(format, channels);
   1.107 @@ -1530,17 +1548,23 @@
   1.108  
   1.109      angle = SDL_abs(angle) % 360;  /* make angle between 0 and 359. */
   1.110  
   1.111 +    SDL_LockAudio();
   1.112      args = get_position_arg(channel);
   1.113 -    if (!args)
   1.114 +    if (!args) {
   1.115 +        SDL_UnlockAudio();
   1.116          return(0);
   1.117 +    }
   1.118  
   1.119          /* it's a no-op; unregister the effect, if it's registered. */
   1.120      if ((!distance) && (!angle)) {
   1.121          if (args->in_use) {
   1.122 -            return(Mix_UnregisterEffect(channel, f));
   1.123 +            retval = _Mix_UnregisterEffect_locked(channel, f);
   1.124 +            SDL_UnlockAudio();
   1.125 +            return(retval);
   1.126          } else {
   1.127 -	  return(1);
   1.128 -	}
   1.129 +            SDL_UnlockAudio();
   1.130 +            return(1);
   1.131 +        }
   1.132      }
   1.133  
   1.134      if (channels == 2)
   1.135 @@ -1581,10 +1605,11 @@
   1.136      args->room_angle = room_angle;
   1.137      if (!args->in_use) {
   1.138          args->in_use = 1;
   1.139 -        return(Mix_RegisterEffect(channel, f, _Eff_PositionDone, (void *) args));
   1.140 +        retval = _Mix_RegisterEffect_locked(channel, f, _Eff_PositionDone, (void *) args);
   1.141      }
   1.142  
   1.143 -    return(1);
   1.144 +    SDL_UnlockAudio();
   1.145 +    return(retval);
   1.146  }
   1.147  
   1.148  
     2.1 --- a/effects_internal.h	Sat Oct 10 17:05:45 2009 +0000
     2.2 +++ b/effects_internal.h	Sun Oct 11 02:59:12 2009 +0000
     2.3 @@ -45,6 +45,12 @@
     2.4  void _Mix_DeinitEffects(void);
     2.5  void _Eff_PositionDeinit(void);
     2.6  
     2.7 +int _Mix_RegisterEffect_locked(int channel, Mix_EffectFunc_t f,
     2.8 +                               Mix_EffectDone_t d, void *arg);
     2.9 +int _Mix_UnregisterEffect_locked(int channel, Mix_EffectFunc_t f);
    2.10 +int _Mix_UnregisterAllEffects_locked(int channel);
    2.11 +
    2.12 +
    2.13  /* Set up for C function definitions, even when using C++ */
    2.14  #ifdef __cplusplus
    2.15  }
     3.1 --- a/mixer.c	Sat Oct 10 17:05:45 2009 +0000
     3.2 +++ b/mixer.c	Sun Oct 11 02:59:12 2009 +0000
     3.3 @@ -1276,11 +1276,11 @@
     3.4  }
     3.5  
     3.6  
     3.7 -int Mix_RegisterEffect(int channel, Mix_EffectFunc_t f,
     3.8 +/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */
     3.9 +int _Mix_RegisterEffect_locked(int channel, Mix_EffectFunc_t f,
    3.10  			Mix_EffectDone_t d, void *arg)
    3.11  {
    3.12  	effect_info **e = NULL;
    3.13 -	int retval;
    3.14  
    3.15  	if (channel == MIX_CHANNEL_POST) {
    3.16  		e = &posteffects;
    3.17 @@ -1292,17 +1292,24 @@
    3.18  		e = &mix_channel[channel].effects;
    3.19  	}
    3.20  
    3.21 -	SDL_LockAudio();
    3.22 -	retval = _Mix_register_effect(e, f, d, arg);
    3.23 -	SDL_UnlockAudio();
    3.24 -	return(retval);
    3.25 +	return _Mix_register_effect(e, f, d, arg);
    3.26  }
    3.27  
    3.28 +int Mix_RegisterEffect(int channel, Mix_EffectFunc_t f,
    3.29 +			Mix_EffectDone_t d, void *arg)
    3.30 +{
    3.31 +    int retval;
    3.32 +	SDL_LockAudio();
    3.33 +	retval = _Mix_RegisterEffect_locked(channel, f, d, arg);
    3.34 +	SDL_UnlockAudio();
    3.35 +    return retval;
    3.36 +}
    3.37  
    3.38 -int Mix_UnregisterEffect(int channel, Mix_EffectFunc_t f)
    3.39 +
    3.40 +/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */
    3.41 +int _Mix_UnregisterEffect_locked(int channel, Mix_EffectFunc_t f)
    3.42  {
    3.43  	effect_info **e = NULL;
    3.44 -	int retval;
    3.45  
    3.46  	if (channel == MIX_CHANNEL_POST) {
    3.47  		e = &posteffects;
    3.48 @@ -1314,17 +1321,22 @@
    3.49  		e = &mix_channel[channel].effects;
    3.50  	}
    3.51  
    3.52 +	return _Mix_remove_effect(channel, e, f);
    3.53 +}
    3.54 +
    3.55 +int Mix_UnregisterEffect(int channel, Mix_EffectFunc_t f)
    3.56 +{
    3.57 +	int retval;
    3.58  	SDL_LockAudio();
    3.59 -	retval = _Mix_remove_effect(channel, e, f);
    3.60 +	retval = _Mix_UnregisterEffect_locked(channel, f);
    3.61  	SDL_UnlockAudio();
    3.62  	return(retval);
    3.63  }
    3.64  
    3.65 -
    3.66 -int Mix_UnregisterAllEffects(int channel)
    3.67 +/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */
    3.68 +int _Mix_UnregisterAllEffects_locked(int channel)
    3.69  {
    3.70  	effect_info **e = NULL;
    3.71 -	int retval;
    3.72  
    3.73  	if (channel == MIX_CHANNEL_POST) {
    3.74  		e = &posteffects;
    3.75 @@ -1336,8 +1348,14 @@
    3.76  		e = &mix_channel[channel].effects;
    3.77  	}
    3.78  
    3.79 +	return _Mix_remove_all_effects(channel, e);
    3.80 +}
    3.81 +
    3.82 +int Mix_UnregisterAllEffects(int channel)
    3.83 +{
    3.84 +	int retval;
    3.85  	SDL_LockAudio();
    3.86 -	retval = _Mix_remove_all_effects(channel, e);
    3.87 +	retval = _Mix_UnregisterAllEffects_locked(channel);
    3.88  	SDL_UnlockAudio();
    3.89  	return(retval);
    3.90  }