diff options
author | Max Kellermann <max@duempel.org> | 2009-08-13 23:33:46 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-08-13 23:33:46 +0200 |
commit | e28a0e97b5d2e54684c6452d6d45f64ff1e542d9 (patch) | |
tree | 38f0c66be040d13c8356293e64cedf8280174fbc /src/decoder_control.h | |
parent | 499ed62dd790949c571517b54ef0e96fad26b16b (diff) | |
download | mpd-e28a0e97b5d2e54684c6452d6d45f64ff1e542d9.tar.gz mpd-e28a0e97b5d2e54684c6452d6d45f64ff1e542d9.tar.xz mpd-e28a0e97b5d2e54684c6452d6d45f64ff1e542d9.zip |
decoder_control: protect command, state with a mutex
Replace decoder_control.notify with decoder_control.mutex and
decoder_control.cond. Lock the mutex on all accesses to
decoder_control.command and decoder_control.state.
Diffstat (limited to 'src/decoder_control.h')
-rw-r--r-- | src/decoder_control.h | 97 |
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) { |