[1/3] pcm_local: Add snd_pcm_is_locked
diff mbox series

Message ID 20190922032853.6123-2-thematrixeatsyou@gmail.com
State New
Headers show
Series
  • Make pcm_ioplug check lock status before locking (fixes pcm_jack lockups)
Related show

Commit Message

Ben Russell Sept. 22, 2019, 3:28 a.m. UTC
This is needed in preparation for a fix to be applied to
pcm_ioplug which will be in a following commit.

Signed-off-by: Ben Russell <thematrixeatsyou@gmail.com>
---
 src/pcm/pcm_local.h | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

Patch
diff mbox series

diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index 05ed935f..649d84f2 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -1171,9 +1171,41 @@  static inline void snd_pcm_unlock(snd_pcm_t *pcm)
 	if (pcm->lock_enabled && pcm->need_lock)
 		pthread_mutex_unlock(&pcm->lock);
 }
+
+/*
+ * snd_pcm_is_locked() is used to determine if the lock is currently held.
+ * It is mostly provided as a workaround for pcm_ioplug, which otherwise would
+ * for some functions assume that the plugin is locked even when it isn't.
+ *
+ * If $LIBASOUND_THREAD_SAFE=0 is set then this always returns 0 as there
+ * is no mutex in that case.
+ */
+static inline int snd_pcm_is_locked(snd_pcm_t *pcm)
+{
+	int trylock_result;
+	int unlock_result;
+
+	if (pcm->lock_enabled) {
+		trylock_result = pthread_mutex_trylock(&pcm->lock);
+		assert(trylock_result == 0 || trylock_result == EBUSY);
+		if (trylock_result == 0) {
+			/* we managed to grab the lock; therefore, it wasn't locked */
+			unlock_result = pthread_mutex_unlock(&pcm->lock);
+			assert(unlock_result == 0);
+			return 0;
+		} else {
+			/* we failed to grab the lock; therefore, it was locked */
+			return 1;
+		}
+	} else {
+		return 0;
+	}
+}
+
 #else /* THREAD_SAFE_API */
 #define __snd_pcm_lock(pcm)		do {} while (0)
 #define __snd_pcm_unlock(pcm)		do {} while (0)
 #define snd_pcm_lock(pcm)		do {} while (0)
 #define snd_pcm_unlock(pcm)		do {} while (0)
+#define snd_pcm_is_locked(pcm)		0
 #endif /* THREAD_SAFE_API */