Make some alsa operation sequences un-cancellable. Make some cleanup sequences un-cancellable.
This commit is contained in:
+30
-3
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user