Ryan Gordon - Thu May 2 21:08:48 PDT 2002
authorSam Lantinga <slouken@libsdl.org>
Fri, 03 May 2002 04:09:27 +0000
changeset 172fb810079d5f1
parent 171 5f2fbfa3f0af
child 173 0821a4ea0008
Ryan Gordon - Thu May 2 21:08:48 PDT 2002
* Fixed deadlock introduced in the last release
CHANGES
mixer.c
     1.1 --- a/CHANGES	Thu Apr 18 04:45:51 2002 +0000
     1.2 +++ b/CHANGES	Fri May 03 04:09:27 2002 +0000
     1.3 @@ -1,3 +1,7 @@
     1.4 +
     1.5 +1.2.4:
     1.6 +Ryan Gordon - Thu May  2 21:08:48 PDT 2002
     1.7 + * Fixed deadlock introduced in the last release
     1.8  
     1.9  1.2.3:
    1.10  Sam Lantinga - Sat Apr 13 07:49:47 PDT 2002
     2.1 --- a/mixer.c	Thu Apr 18 04:45:51 2002 +0000
     2.2 +++ b/mixer.c	Fri May 03 04:09:27 2002 +0000
     2.3 @@ -41,7 +41,6 @@
     2.4  
     2.5  static int audio_opened = 0;
     2.6  static SDL_AudioSpec mixer;
     2.7 -static SDL_mutex *mixer_lock;
     2.8  
     2.9  typedef struct _Mix_effectinfo
    2.10  {
    2.11 @@ -102,26 +101,22 @@
    2.12  
    2.13  static int _Mix_remove_all_effects(int channel, effect_info **e);
    2.14  
    2.15 -/* rcg06122001 Cleanup effect callbacks. */
    2.16 -static void _Mix_channel_done_playing(int channel, int lockaudio)
    2.17 +/*
    2.18 + * rcg06122001 Cleanup effect callbacks.
    2.19 + *  MAKE SURE SDL_LockAudio() is called before this (or you're in the
    2.20 + *   audio callback).
    2.21 + */
    2.22 +static void _Mix_channel_done_playing(int channel)
    2.23  {
    2.24 -	if (lockaudio) {
    2.25 -		SDL_LockAudio();
    2.26 -	}
    2.27 -
    2.28  	if (channel_done_callback) {
    2.29  	    channel_done_callback(channel);
    2.30  	}
    2.31  
    2.32  	/*
    2.33 -         * Call internal function directly, to avoid locking audio from
    2.34 -         *   inside audio callback.
    2.35 -         */
    2.36 +	 * Call internal function directly, to avoid locking audio from
    2.37 +	 *   inside audio callback.
    2.38 +	 */
    2.39  	_Mix_remove_all_effects(channel, &mix_channel[channel].effects);
    2.40 -
    2.41 -	if (lockaudio) {
    2.42 -		SDL_UnlockAudio();
    2.43 -	}
    2.44  }
    2.45  
    2.46  
    2.47 @@ -165,8 +160,7 @@
    2.48  		mix_music(music_data, stream, len);
    2.49  	}
    2.50  
    2.51 -	/* Grab the channels we need to mix */
    2.52 -	SDL_mutexP(mixer_lock);
    2.53 +	/* Mix any playing channels... */
    2.54  	sdl_ticks = SDL_GetTicks();
    2.55  	for ( i=0; i<num_channels; ++i ) {
    2.56  		if( ! mix_channel[i].paused ) {
    2.57 @@ -235,7 +229,7 @@
    2.58  
    2.59  				/* rcg06072001 Alert app if channel is done playing. */
    2.60  				if (!mix_channel[i].playing) {
    2.61 -					_Mix_channel_done_playing(i, 0);
    2.62 +					_Mix_channel_done_playing(i);
    2.63  				}
    2.64  			}
    2.65  		}
    2.66 @@ -247,7 +241,6 @@
    2.67  	if ( mix_postmix ) {
    2.68  		mix_postmix(mix_postmix_data, stream, len);
    2.69  	}
    2.70 -	SDL_mutexV(mixer_lock);
    2.71  }
    2.72  
    2.73  static void PrintFormat(char *title, SDL_AudioSpec *fmt)
    2.74 @@ -288,20 +281,9 @@
    2.75  	PrintFormat("Audio device", &mixer);
    2.76  #endif
    2.77  
    2.78 -	/* Create the channel lock mutex */
    2.79 -	mixer_lock = SDL_CreateMutex();
    2.80 -#ifndef macintosh /* Hmm.. what implications does this have? */
    2.81 -	if ( mixer_lock == NULL ) {
    2.82 -		SDL_CloseAudio();
    2.83 -		SDL_SetError("Unable to create mixer lock");
    2.84 -		return(-1);
    2.85 -	}
    2.86 -#endif
    2.87 -
    2.88  	/* Initialize the music players */
    2.89  	if ( open_music(&mixer) < 0 ) {
    2.90  		SDL_CloseAudio();
    2.91 -		SDL_DestroyMutex(mixer_lock);
    2.92  		return(-1);
    2.93  	}
    2.94  
    2.95 @@ -343,7 +325,7 @@
    2.96  			Mix_HaltChannel(i);
    2.97  		}
    2.98  	}
    2.99 -	SDL_mutexP(mixer_lock);
   2.100 +	SDL_LockAudio();
   2.101  	mix_channel = (struct _Mix_Channel *) realloc(mix_channel, numchans * sizeof(struct _Mix_Channel));
   2.102  	if ( numchans > num_channels ) {
   2.103  		/* Initialize the new channels */
   2.104 @@ -359,7 +341,7 @@
   2.105  		}
   2.106  	}
   2.107  	num_channels = numchans;
   2.108 -	SDL_mutexV(mixer_lock);
   2.109 +	SDL_UnlockAudio();
   2.110  	return(num_channels);
   2.111  }
   2.112  
   2.113 @@ -526,16 +508,15 @@
   2.114  	/* Caution -- if the chunk is playing, the mixer will crash */
   2.115  	if ( chunk ) {
   2.116  		/* Guarantee that this chunk isn't playing */
   2.117 +		SDL_LockAudio();
   2.118  		if ( mix_channel ) {
   2.119 -			SDL_mutexP(mixer_lock);
   2.120  			for ( i=0; i<num_channels; ++i ) {
   2.121  				if ( chunk == mix_channel[i].chunk ) {
   2.122  					mix_channel[i].playing = 0;
   2.123  				}
   2.124  			}
   2.125 -			SDL_mutexV(mixer_lock);
   2.126  		}
   2.127 -
   2.128 +		SDL_UnlockAudio();
   2.129  		/* Actually free the chunk */
   2.130  		if ( chunk->allocated ) {
   2.131  			free(chunk->abuf);
   2.132 @@ -581,9 +562,9 @@
   2.133  
   2.134  void Mix_ChannelFinished(void (*channel_finished)(int channel))
   2.135  {
   2.136 -    SDL_LockAudio();
   2.137 -    channel_done_callback = channel_finished;
   2.138 -    SDL_UnlockAudio();
   2.139 +	SDL_LockAudio();
   2.140 +	channel_done_callback = channel_finished;
   2.141 +	SDL_UnlockAudio();
   2.142  }
   2.143  
   2.144  
   2.145 @@ -615,7 +596,7 @@
   2.146  	}
   2.147  
   2.148  	/* Lock the mixer while modifying the playing channels */
   2.149 -	SDL_mutexP(mixer_lock);
   2.150 +	SDL_LockAudio();
   2.151  	{
   2.152  		/* If which is -1, play on the first free channel */
   2.153  		if ( which == -1 ) {
   2.154 @@ -634,7 +615,7 @@
   2.155  		if ( which >= 0 ) {
   2.156  			Uint32 sdl_ticks = SDL_GetTicks();
   2.157  			if (Mix_Playing(which))
   2.158 -				_Mix_channel_done_playing(which, 1);
   2.159 +				_Mix_channel_done_playing(which);
   2.160  			mix_channel[which].samples = chunk->abuf;
   2.161  			mix_channel[which].playing = chunk->alen;
   2.162  			mix_channel[which].looping = loops;
   2.163 @@ -645,7 +626,7 @@
   2.164  			mix_channel[which].expire = (ticks>0) ? (sdl_ticks + ticks) : 0;
   2.165  		}
   2.166  	}
   2.167 -	SDL_mutexV(mixer_lock);
   2.168 +	SDL_UnlockAudio();
   2.169  
   2.170  	/* Return the channel on which the sound is being played */
   2.171  	return(which);
   2.172 @@ -662,9 +643,9 @@
   2.173  			status += Mix_ExpireChannel(i, ticks);
   2.174  		}
   2.175  	} else if ( which < num_channels ) {
   2.176 -		SDL_mutexP(mixer_lock);
   2.177 +		SDL_LockAudio();
   2.178  		mix_channel[which].expire = (ticks>0) ? (SDL_GetTicks() + ticks) : 0;
   2.179 -		SDL_mutexV(mixer_lock);
   2.180 +		SDL_UnlockAudio();
   2.181  		++ status;
   2.182  	}
   2.183  	return(status);
   2.184 @@ -681,7 +662,7 @@
   2.185  	}
   2.186  
   2.187  	/* Lock the mixer while modifying the playing channels */
   2.188 -	SDL_mutexP(mixer_lock);
   2.189 +	SDL_LockAudio();
   2.190  	{
   2.191  		/* If which is -1, play on the first free channel */
   2.192  		if ( which == -1 ) {
   2.193 @@ -700,7 +681,7 @@
   2.194  		if ( which >= 0 ) {
   2.195  			Uint32 sdl_ticks = SDL_GetTicks();
   2.196  			if (Mix_Playing(which))
   2.197 -				_Mix_channel_done_playing(which, 1);
   2.198 +				_Mix_channel_done_playing(which);
   2.199  			mix_channel[which].samples = chunk->abuf;
   2.200  			mix_channel[which].playing = chunk->alen;
   2.201  			mix_channel[which].looping = loops;
   2.202 @@ -714,7 +695,7 @@
   2.203  			mix_channel[which].expire = (ticks > 0) ? (sdl_ticks+ticks) : 0;
   2.204  		}
   2.205  	}
   2.206 -	SDL_mutexV(mixer_lock);
   2.207 +	SDL_UnlockAudio();
   2.208  
   2.209  	/* Return the channel on which the sound is being played */
   2.210  	return(which);
   2.211 @@ -768,16 +749,16 @@
   2.212  			Mix_HaltChannel(i);
   2.213  		}
   2.214  	} else {
   2.215 -		SDL_mutexP(mixer_lock);
   2.216 +		SDL_LockAudio();
   2.217  		if (mix_channel[which].playing) {
   2.218 -			_Mix_channel_done_playing(which, 1);
   2.219 +			_Mix_channel_done_playing(which);
   2.220  		mix_channel[which].playing = 0;
   2.221  		}
   2.222  		mix_channel[which].expire = 0;
   2.223  		if(mix_channel[which].fading != MIX_NO_FADING) /* Restore volume */
   2.224  			mix_channel[which].volume = mix_channel[which].fade_volume;
   2.225  		mix_channel[which].fading = MIX_NO_FADING;
   2.226 -		SDL_mutexV(mixer_lock);
   2.227 +		SDL_UnlockAudio();
   2.228  	}
   2.229  	return(0);
   2.230  }
   2.231 @@ -809,7 +790,7 @@
   2.232  				status += Mix_FadeOutChannel(i, ms);
   2.233  			}
   2.234  		} else {
   2.235 -			SDL_mutexP(mixer_lock);
   2.236 +			SDL_LockAudio();
   2.237  			if ( mix_channel[which].playing && 
   2.238  			    (mix_channel[which].volume > 0) &&
   2.239  			    (mix_channel[which].fading != MIX_FADING_OUT) ) {
   2.240 @@ -820,7 +801,7 @@
   2.241  				mix_channel[which].ticks_fade = SDL_GetTicks();
   2.242  				++status;
   2.243  			}
   2.244 -			SDL_mutexV(mixer_lock);
   2.245 +			SDL_UnlockAudio();
   2.246  		}
   2.247  	}
   2.248  	return(status);
   2.249 @@ -898,7 +879,6 @@
   2.250  			close_music();
   2.251  			Mix_HaltChannel(-1);
   2.252  			SDL_CloseAudio();
   2.253 -			SDL_DestroyMutex(mixer_lock);
   2.254  			free(mix_channel);
   2.255  			mix_channel = NULL;
   2.256  		}
   2.257 @@ -929,10 +909,11 @@
   2.258  void Mix_Resume(int which)
   2.259  {
   2.260  	Uint32 sdl_ticks = SDL_GetTicks();
   2.261 +
   2.262 +	SDL_LockAudio();
   2.263  	if ( which == -1 ) {
   2.264  		int i;
   2.265  
   2.266 -		SDL_mutexP(mixer_lock);
   2.267  		for ( i=0; i<num_channels; ++i ) {
   2.268  			if ( mix_channel[i].playing > 0 ) {
   2.269  				if(mix_channel[i].expire > 0)
   2.270 @@ -940,16 +921,14 @@
   2.271  				mix_channel[i].paused = 0;
   2.272  			}
   2.273  		}
   2.274 -		SDL_mutexV(mixer_lock);
   2.275  	} else {
   2.276 -		SDL_mutexP(mixer_lock);
   2.277  		if ( mix_channel[which].playing > 0 ) {
   2.278  			if(mix_channel[which].expire > 0)
   2.279  				mix_channel[which].expire += sdl_ticks - mix_channel[which].paused;
   2.280  			mix_channel[which].paused = 0;
   2.281  		}
   2.282 -		SDL_mutexV(mixer_lock);
   2.283  	}
   2.284 +	SDL_UnlockAudio();
   2.285  }
   2.286  
   2.287  int Mix_Paused(int which)
   2.288 @@ -976,9 +955,9 @@
   2.289  	if ( which < 0 || which > num_channels )
   2.290  		return(0);
   2.291  
   2.292 -	SDL_mutexP(mixer_lock);
   2.293 +	SDL_LockAudio();
   2.294  	mix_channel[which].tag = tag;
   2.295 -	SDL_mutexV(mixer_lock);
   2.296 +	SDL_UnlockAudio();
   2.297  	return(1);
   2.298  }
   2.299