audio_pt_int.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include "qemu/osdep.h"
  2. #include "qemu-common.h"
  3. #include "audio.h"
  4. #define AUDIO_CAP "audio-pt"
  5. #include "audio_int.h"
  6. #include "audio_pt_int.h"
  7. static void GCC_FMT_ATTR(3, 4) logerr (struct audio_pt *pt, int err,
  8. const char *fmt, ...)
  9. {
  10. va_list ap;
  11. va_start (ap, fmt);
  12. AUD_vlog (pt->drv, fmt, ap);
  13. va_end (ap);
  14. AUD_log (NULL, "\n");
  15. AUD_log (pt->drv, "Reason: %s\n", strerror (err));
  16. }
  17. int audio_pt_init (struct audio_pt *p, void *(*func) (void *),
  18. void *opaque, const char *drv, const char *cap)
  19. {
  20. int err, err2;
  21. const char *efunc;
  22. sigset_t set, old_set;
  23. p->drv = drv;
  24. err = sigfillset (&set);
  25. if (err) {
  26. logerr (p, errno, "%s(%s): sigfillset failed", cap, AUDIO_FUNC);
  27. return -1;
  28. }
  29. err = pthread_mutex_init (&p->mutex, NULL);
  30. if (err) {
  31. efunc = "pthread_mutex_init";
  32. goto err0;
  33. }
  34. err = pthread_cond_init (&p->cond, NULL);
  35. if (err) {
  36. efunc = "pthread_cond_init";
  37. goto err1;
  38. }
  39. err = pthread_sigmask (SIG_BLOCK, &set, &old_set);
  40. if (err) {
  41. efunc = "pthread_sigmask";
  42. goto err2;
  43. }
  44. err = pthread_create (&p->thread, NULL, func, opaque);
  45. err2 = pthread_sigmask (SIG_SETMASK, &old_set, NULL);
  46. if (err2) {
  47. logerr (p, err2, "%s(%s): pthread_sigmask (restore) failed",
  48. cap, AUDIO_FUNC);
  49. /* We have failed to restore original signal mask, all bets are off,
  50. so terminate the process */
  51. exit (EXIT_FAILURE);
  52. }
  53. if (err) {
  54. efunc = "pthread_create";
  55. goto err2;
  56. }
  57. return 0;
  58. err2:
  59. err2 = pthread_cond_destroy (&p->cond);
  60. if (err2) {
  61. logerr (p, err2, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC);
  62. }
  63. err1:
  64. err2 = pthread_mutex_destroy (&p->mutex);
  65. if (err2) {
  66. logerr (p, err2, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC);
  67. }
  68. err0:
  69. logerr (p, err, "%s(%s): %s failed", cap, AUDIO_FUNC, efunc);
  70. return -1;
  71. }
  72. int audio_pt_fini (struct audio_pt *p, const char *cap)
  73. {
  74. int err, ret = 0;
  75. err = pthread_cond_destroy (&p->cond);
  76. if (err) {
  77. logerr (p, err, "%s(%s): pthread_cond_destroy failed", cap, AUDIO_FUNC);
  78. ret = -1;
  79. }
  80. err = pthread_mutex_destroy (&p->mutex);
  81. if (err) {
  82. logerr (p, err, "%s(%s): pthread_mutex_destroy failed", cap, AUDIO_FUNC);
  83. ret = -1;
  84. }
  85. return ret;
  86. }
  87. int audio_pt_lock (struct audio_pt *p, const char *cap)
  88. {
  89. int err;
  90. err = pthread_mutex_lock (&p->mutex);
  91. if (err) {
  92. logerr (p, err, "%s(%s): pthread_mutex_lock failed", cap, AUDIO_FUNC);
  93. return -1;
  94. }
  95. return 0;
  96. }
  97. int audio_pt_unlock (struct audio_pt *p, const char *cap)
  98. {
  99. int err;
  100. err = pthread_mutex_unlock (&p->mutex);
  101. if (err) {
  102. logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC);
  103. return -1;
  104. }
  105. return 0;
  106. }
  107. int audio_pt_wait (struct audio_pt *p, const char *cap)
  108. {
  109. int err;
  110. err = pthread_cond_wait (&p->cond, &p->mutex);
  111. if (err) {
  112. logerr (p, err, "%s(%s): pthread_cond_wait failed", cap, AUDIO_FUNC);
  113. return -1;
  114. }
  115. return 0;
  116. }
  117. int audio_pt_unlock_and_signal (struct audio_pt *p, const char *cap)
  118. {
  119. int err;
  120. err = pthread_mutex_unlock (&p->mutex);
  121. if (err) {
  122. logerr (p, err, "%s(%s): pthread_mutex_unlock failed", cap, AUDIO_FUNC);
  123. return -1;
  124. }
  125. err = pthread_cond_signal (&p->cond);
  126. if (err) {
  127. logerr (p, err, "%s(%s): pthread_cond_signal failed", cap, AUDIO_FUNC);
  128. return -1;
  129. }
  130. return 0;
  131. }
  132. int audio_pt_join (struct audio_pt *p, void **arg, const char *cap)
  133. {
  134. int err;
  135. void *ret;
  136. err = pthread_join (p->thread, &ret);
  137. if (err) {
  138. logerr (p, err, "%s(%s): pthread_join failed", cap, AUDIO_FUNC);
  139. return -1;
  140. }
  141. *arg = ret;
  142. return 0;
  143. }