Skip to content

Commit

Permalink
prevent concurrency issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Pixaurora committed Oct 5, 2024
1 parent 7691e74 commit 5a99ba2
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,41 +58,55 @@ private static void handleTrackEnd(ListeningProgress progress, Pair<ResourcePath
public static void init() {
}

public static synchronized void tick() {
for (Runnable task : MAIN_THREAD_TASKS) {
task.run();
public static void tick() {
synchronized (MAIN_THREAD_TASKS) {
for (Runnable task : MAIN_THREAD_TASKS) {
task.run();
}

MAIN_THREAD_TASKS.clear();
}
}

MAIN_THREAD_TASKS.clear();
public static void addMainThreadTask(Runnable task) {
synchronized (MAIN_THREAD_TASKS) {
MAIN_THREAD_TASKS.add(task);
}
}

public static boolean isTracking(ListeningProgress progress) {
return PLAYING_TRACKS.containsKey(progress);
synchronized (PLAYING_TRACKS) {
return PLAYING_TRACKS.containsKey(progress);
}
}

public static boolean isTrackingAnything() {
return PLAYING_TRACKS.size() > 0;
synchronized (PLAYING_TRACKS) {
return PLAYING_TRACKS.size() > 0;
}
}

public static synchronized void stop() {
for (Map.Entry<ListeningProgress, Pair<ResourcePath, Optional<Track>>> entry : PLAYING_TRACKS.entrySet()) {
handleTrackEnd(entry.getKey(), entry.getValue());
public static void stop() {
synchronized (PLAYING_TRACKS) {
PLAYING_TRACKS.forEach(EventHandling::handleTrackEnd);
}

tick(); // Tick one last time to clear any remaining tasks out.
}

public static synchronized Collection<PlayingSong> playingSongs() {
List<PlayingSong> songs = new ArrayList<>();
public static Collection<PlayingSong> playingSongs() {
synchronized (PLAYING_TRACKS) {
List<PlayingSong> songs = new ArrayList<>();

for (Map.Entry<ListeningProgress, Pair<ResourcePath, Optional<Track>>> entry : PLAYING_TRACKS.entrySet()) {
songs.add(new PlayingSong(entry.getValue().second(), entry.getKey()));
}
for (Map.Entry<ListeningProgress, Pair<ResourcePath, Optional<Track>>> entry : PLAYING_TRACKS.entrySet()) {
songs.add(new PlayingSong(entry.getValue().second(), entry.getKey()));
}

return songs;
return songs;
}
}

private static synchronized TrackStartEvent createStartEvent(ResourcePath path, ListeningProgress progress) {
private static TrackStartEvent createStartEvent(ResourcePath path, ListeningProgress progress) {
Optional<Track> track = MusicMetadata.matchTrack(path);

if (track.isPresent()) {
Expand All @@ -101,7 +115,9 @@ private static synchronized TrackStartEvent createStartEvent(ResourcePath path,
MusicMetadata.asMutable().giveDuration(track.get(), songDuration);
}

PLAYING_TRACKS.put(progress, Pair.of(path, track));
synchronized (PLAYING_TRACKS) {
PLAYING_TRACKS.put(progress, Pair.of(path, track));
}

return new TrackEventImpl(path, track, progress);
}
Expand All @@ -112,23 +128,25 @@ private static Duration songDuration(ResourcePath path) throws IOException {
}
}

private static synchronized Pair<ResourcePath, Optional<Track>> getTrackInfo(ListeningProgress progress,
private static Pair<ResourcePath, Optional<Track>> getTrackInfo(ListeningProgress progress,
boolean flushFromMap) {
Pair<ResourcePath, Optional<Track>> trackInfo = Objects.requireNonNull(PLAYING_TRACKS.get(progress));
synchronized (PLAYING_TRACKS) {
Pair<ResourcePath, Optional<Track>> trackInfo = Objects.requireNonNull(PLAYING_TRACKS.get(progress));

if (flushFromMap) {
PLAYING_TRACKS.remove(progress);
}
if (flushFromMap) {
PLAYING_TRACKS.remove(progress);
}

return trackInfo;
return trackInfo;
}
}

private static void processEvent(Consumer<MusicEventListener> event) {
for (MusicEventListener listener : KitTunes.MUSIC_LISTENERS) {
Runnable eventAction = () -> event.accept(listener);

if (listener.isSynchronized()) {
MAIN_THREAD_TASKS.add(eventAction);
addMainThreadTask(eventAction);
} else {
KitTunes.EXECUTOR.execute(eventAction);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ public ConfigManager(Path savePath, Class<T> configClass, Supplier<T> defaults)
this.config = this.createConfig();
}

public synchronized void execute(Consumer<T> task) {
task.accept(this.config);
public void execute(Consumer<T> task) {
synchronized (this) {
task.accept(this.config);
}
}

public synchronized void save() throws IOException {
this.saveAtomically(config);
public void save() throws IOException {
synchronized (this) {
this.saveAtomically(config);
}
}

private void saveAtomically(T config) throws IOException {
Expand Down

0 comments on commit 5a99ba2

Please sign in to comment.