0007-Fix-ogg123-freeze-when-interrupting-at-End-Of-Stream.patch 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. From: =?utf-8?q?Martin_Stegh=C3=B6fer?= <martin@steghoefer.eu>
  2. Date: Tue, 28 Oct 2014 23:04:19 +0100
  3. Subject: Fix ogg123 freeze when interrupting at End-Of-Stream.
  4. Bug-Debian: https://bugs.debian.org/307325
  5. Forwarded: https://trac.xiph.org/ticket/1956#comment:3
  6. When arriving at the end of the input file, the main thread waits for
  7. the output thread to finish up the current buffer. If a cancellation
  8. signal arrives at that stage, this signal of an empty buffer never
  9. arrives because the output thread bails out before actually emptying
  10. the buffer.
  11. Fix:
  12. 1.) Make sure the output thread wakes up the main thread when bailing
  13. out, so the main thread can go on, too.
  14. 2.) When the main thread wakes up while waiting for an empty buffer,
  15. make sure it understands the situation (that there won't be an empty
  16. buffer because the replay has been cancelled) and doesn't go back to
  17. sleep.
  18. ---
  19. ogg123/buffer.c | 26 +++++++++++++++++++++++---
  20. 1 file changed, 23 insertions(+), 3 deletions(-)
  21. diff --git a/ogg123/buffer.c b/ogg123/buffer.c
  22. index b09c9c9..c7111d2 100644
  23. --- a/ogg123/buffer.c
  24. +++ b/ogg123/buffer.c
  25. @@ -209,8 +209,18 @@ void *buffer_thread_func (void *arg)
  26. never be unset. */
  27. while ( !(buf->eos && buf->curfill == 0) && !buf->abort_write) {
  28. - if (buf->cancel_flag || sig_request.cancel)
  29. + if (buf->cancel_flag || sig_request.cancel) {
  30. + /* signal empty buffer space, so the main
  31. + thread can wake up to die in peace */
  32. +
  33. + DEBUG("Abort: Wake up the writer thread");
  34. + LOCK_MUTEX(buf->mutex);
  35. + COND_SIGNAL(buf->write_cond);
  36. + UNLOCK_MUTEX(buf->mutex);
  37. +
  38. + /* abort this thread, too */
  39. break;
  40. + }
  41. DEBUG("Check for something to play");
  42. /* Block until we can play something */
  43. @@ -227,8 +237,18 @@ void *buffer_thread_func (void *arg)
  44. UNLOCK_MUTEX(buf->mutex);
  45. - if (buf->cancel_flag || sig_request.cancel)
  46. + if (buf->cancel_flag || sig_request.cancel) {
  47. + /* signal empty buffer space, so the main
  48. + thread can wake up to die in peace */
  49. +
  50. + DEBUG("Abort: Wake up the writer thread");
  51. + LOCK_MUTEX(buf->mutex);
  52. + COND_SIGNAL(buf->write_cond);
  53. + UNLOCK_MUTEX(buf->mutex);
  54. +
  55. + /* abort this thread, too */
  56. break;
  57. + }
  58. /* Don't need to lock buffer while running actions since position
  59. won't change. We clear out any actions before we compute the
  60. @@ -756,7 +776,7 @@ void buffer_wait_for_empty (buf_t *buf)
  61. pthread_cleanup_push(buffer_mutex_unlock, buf);
  62. LOCK_MUTEX(buf->mutex);
  63. - while (!empty && !buf->abort_write) {
  64. + while (!empty && !buf->abort_write && !buf->cancel_flag && !sig_request.cancel) {
  65. if (buf->curfill > 0) {
  66. DEBUG1("Buffer curfill = %ld, going back to sleep.", buf->curfill);