Make some alsa operation sequences un-cancellable. Make some cleanup sequences un-cancellable.

This commit is contained in:
Mike Brady
2018-11-24 22:28:52 +00:00
parent 57ae8ad846
commit 3b4654df77
2 changed files with 49 additions and 7 deletions
+30 -3
View File
@@ -405,6 +405,8 @@ static int init(int argc, char **argv) {
debug(1, "alsa output device name is \"%s\".", alsa_out_dev);
if (hardware_mixer) {
int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
if (alsa_mix_dev == NULL)
alsa_mix_dev = alsa_out_dev;
@@ -491,6 +493,7 @@ static int init(int argc, char **argv) {
}
debug_mutex_unlock(&alsa_mutex, 3); // release the mutex
pthread_cleanup_pop(0);
pthread_setcancelstate(oldState, NULL);
} else {
// debug(1, "Has no mixer and thus no hardware mute.");
}
@@ -504,7 +507,7 @@ static void deinit(void) {
stop();
}
int open_alsa_device(void) {
int actual_open_alsa_device(void) {
// the alsa mutex is already acquired when this is called
const snd_pcm_uframes_t minimal_buffer_headroom =
352 * 2; // we accept this much headroom in the hardware buffer, but we'll
@@ -851,6 +854,15 @@ int open_alsa_device(void) {
return 0;
}
int open_alsa_device(void) {
int result;
int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
result = actual_open_alsa_device();
pthread_setcancelstate(oldState, NULL);
return result;
}
static void start(int i_sample_rate, int i_sample_format) {
// debug(2,"audio_alsa start called.");
if (i_sample_rate == 0)
@@ -874,6 +886,8 @@ int delay(long *the_delay) {
if (alsa_handle == NULL) {
return -ENODEV;
} else {
int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 1);
int derr;
snd_pcm_state_t dac_state = snd_pcm_state(alsa_handle);
@@ -926,6 +940,7 @@ int delay(long *the_delay) {
// here, occasionally pretend there's a problem with pcm_get_delay()
// if ((random() % 100000) < 3) // keep it pretty rare
// reply = -EIO; // pretend something bad has happened
pthread_setcancelstate(oldState, NULL);
return reply;
}
}
@@ -945,10 +960,13 @@ int get_rate_information(uint64_t *elapsed_time, uint64_t *frames_played) {
static int play(void *buf, int samples) {
// debug(3,"audio_alsa play called.");
int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
int ret = 0;
if (alsa_handle == NULL) {
pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 1);
ret = open_alsa_device();
ret = actual_open_alsa_device();
if (ret == 0) {
if (audio_alsa.volume)
do_volume(set_volume);
@@ -1047,13 +1065,14 @@ static int play(void *buf, int samples) {
debug_mutex_unlock(&alsa_mutex, 3);
pthread_cleanup_pop(0); // release the mutex
}
pthread_setcancelstate(oldState, NULL);
return ret;
}
static void flush(void) {
// debug(2,"audio_alsa flush called.");
int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
pthread_cleanup_debug_mutex_lock(&alsa_mutex, 10000, 1);
int derr;
do_mute(1);
@@ -1094,6 +1113,8 @@ static void parameters(audio_parameters *info) {
}
void do_volume(double vol) { // caller is assumed to have the alsa_mutex when using this function
int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
debug(3, "Setting volume db to %f.", vol);
set_volume = vol;
if (volume_set_request && (open_mixer() == 1)) {
@@ -1125,6 +1146,7 @@ void do_volume(double vol) { // caller is assumed to have the alsa_mutex when us
volume_set_request = 0; // any external request that has been made is now satisfied
close_mixer();
}
pthread_setcancelstate(oldState, NULL);
}
void volume(double vol) {
@@ -1165,6 +1187,9 @@ static void mute(int mute_state_requested) {
void do_mute(int mute_state_requested) {
int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState); // make this un-cancellable
// if a mute is requested now, then
// if an external mute request is in place, leave everything muted
// otherwise, if an external mute request is pending, action it
@@ -1205,4 +1230,6 @@ void do_mute(int mute_state_requested) {
}
}
mute_request_pending = 0;
pthread_setcancelstate(oldState, NULL);
}
+19 -4
View File
@@ -98,14 +98,16 @@ uint64_t local_to_remote_time_difference_now(rtsp_conn_info *conn) {
}
void rtp_audio_receiver_cleanup_handler(void *arg) {
int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
debug(3, "Audio Receiver Cleanup.");
rtsp_conn_info *conn = (rtsp_conn_info *)arg;
debug(3, "shutdown audio socket.");
shutdown(conn->audio_socket, SHUT_RDWR);
debug(3, "close audio socket.");
close(conn->audio_socket);
debug(3, "Audio Receiver Cleanup Successful.");
debug(3, "Connection %d: Audio Receiver Cleanup.", conn->connection_number);
pthread_setcancelstate(oldState, NULL);
}
void *rtp_audio_receiver(void *arg) {
@@ -240,13 +242,16 @@ void *rtp_audio_receiver(void *arg) {
}
void rtp_control_handler_cleanup_handler(void *arg) {
int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
debug(3, "Control Receiver Cleanup.");
rtsp_conn_info *conn = (rtsp_conn_info *)arg;
debug(3, "shutdown control socket.");
shutdown(conn->control_socket, SHUT_RDWR);
debug(3, "close control socket.");
close(conn->control_socket);
debug(3, "Control Receiver Cleanup Successful.");
debug(3, "Connection %d: Control Receiver Cleanup.", conn->connection_number);
pthread_setcancelstate(oldState, NULL);
}
void *rtp_control_receiver(void *arg) {
@@ -495,7 +500,13 @@ void *rtp_control_receiver(void *arg) {
pthread_exit(NULL);
}
void rtp_timing_sender_cleanup_handler(void *arg) {
rtsp_conn_info *conn = (rtsp_conn_info *)arg;
debug(3, "Connection %d: Timing Sender Cleanup.", conn->connection_number);
}
void *rtp_timing_sender(void *arg) {
pthread_cleanup_push(rtp_timing_sender_cleanup_handler, arg);
rtsp_conn_info *conn = (rtsp_conn_info *)arg;
struct timing_request {
char leader;
@@ -555,10 +566,13 @@ void *rtp_timing_sender(void *arg) {
usleep(3000000);
}
debug(3, "rtp_timing_sender thread interrupted. This should never happen.");
pthread_cleanup_pop(0); // don't execute anything here.
pthread_exit(NULL);
}
void rtp_timing_receiver_cleanup_handler(void *arg) {
int oldState;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
debug(3, "Timing Receiver Cleanup.");
rtsp_conn_info *conn = (rtsp_conn_info *)arg;
pthread_cancel(conn->timer_requester);
@@ -567,7 +581,8 @@ void rtp_timing_receiver_cleanup_handler(void *arg) {
shutdown(conn->timing_socket, SHUT_RDWR);
debug(3, "close timing socket.");
close(conn->timing_socket);
debug(3, "Timing Receiver Cleanup Successful.");
debug(3, "Connection %d: Timing Receiver Cleanup.", conn->connection_number);
pthread_setcancelstate(oldState, NULL);
}
void *rtp_timing_receiver(void *arg) {