all: use volatile in shared objects

Use volatile on all mutable shared object fields in an attempt to
reduce the amount of possible bugs stemming from caching.
This commit is contained in:
Alexander Capehart 2023-01-03 13:58:31 -07:00
parent d4d3bd5ff4
commit d8e24c4c47
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
3 changed files with 13 additions and 10 deletions

View file

@ -30,8 +30,6 @@ import org.oxycblt.auxio.music.filesystem.useQuery
* generally recommended to use this over Indexer to keep track of the library state, as the
* interface will be less volatile.
*
* TODO: Use volatile on individual fields
*
* @author Alexander Capehart (OxygenCobalt)
*/
class MusicStore private constructor() {
@ -42,6 +40,7 @@ class MusicStore private constructor() {
* can change, so it's highly recommended to not access this directly and instead rely on
* [Listener].
*/
@Volatile
var library: Library? = null
set(value) {
field = value

View file

@ -51,10 +51,10 @@ import org.oxycblt.auxio.util.logW
* @author Alexander Capehart (OxygenCobalt)
*/
class Indexer private constructor() {
private var lastResponse: Result<MusicStore.Library>? = null
private var indexingState: Indexing? = null
private var controller: Controller? = null
private var listener: Listener? = null
@Volatile private var lastResponse: Result<MusicStore.Library>? = null
@Volatile private var indexingState: Indexing? = null
@Volatile private var controller: Controller? = null
@Volatile private var listener: Listener? = null
/** Whether music loading is occurring or not. */
val isIndexing: Boolean

View file

@ -55,18 +55,19 @@ import org.oxycblt.auxio.util.logW
class PlaybackStateManager private constructor() {
private val musicStore = MusicStore.getInstance()
private val listeners = mutableListOf<Listener>()
private var internalPlayer: InternalPlayer? = null
private var pendingAction: InternalPlayer.Action? = null
private var isInitialized = false
@Volatile private var internalPlayer: InternalPlayer? = null
@Volatile private var pendingAction: InternalPlayer.Action? = null
@Volatile private var isInitialized = false
/** The currently playing [Song]. Null if nothing is playing. */
val song
get() = queue.getOrNull(index)
/** The [MusicParent] currently being played. Null if playback is occurring from all songs. */
@Volatile
var parent: MusicParent? = null
private set
private var _queue = mutableListOf<Song>()
@Volatile private var _queue = mutableListOf<Song>()
/** The current queue. */
val queue
get() = _queue
@ -74,15 +75,18 @@ class PlaybackStateManager private constructor() {
var index = -1
private set
/** The current [InternalPlayer] state. */
@Volatile
var playerState = InternalPlayer.State.from(isPlaying = false, isAdvancing = false, 0)
private set
/** The current [RepeatMode] */
@Volatile
var repeatMode = RepeatMode.NONE
set(value) {
field = value
notifyRepeatModeChanged()
}
/** Whether the queue is shuffled. */
@Volatile
var isShuffled = false
private set
/**