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;
}
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.");
}
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
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)
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);
// 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;
}
}
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);
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);
}
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)) {
volume_set_request = 0; // any external request that has been made is now satisfied
close_mixer();
}
+ pthread_setcancelstate(oldState, NULL);
}
void volume(double vol) {
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
}
}
mute_request_pending = 0;
+
+ pthread_setcancelstate(oldState, NULL);
}
}
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) {
}
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) {
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;
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);
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) {