aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder_control.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/decoder_control.h97
1 files changed, 92 insertions, 5 deletions
diff --git a/src/decoder_control.h b/src/decoder_control.h
index 703ea256c..7e861f970 100644
--- a/src/decoder_control.h
+++ b/src/decoder_control.h
@@ -22,13 +22,16 @@
#include "decoder_command.h"
#include "audio_format.h"
-#include "notify.h"
+
+#include <glib.h>
#include <assert.h>
#define DECODE_TYPE_FILE 0
#define DECODE_TYPE_URL 1
+struct notify;
+
enum decoder_state {
DECODE_STATE_STOP = 0,
DECODE_STATE_START,
@@ -48,14 +51,25 @@ struct decoder_control {
thread isn't running */
GThread *thread;
- struct notify notify;
+ /**
+ * This lock protects #state and #command.
+ */
+ GMutex *mutex;
+
+ /**
+ * Trigger this object after you have modified #command. This
+ * is also used by the decoder thread to notify the caller
+ * when it has finished a command.
+ */
+ GCond *cond;
+
+ enum decoder_state state;
+ enum decoder_command command;
- volatile enum decoder_state state;
- volatile enum decoder_command command;
bool quit;
bool seek_error;
bool seekable;
- volatile double seek_where;
+ double seek_where;
/** the format of the song file */
struct audio_format in_audio_format;
@@ -80,6 +94,46 @@ void dc_init(void);
void dc_deinit(void);
+/**
+ * Locks the #decoder_control object.
+ */
+static inline void
+decoder_lock(void)
+{
+ g_mutex_lock(dc.mutex);
+}
+
+/**
+ * Unlocks the #decoder_control object.
+ */
+static inline void
+decoder_unlock(void)
+{
+ g_mutex_unlock(dc.mutex);
+}
+
+/**
+ * Waits for a signal on the #decoder_control object. This function
+ * is only valid in the decoder thread. The object must be locked
+ * prior to calling this function.
+ */
+static inline void
+decoder_wait(void)
+{
+ g_cond_wait(dc.cond, dc.mutex);
+}
+
+/**
+ * Signals the #decoder_control object. This function is only valid
+ * in the player thread. The object should be locked prior to calling
+ * this function.
+ */
+static inline void
+decoder_signal(void)
+{
+ g_cond_signal(dc.cond);
+}
+
static inline bool decoder_is_idle(void)
{
return (dc.state == DECODE_STATE_STOP ||
@@ -100,6 +154,39 @@ static inline bool decoder_has_failed(void)
return dc.state == DECODE_STATE_ERROR;
}
+static inline bool decoder_lock_is_idle(void)
+{
+ bool ret;
+
+ decoder_lock();
+ ret = decoder_is_idle();
+ decoder_unlock();
+
+ return ret;
+}
+
+static inline bool decoder_lock_is_starting(void)
+{
+ bool ret;
+
+ decoder_lock();
+ ret = decoder_is_starting();
+ decoder_unlock();
+
+ return ret;
+}
+
+static inline bool decoder_lock_has_failed(void)
+{
+ bool ret;
+
+ decoder_lock();
+ ret = decoder_has_failed();
+ decoder_unlock();
+
+ return ret;
+}
+
static inline struct song *
decoder_current_song(void)
{