aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder_control.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/decoder_control.h')
-rw-r--r--src/decoder_control.h103
1 files changed, 94 insertions, 9 deletions
diff --git a/src/decoder_control.h b/src/decoder_control.h
index 6a04a1617..cab6c69c7 100644
--- a/src/decoder_control.h
+++ b/src/decoder_control.h
@@ -22,7 +22,8 @@
#include "decoder_command.h"
#include "audio_format.h"
-#include "notify.h"
+
+#include <glib.h>
#include <assert.h>
@@ -45,14 +46,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;
@@ -77,6 +89,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 ||
@@ -97,6 +149,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)
{
@@ -115,19 +200,19 @@ decoder_current_song(void)
}
void
-dc_command_wait(struct notify *notify);
+dc_command_wait(void);
void
-dc_start(struct notify *notify, struct song *song);
+dc_start(struct song *song);
void
dc_start_async(struct song *song);
void
-dc_stop(struct notify *notify);
+dc_stop(void);
bool
-dc_seek(struct notify *notify, double where);
+dc_seek(double where);
void
dc_quit(void);