diff options
| author | Lars-Dominik Braun <lars@6xq.net> | 2012-05-16 14:18:27 +0200 | 
|---|---|---|
| committer | Lars-Dominik Braun <lars@6xq.net> | 2012-05-17 21:55:57 +0200 | 
| commit | f6dffd1822404522b8354ac453a911a0d98bfc61 (patch) | |
| tree | 46fec199f0e4e5f59588f75c5ed1446a06e13367 /src | |
| parent | c922257347ee0cf5ea6cdd65786da2774c79c132 (diff) | |
| download | pianobar-windows-f6dffd1822404522b8354ac453a911a0d98bfc61.tar.gz pianobar-windows-f6dffd1822404522b8354ac453a911a0d98bfc61.tar.bz2 pianobar-windows-f6dffd1822404522b8354ac453a911a0d98bfc61.zip | |
Fix player thread teardown/signals on OS X
1) Realtime signals don’t exist in OS X
2) libao apparently locks a mutex in ao_play, which is locked again in
   ao_close and causes a deadlock
Closes #256, although I’m considering the option of partially reverting
7df9371491e96a99c1e463f7787aede352ac5a37, as this introduces more nasty
behavior than it solves.
Diffstat (limited to 'src')
| -rw-r--r-- | src/player.c | 10 | ||||
| -rw-r--r-- | src/player.h | 4 | ||||
| -rw-r--r-- | src/ui_act.c | 4 | 
3 files changed, 16 insertions, 2 deletions
| diff --git a/src/player.c b/src/player.c index b743ee8..f53feaa 100644 --- a/src/player.c +++ b/src/player.c @@ -156,9 +156,15 @@ static WaitressCbReturn_t BarPlayerAACCb (void *ptr, size_t size,  			for (i = 0; i < frameInfo.samples; i++) {  				aacDecoded[i] = applyReplayGain (aacDecoded[i], player->scale);  			} + +			int oldstate; +			pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);  			/* ao_play needs bytes: 1 sample = 16 bits = 2 bytes */  			ao_play (player->audioOutDevice, (char *) aacDecoded,  					frameInfo.samples * 2); +			pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &oldstate); +			pthread_testcancel(); +  			/* add played frame length to played time, explained below */  			player->songPlayed += (unsigned long long int) frameInfo.samples *  					(unsigned long long int) BAR_PLAYER_MS_TO_S_FACTOR / @@ -385,9 +391,13 @@ static WaitressCbReturn_t BarPlayerMp3Cb (void *ptr, size_t size,  			 * be visible to user (ugly, but mp3 decoding != aac decoding) */  			player->mode = PLAYER_RECV_DATA;  		} +		int oldstate; +		pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);  		/* samples * length * channels */  		ao_play (player->audioOutDevice, (char *) madDecoded,  				player->mp3Synth.pcm.length * 2 * 2); +		pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &oldstate); +		pthread_testcancel();  		/* avoid division by 0 */  		if (player->mode == PLAYER_RECV_DATA) { diff --git a/src/player.h b/src/player.h index 2261d44..1e04f9f 100644 --- a/src/player.h +++ b/src/player.h @@ -47,8 +47,8 @@ THE SOFTWARE.  #define BAR_PLAYER_MS_TO_S_FACTOR 1000  #define BAR_PLAYER_BUFSIZE (WAITRESS_BUFFER_SIZE*2) -#define BAR_PLAYER_SIGSTOP SIGRTMIN -#define BAR_PLAYER_SIGCONT SIGRTMIN+1 +#define BAR_PLAYER_SIGSTOP SIGUSR1 +#define BAR_PLAYER_SIGCONT SIGUSR2  struct audioPlayer {  	unsigned char channels; diff --git a/src/ui_act.c b/src/ui_act.c index 2cc3197..a4fc1f7 100644 --- a/src/ui_act.c +++ b/src/ui_act.c @@ -54,6 +54,10 @@ static inline void BarUiDoSkipSong (struct audioPlayer *player) {  	assert (player != NULL);  	if (player->mode != PLAYER_FINISHED_PLAYBACK && player->mode != PLAYER_FREED) { +		/* unpause to make sure thread is able to reach cancellation point */ +		if (player->paused) { +			pthread_kill (player->thread, BAR_PLAYER_SIGCONT); +		}  		pthread_cancel (player->thread);  	}  } | 
