static int suspend(struct userdata *u) {
int32_t ret;
pa_assert(u);
- pa_assert(u->pcm_handle);
- ret = pa_hal_interface_pcm_close(u->hal_interface, u->pcm_handle);
- if (ret) {
- pa_log_error("Error closing PCM device %x", ret);
+ /* suspend could be called by set_state function while waiting for PA_MESSAGE_SHUTDOWN */
+ if (!u->pcm_handle) {
+ pa_log_error("pcm_handle is null. PCM is going to be shutdown due to the recovering failure");
+ return 0;
}
+
+ ret = pa_hal_interface_pcm_close(u->hal_interface, u->pcm_handle);
+ if (ret)
+ pa_log_error("Error closing PCM device. rtpoll will be stopped anyway");
+
u->pcm_handle = NULL;
if (u->rtpoll_item) {
pa_log_info("Device suspended...");
- return 0;
+ return ret;
}
/* Called from IO context */
pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
revents = pollfd->revents;
if (revents & ~POLLOUT) {
- pa_log_debug("Poll error 0x%x occured, try recover.", revents);
- pa_hal_interface_pcm_recover(u->hal_interface, u->pcm_handle, revents);
+ pa_log_error("Poll error 0x%x occured, try recover.", revents);
+
+ if (pa_hal_interface_pcm_recover(u->hal_interface, u->pcm_handle, revents)) {
+ pa_log_warn("Try to suspend and unsuspend for recovering the pcm device");
+
+ if (suspend(u)) {
+ pa_log_error("Failed to suspend!. This thread is going to shutdown.");
+ goto fail;
+ }
+ if (unsuspend(u)) {
+ pa_log_error("Failed to unsuspend!. This thread is going to shutdown.");
+ goto fail;
+ }
+ }
+
u->first = true;
revents = 0;
}
static int suspend(struct userdata *u) {
int32_t ret;
pa_assert(u);
- pa_assert(u->pcm_handle);
- ret = pa_hal_interface_pcm_close(u->hal_interface, u->pcm_handle);
- if (ret) {
- pa_log_error("Error closing PCM device %x", ret);
+ /* suspend could be called by set_state function while waiting for PA_MESSAGE_SHUTDOWN */
+ if (!u->pcm_handle) {
+ pa_log_error("pcm_handle is null. PCM is going to be shutdown due to the recovering failure");
+ return 0;
}
+
+ ret = pa_hal_interface_pcm_close(u->hal_interface, u->pcm_handle);
+ if (ret)
+ pa_log_error("Error closing PCM device. rtpoll will be stopped anyway");
+
u->pcm_handle = NULL;
if (u->rtpoll_item) {
pa_log_info("Device suspended...");
- return 0;
+ return ret;
}
/* Called from IO context */
pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
revents = pollfd->revents;
if (revents & ~POLLIN) {
- pa_log_debug("Poll error 0x%x occured, try recover.", revents);
- pa_hal_interface_pcm_recover(u->hal_interface, u->pcm_handle, revents);
+ pa_log_error("Poll error 0x%x occured, try recover.", revents);
+
+ if (pa_hal_interface_pcm_recover(u->hal_interface, u->pcm_handle, revents)) {
+ pa_log_warn("Try to suspend and unsuspend for recovering the pcm device");
+
+ if (suspend(u)) {
+ pa_log_error("Failed to suspend!. This thread is going to shutdown.");
+ goto fail;
+ }
+ if (unsuspend(u)) {
+ pa_log_error("Failed to unsuspend!. This thread is going to shutdown.");
+ goto fail;
+ }
+ }
+
u->first = true;
revents = 0;
}