diff --git a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c index 3a841ad0d..2b3a5b4be 100644 --- a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c +++ b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c @@ -46,7 +46,6 @@ struct rdpsnd_alsa_plugin rdpsndDevicePlugin device; HANDLE mutex; - HANDLE thread; char* device_name; snd_pcm_t* pcm_handle; snd_mixer_t* mixer_handle; @@ -80,7 +79,7 @@ static void rdpsnd_alsa_set_params(rdpsndAlsaPlugin* alsa) snd_pcm_drop(alsa->pcm_handle); #ifdef RDPSND_ALSA_ASYNC - //snd_async_add_pcm_handler(&alsa->pcm_callback, alsa->pcm_handle, rdpsnd_alsa_async_handler, (void*) alsa); + snd_async_add_pcm_handler(&alsa->pcm_callback, alsa->pcm_handle, rdpsnd_alsa_async_handler, (void*) alsa); #endif status = snd_pcm_hw_params_malloc(&hw_params); @@ -246,7 +245,10 @@ static void rdpsnd_alsa_open(rdpsndDevicePlugin* device, rdpsndFormat* format, i DEBUG_SVC("opening"); mode = 0; - //mode |= SND_PCM_NONBLOCK; + +#ifdef RDPSND_ALSA_ASYNC + mode |= SND_PCM_NONBLOCK; +#endif status = snd_pcm_open(&alsa->pcm_handle, alsa->device_name, SND_PCM_STREAM_PLAYBACK, mode); @@ -374,6 +376,7 @@ void rdpsnd_alsa_process_audio_data(rdpsndAlsaPlugin* alsa) BYTE* pindex; int rbytes_per_frame; int sbytes_per_frame; + snd_pcm_sframes_t avail; sbytes_per_frame = alsa->source_channels * alsa->bytes_per_channel; rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel; @@ -382,18 +385,24 @@ void rdpsnd_alsa_process_audio_data(rdpsndAlsaPlugin* alsa) pindex = alsa->audio_data; end = pindex + alsa->audio_data_left; + avail = snd_pcm_avail_update(alsa->pcm_handle); while (pindex + alsa->period_size * rbytes_per_frame <= end) { length = end - pindex; status = snd_pcm_writei(alsa->pcm_handle, pindex, alsa->period_size); + avail = snd_pcm_avail_update(alsa->pcm_handle); if (status == -EPIPE) { snd_pcm_recover(alsa->pcm_handle, status, 0); status = 0; } + else if (status == -EAGAIN) + { + break; + } else if (status < 0) { DEBUG_WARN("snd_pcm_writei status %d", status); @@ -418,14 +427,11 @@ void rdpsnd_alsa_process_audio_data(rdpsndAlsaPlugin* alsa) void rdpsnd_alsa_async_handler(snd_async_handler_t* pcm_callback) { snd_pcm_t* pcm_handle; - snd_pcm_sframes_t avail; rdpsndAlsaPlugin* alsa; pcm_handle = snd_async_handler_get_pcm(pcm_callback); alsa = (rdpsndAlsaPlugin*) snd_async_handler_get_callback_private(pcm_callback); - avail = snd_pcm_avail_update(pcm_handle); - rdpsnd_alsa_process_audio_data(alsa); } @@ -501,9 +507,7 @@ static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, BYTE* data, int size) ReleaseMutex(alsa->mutex); -#ifndef RDPSND_ALSA_ASYNC rdpsnd_alsa_process_audio_data(alsa); -#endif } static void rdpsnd_alsa_start(rdpsndDevicePlugin* device) @@ -516,21 +520,6 @@ static void rdpsnd_alsa_start(rdpsndDevicePlugin* device) snd_pcm_start(alsa->pcm_handle); } -void* rdpsnd_alsa_thread(void* arg) -{ - rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) arg; - - while (1) - { - if (alsa->pcm_handle) - rdpsnd_alsa_process_audio_data(alsa); - - Sleep(10); - } - - return NULL; -} - COMMAND_LINE_ARGUMENT_A rdpsnd_alsa_args[] = { { "dev", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "device" }, @@ -593,10 +582,6 @@ int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pE alsa->mutex = CreateMutex(NULL, FALSE, NULL); -#ifdef RDPSND_ALSA_ASYNC - alsa->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpsnd_alsa_thread, (void*) alsa, 0, NULL); -#endif - if (!alsa->device_name) alsa->device_name = _strdup("default"); diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 1f19ca506..cbf031e54 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "rdpsnd_main.h" @@ -408,9 +409,9 @@ static void rdpsnd_process_message_setvolume(rdpsndPlugin* rdpsnd, STREAM* data_ static void rdpsnd_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) { - rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin; BYTE msgType; UINT16 BodySize; + rdpsndPlugin* rdpsnd = (rdpsndPlugin*) plugin; if (rdpsnd->expectingWave) { @@ -577,7 +578,6 @@ static void rdpsnd_process_connect(rdpSvcPlugin* plugin) DEBUG_SVC("connecting"); rdpsnd->latency = -1; - rdpsnd->MsgPipe = MessagePipe_New(); rdpsnd->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpsnd_schedule_thread, (void*) plugin, 0, NULL); @@ -674,6 +674,15 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) _p->plugin.event_callback = rdpsnd_process_event; _p->plugin.terminate_callback = rdpsnd_process_terminate; +#ifndef _WIN32 + { + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGIO); + pthread_sigmask(SIG_BLOCK, &mask, NULL); + } +#endif + svc_plugin_init((rdpSvcPlugin*) _p, pEntryPoints); return 1; diff --git a/libfreerdp/utils/signal.c b/libfreerdp/utils/signal.c index 5e7ebce3e..82cdec9ad 100644 --- a/libfreerdp/utils/signal.c +++ b/libfreerdp/utils/signal.c @@ -64,46 +64,49 @@ static void fatal_handler(int signum) raise(signum); } -int freerdp_handle_signals(void) +const int fatal_signals[] = { - const int fatal_signals[] = { - SIGABRT, - SIGALRM, - SIGBUS, - SIGFPE, - SIGHUP, - SIGILL, - SIGINT, - SIGKILL, - SIGPIPE, - SIGQUIT, - SIGSEGV, - SIGSTOP, - SIGTERM, - SIGTSTP, - SIGTTIN, - SIGTTOU, - SIGUSR1, - SIGUSR2, + SIGABRT, + SIGALRM, + SIGBUS, + SIGFPE, + SIGHUP, + SIGILL, + SIGINT, + SIGKILL, + SIGPIPE, + SIGQUIT, + SIGSEGV, + SIGSTOP, + SIGTERM, + SIGTSTP, + SIGTTIN, + SIGTTOU, + SIGUSR1, + SIGUSR2, #ifdef SIGPOLL - SIGPOLL, + SIGPOLL, #endif #ifdef SIGPROF - SIGPROF, + SIGPROF, #endif #ifdef SIGSYS - SIGSYS, + SIGSYS, #endif - SIGTRAP, + SIGTRAP, #ifdef SIGVTALRM - SIGVTALRM, + SIGVTALRM, #endif - SIGXCPU, - SIGXFSZ - }; + SIGXCPU, + SIGXFSZ +}; + +int freerdp_handle_signals(void) +{ int signal_index; sigset_t orig_set; - struct sigaction orig_sigaction, fatal_sigaction; + struct sigaction orig_sigaction; + struct sigaction fatal_sigaction; sigfillset(&(fatal_sigaction.sa_mask)); sigdelset(&(fatal_sigaction.sa_mask), SIGCONT); @@ -112,16 +115,19 @@ int freerdp_handle_signals(void) fatal_sigaction.sa_handler = fatal_handler; fatal_sigaction.sa_flags = 0; - for (signal_index = 0; - signal_index < ARRAYSIZE(fatal_signals); - signal_index++) - if (sigaction(fatal_signals[signal_index], - NULL, &orig_sigaction) == 0) + for (signal_index = 0; signal_index < ARRAYSIZE(fatal_signals); signal_index++) + { + if (sigaction(fatal_signals[signal_index], NULL, &orig_sigaction) == 0) + { if (orig_sigaction.sa_handler != SIG_IGN) - sigaction(fatal_signals[signal_index], - &fatal_sigaction, NULL); + { + sigaction(fatal_signals[signal_index], &fatal_sigaction, NULL); + } + } + } pthread_sigmask(SIG_SETMASK, &orig_set, NULL); + return 0; }