summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c3
-rw-r--r--playlist.c50
-rw-r--r--plugins.c3
-rw-r--r--plugins/gtkui/gtkplaylist.c112
-rw-r--r--plugins/gtkui/gtkui.h10
-rw-r--r--plugins/gtkui/search.c12
-rw-r--r--plugins/mpgmad/mpgmad.c4
-rw-r--r--streamer.c31
8 files changed, 176 insertions, 49 deletions
diff --git a/main.c b/main.c
index fab717ad..6b401185 100644
--- a/main.c
+++ b/main.c
@@ -640,9 +640,10 @@ main (int argc, char *argv[]) {
plug_unload_all ();
// at this point we can simply do exit(0), but let's clean up for debugging
+
+ plt_free (); // plt_free may access conf_*
conf_free ();
messagepump_free ();
- plt_free ();
plug_free_decoder_ids ();
pl_free ();
sigterm_handled = 1;
diff --git a/playlist.c b/playlist.c
index d51b81bc..28ae51a1 100644
--- a/playlist.c
+++ b/playlist.c
@@ -44,6 +44,9 @@
#pragma GCC optimize("O0")
+#define DISABLE_LOCKING 1
+
+// file format revision history
// 1.0->1.1 changelog:
// added sample-accurate seek positions for sub-tracks
#define PLAYLIST_MAJOR_VER 1
@@ -65,8 +68,10 @@ static playlist_t *playlists_head = NULL;
static playlist_t *playlist = NULL; // current playlist
static int plt_loading = 0; // disable sending event about playlist switch, config regen, etc
+#if !DISABLE_LOCKING
static uintptr_t mutex;
static uintptr_t mutex_plt;
+#endif
#define LOCK {pl_lock();}
#define UNLOCK {pl_unlock();}
@@ -79,12 +84,15 @@ static uintptr_t mutex_plt;
int
pl_init (void) {
+#if !DISABLE_LOCKING
mutex = mutex_create_recursive ();
mutex_plt = mutex_create_recursive ();
+#endif
}
void
pl_free (void) {
+#if !DISABLE_LOCKING
if (mutex) {
mutex_free (mutex);
mutex = 0;
@@ -93,26 +101,35 @@ pl_free (void) {
mutex_free (mutex_plt);
mutex_plt = 0;
}
+#endif
}
void
plt_lock (void) {
+#if !DISABLE_LOCKING
mutex_lock (mutex_plt);
+#endif
}
void
plt_unlock (void) {
+#if !DISABLE_LOCKING
mutex_unlock (mutex_plt);
+#endif
}
void
pl_lock (void) {
+#if !DISABLE_LOCKING
mutex_lock (mutex);
+#endif
}
void
pl_unlock (void) {
+#if !DISABLE_LOCKING
mutex_unlock (mutex);
+#endif
}
void
@@ -328,11 +345,6 @@ plt_set_title (int plt, const char *title) {
return -1;
}
-//playlist_t *
-//plt_get_curr_ptr (void) {
-// return playlist;
-//}
-
void
plt_free (void) {
PLT_LOCK;
@@ -1263,6 +1275,7 @@ void
pl_item_ref (playItem_t *it) {
LOCK;
it->_refc++;
+ printf ("+it %p: refc=%d: %s\n", it, it->_refc, it->fname);
UNLOCK;
}
@@ -1288,6 +1301,7 @@ void
pl_item_unref (playItem_t *it) {
LOCK;
it->_refc--;
+ printf ("-it %p: refc=%d: %s\n", it, it->_refc, it->fname);
if (it->_refc < 0) {
fprintf (stderr, "\033[0;31mplaylist: bad refcount on item %p\033[37;0m\n", it);
}
@@ -1773,6 +1787,7 @@ pl_load (const char *fname) {
}
pl_insert_item (playlist->tail[PL_MAIN], it);
pl_item_unref (it);
+ trace ("last playlist item refc: %d\n", it->_refc);
it = NULL;
}
GLOBAL_UNLOCK;
@@ -2261,22 +2276,38 @@ pl_is_selected (playItem_t *it) {
playItem_t *
pl_get_first (int iter) {
- return playlist->head[iter];
+ playItem_t *p = playlist->head[iter];
+ if (p) {
+ pl_item_ref (p);
+ }
+ return p;
}
playItem_t *
pl_get_last (int iter) {
- return playlist->tail[iter];
+ playItem_t *p = playlist->tail[iter];
+ if (p) {
+ pl_item_ref (p);
+ }
+ return p;
}
playItem_t *
pl_get_next (playItem_t *it, int iter) {
- return it ? it->next[iter] : NULL;
+ playItem_t *next = it ? it->next[iter] : NULL;
+ if (next) {
+ pl_item_ref (next);
+ }
+ return next;
}
playItem_t *
pl_get_prev (playItem_t *it, int iter) {
- return it ? it->prev[iter] : NULL;
+ playItem_t *prev = it ? it->prev[iter] : NULL;
+ if (prev) {
+ pl_item_ref (prev);
+ }
+ return prev;
}
int
@@ -2477,6 +2508,7 @@ pl_playqueue_getnext (void) {
LOCK;
if (playqueue_count > 0) {
playItem_t *val = playqueue[0];
+ pl_item_ref (val);
UNLOCK;
return val;
}
diff --git a/plugins.c b/plugins.c
index 81a9141c..6ac46182 100644
--- a/plugins.c
+++ b/plugins.c
@@ -426,6 +426,9 @@ plug_trigger_event_trackinfochanged (int trk) {
event.index = trk;
event.track = DB_PLAYITEM (pl_get_for_idx (trk));
plug_event_call (DB_EVENT (&event));
+ if (event.track) {
+ pl_item_unref ((playItem_t *)event.track);
+ }
}
void
diff --git a/plugins/gtkui/gtkplaylist.c b/plugins/gtkui/gtkplaylist.c
index 2c423e11..7d9f5980 100644
--- a/plugins/gtkui/gtkplaylist.c
+++ b/plugins/gtkui/gtkplaylist.c
@@ -48,14 +48,6 @@
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
-#define PL_HEAD(iter) (deadbeef->pl_get_first(iter))
-#define PL_TAIL(iter) (deadbeef->pl_get_last(iter))
-#define PL_NEXT(it, iter) (deadbeef->pl_get_next(it, iter))
-#define PL_PREV(it, iter) (deadbeef->pl_get_prev(it, iter))
-#define SELECTED(it) (deadbeef->pl_is_selected(it))
-#define SELECT(it, sel) (deadbeef->pl_set_selected(it,sel))
-#define VSELECT(it, sel) {deadbeef->pl_set_selected(it,sel);gtk_pl_redraw_item_everywhere (it);}
-
extern DB_functions_t *deadbeef; // defined in gtkui.c
#define trace(...) { fprintf(stderr, __VA_ARGS__); }
@@ -435,12 +427,17 @@ gtkpl_draw_playlist (gtkplaylist_t *ps, int x, int y, int w, int h) {
// draw background
DB_playItem_t *it = deadbeef->pl_get_for_idx_and_iter (ps->scrollpos, ps->iterator);
DB_playItem_t *it_copy = it;
+ if (it_copy) {
+ REF (it_copy);
+ }
for (row = row1; row < row2_full; row++) {
gtkpl_draw_pl_row_back (ps, row, it);
- if (it) {
+ if (it) {
+ UNREF (it);
it = PL_NEXT (it, ps->iterator);
}
}
+ UNREF (it);
it = it_copy;
int idx = 0;
for (row = row1; row < row2; row++, idx++) {
@@ -448,8 +445,11 @@ gtkpl_draw_playlist (gtkplaylist_t *ps, int x, int y, int w, int h) {
break;
}
gtkpl_draw_pl_row (ps, row, it);
- it = PL_NEXT (it, ps->iterator);
+ DB_playItem_t *next = PL_NEXT (it, ps->iterator);
+ UNREF (it);
+ it = next;
}
+ UNREF (it);
draw_end ();
}
@@ -501,7 +501,7 @@ void
gtkpl_select_single (gtkplaylist_t *ps, int sel) {
int idx=0;
DB_playItem_t *it = PL_HEAD (ps->iterator);
- for (; it; it = PL_NEXT (it, ps->iterator), idx++) {
+ for (; it; idx++) {
if (idx == sel) {
if (!SELECTED (it)) {
VSELECT (it, 1);
@@ -510,7 +510,11 @@ gtkpl_select_single (gtkplaylist_t *ps, int sel) {
else if (SELECTED (it)) {
VSELECT (it, 0);
}
+ DB_playItem_t *next = PL_NEXT (it, ps->iterator);
+ UNREF (it);
+ it = next;
}
+ UNREF (it);
}
// {{{ expected behaviour for mouse1 without modifiers:
@@ -566,12 +570,15 @@ gtkpl_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time)
if (prev != r) {
deadbeef->pl_set_cursor (ps->iterator, r);
if (prev != -1) {
- gtkpl_redraw_pl_row (&main_playlist, prev, deadbeef->pl_get_for_idx (prev));
+ DB_playItem_t *prev_it = deadbeef->pl_get_for_idx (prev);
+ gtkpl_redraw_pl_row (&main_playlist, prev, prev_it);
+ UNREF (prev_it);
}
if (r != -1) {
gtkpl_redraw_pl_row (&main_playlist, r, it);
}
}
+ UNREF (it);
deadbeef->sendmessage (M_PLAYSONGNUM, 0, r, 0);
return;
}
@@ -606,11 +613,16 @@ gtkpl_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time)
}
else {
dragwait = 1;
- gtkpl_redraw_pl_row (ps, prev, gtkpl_get_for_idx (ps, prev));
+ DB_playItem_t *item = gtkpl_get_for_idx (ps, prev);
+ gtkpl_redraw_pl_row (ps, prev, item);
+ UNREF (item);
if (deadbeef->pl_get_cursor (ps->iterator) != prev) {
- gtkpl_redraw_pl_row (ps, deadbeef->pl_get_cursor (ps->iterator), gtkpl_get_for_idx (ps, deadbeef->pl_get_cursor (ps->iterator)));
+ DB_playItem_t *item = gtkpl_get_for_idx (ps, deadbeef->pl_get_cursor (ps->iterator));
+ gtkpl_redraw_pl_row (ps, deadbeef->pl_get_cursor (ps->iterator), item);
+ UNREF (item);
}
}
+ UNREF (it);
}
else if (state & GDK_CONTROL_MASK) {
// toggle selection
@@ -618,6 +630,7 @@ gtkpl_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time)
DB_playItem_t *it = gtkpl_get_for_idx (ps, y);
if (it) {
VSELECT (it, 1 - SELECTED (it));
+ UNREF (it);
}
}
}
@@ -626,7 +639,7 @@ gtkpl_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time)
int start = min (prev, deadbeef->pl_get_cursor (ps->iterator));
int end = max (prev, deadbeef->pl_get_cursor (ps->iterator));
int idx = 0;
- for (DB_playItem_t *it = PL_HEAD (ps->iterator); it; it = PL_NEXT (it, ps->iterator), idx++) {
+ for (DB_playItem_t *it = PL_HEAD (ps->iterator); it; idx++) {
if (idx >= start && idx <= end) {
if (!SELECTED (it)) {
VSELECT (it, 1);
@@ -637,13 +650,19 @@ gtkpl_mouse1_pressed (gtkplaylist_t *ps, int state, int ex, int ey, double time)
VSELECT (it, 0);
}
}
+ DB_playItem_t *next = PL_NEXT (it, ps->iterator);
+ UNREF (it);
}
}
if (deadbeef->pl_get_cursor (ps->iterator) != -1 && sel == -1) {
- gtkpl_redraw_pl_row (ps, deadbeef->pl_get_cursor (ps->iterator), gtkpl_get_for_idx (ps, deadbeef->pl_get_cursor (ps->iterator)));
+ DB_playItem_t *it = gtkpl_get_for_idx (ps, deadbeef->pl_get_cursor (ps->iterator));
+ gtkpl_redraw_pl_row (ps, deadbeef->pl_get_cursor (ps->iterator), it);
+ UNREF (it);
}
if (prev != -1 && prev != deadbeef->pl_get_cursor (ps->iterator)) {
- gtkpl_redraw_pl_row (ps, prev, gtkpl_get_for_idx (ps, prev));
+ DB_playItem_t *it = gtkpl_get_for_idx (ps, prev);
+ gtkpl_redraw_pl_row (ps, prev, it);
+ UNREF (it);
}
}
@@ -764,7 +783,8 @@ gtkpl_mousemove (gtkplaylist_t *ps, GdkEventMotion *event) {
int start = min (y, shift_sel_anchor);
int end = max (y, shift_sel_anchor);
int idx=0;
- for (DB_playItem_t *it = PL_HEAD(ps->iterator); it; it = PL_NEXT(it, ps->iterator), idx++) {
+ DB_playItem_t *it;
+ for (it = PL_HEAD(ps->iterator); it; idx++) {
if (idx >= start && idx <= end) {
if (!SELECTED (it)) {
VSELECT (it, 1);
@@ -773,7 +793,11 @@ gtkpl_mousemove (gtkplaylist_t *ps, GdkEventMotion *event) {
else if (SELECTED (it)) {
VSELECT (it, 0);
}
+ DB_playItem_t *next = PL_NEXT(it, ps->iterator);
+ UNREF (it);
+ it = next;
}
+ UNREF (it);
}
if (event->y < 10) {
@@ -844,7 +868,9 @@ gtkpl_scroll (gtkplaylist_t *ps, int newscroll) {
int start = ps->nvisiblerows-d-1;
start = max (0, ps->nvisiblerows-d-1);
for (i = start; i <= ps->nvisiblerows; i++) {
- gtkpl_redraw_pl_row_novis (ps, i+ps->scrollpos, gtkpl_get_for_idx (ps, i+ps->scrollpos));
+ DB_playItem_t *it = gtkpl_get_for_idx (ps, i+ps->scrollpos);
+ gtkpl_redraw_pl_row_novis (ps, i+ps->scrollpos, it);
+ UNREF (it);
}
}
else {
@@ -852,7 +878,9 @@ gtkpl_scroll (gtkplaylist_t *ps, int newscroll) {
ps->scrollpos = newscroll;
int i;
for (i = 0; i <= d+1; i++) {
- gtkpl_redraw_pl_row_novis (ps, i+ps->scrollpos, gtkpl_get_for_idx (ps, i+ps->scrollpos));
+ DB_playItem_t *it = gtkpl_get_for_idx (ps, i+ps->scrollpos);
+ gtkpl_redraw_pl_row_novis (ps, i+ps->scrollpos, it);
+ UNREF (it);
}
}
}
@@ -890,10 +918,14 @@ gtkpl_songchanged (gtkplaylist_t *ps, int from, int to) {
}
if (from >= 0) {
- gtkpl_redraw_pl_row (ps, from, gtkpl_get_for_idx (ps, from));
+ DB_playItem_t *it = gtkpl_get_for_idx (ps, from);
+ gtkpl_redraw_pl_row (ps, from, it);
+ UNREF (it);
}
if (to >= 0) {
- gtkpl_redraw_pl_row (ps, to, gtkpl_get_for_idx (ps, to));
+ DB_playItem_t *it = gtkpl_get_for_idx (ps, to);
+ gtkpl_redraw_pl_row (ps, to, it);
+ UNREF (it);
}
}
@@ -983,7 +1015,8 @@ gtkpl_keypress (gtkplaylist_t *ps, int keyval, int state) {
int start = min (cursor, shift_sel_anchor);
int end = max (cursor, shift_sel_anchor);
int idx=0;
- for (DB_playItem_t *it = PL_HEAD (ps->iterator); it; it = PL_NEXT(it,ps->iterator), idx++) {
+ DB_playItem_t *it;
+ for (it = PL_HEAD (ps->iterator); it; idx++) {
if (idx >= start && idx <= end) {
VSELECT (it, 1);
}
@@ -991,7 +1024,11 @@ gtkpl_keypress (gtkplaylist_t *ps, int keyval, int state) {
{
VSELECT (it, 0);
}
+ DB_playItem_t *next = PL_NEXT(it,ps->iterator);
+ UNREF (it);
+ it = next;
}
+ UNREF (it);
}
}
else {
@@ -1144,6 +1181,8 @@ gtkpl_add_fm_dropped_files (gtkplaylist_t *ps, char *ptr, int length, int drop_y
DB_playItem_t *after = NULL;
if (drop_before) {
after = PL_PREV (drop_before, ps->iterator);
+ UNREF (drop_before);
+ drop_before = NULL;
}
else {
after = PL_TAIL (ps->iterator);
@@ -1165,6 +1204,9 @@ gtkpl_add_fm_dropped_files (gtkplaylist_t *ps, char *ptr, int length, int drop_y
inserted = deadbeef->pl_insert_file (after, fname, &abort, gtkpl_add_file_info_cb, NULL);
}
if (inserted) {
+ if (after) {
+ UNREF (after);
+ }
after = inserted;
}
}
@@ -1176,6 +1218,9 @@ gtkpl_add_fm_dropped_files (gtkplaylist_t *ps, char *ptr, int length, int drop_y
}
free (ptr);
+ if (after) {
+ UNREF (after);
+ }
g_idle_add (progress_hide_idle, NULL);
}
@@ -1623,12 +1668,15 @@ gtkpl_get_idx_of (gtkplaylist_t *ps, DB_playItem_t *it) {
DB_playItem_t *c = PL_HEAD(ps->iterator);
int idx = 0;
while (c && c != it) {
- c = PL_NEXT(c, ps->iterator);;
+ DB_playItem_t *next = PL_NEXT(c, ps->iterator);
+ UNREF (c);
+ c = next;
idx++;
}
if (!c) {
return -1;
}
+ UNREF (c);
return idx;
}
@@ -1636,9 +1684,12 @@ DB_playItem_t *
gtkpl_get_for_idx (gtkplaylist_t *ps, int idx) {
DB_playItem_t *it = PL_HEAD(ps->iterator);
while (idx--) {
- if (!it)
+ if (!it) {
return NULL;
- it = PL_NEXT(it, ps->iterator);
+ }
+ DB_playItem_t *next = PL_NEXT(it, ps->iterator);
+ UNREF (it);
+ it = next;
}
return it;
}
@@ -1869,6 +1920,7 @@ update_win_title_idle (gpointer data) {
notify_notification_show (notification, NULL);
}
}
+ UNREF (track);
}
}
#endif
@@ -1879,6 +1931,7 @@ update_win_title_idle (gpointer data) {
DB_playItem_t *it = deadbeef->pl_get_for_idx (to);
if (it) { // it might have been deleted after event was sent
gtkpl_current_track_changed (it);
+ UNREF (it);
}
}
else {
@@ -1909,9 +1962,12 @@ redraw_queued_tracks (gtkplaylist_t *pl) {
if (deadbeef->pl_playqueue_test (it) != -1) {
gtkpl_redraw_pl_row (pl, i, it);
}
- it = PL_NEXT (it, pl->iterator);
+ DB_playItem_t *next = PL_NEXT (it, pl->iterator);
+ UNREF (it);
+ it = next;
i++;
}
+ UNREF (it);
}
static gboolean
@@ -1970,10 +2026,12 @@ gtkpl_set_cursor_cb (gpointer data) {
if (sc->prev >= minvis && sc->prev <= maxvis) {
it = deadbeef->pl_get_for_idx_and_iter (sc->prev, sc->iter);
gtkpl_redraw_pl_row (sc->pl, sc->prev, it);
+ UNREF (it);
}
if (sc->cursor >= minvis && sc->cursor <= maxvis) {
it = deadbeef->pl_get_for_idx_and_iter (sc->cursor, sc->iter);
gtkpl_redraw_pl_row (sc->pl, sc->cursor, it);
+ UNREF (it);
}
int newscroll = sc->pl->scrollpos;
diff --git a/plugins/gtkui/gtkui.h b/plugins/gtkui/gtkui.h
index 2031b502..3217ab5c 100644
--- a/plugins/gtkui/gtkui.h
+++ b/plugins/gtkui/gtkui.h
@@ -19,6 +19,16 @@
#ifndef __GTKUI_H
#define __GTKUI_H
+#define PL_HEAD(iter) (deadbeef->pl_get_first(iter))
+#define PL_TAIL(iter) (deadbeef->pl_get_last(iter))
+#define PL_NEXT(it, iter) (deadbeef->pl_get_next(it, iter))
+#define PL_PREV(it, iter) (deadbeef->pl_get_prev(it, iter))
+#define SELECTED(it) (deadbeef->pl_is_selected(it))
+#define SELECT(it, sel) (deadbeef->pl_set_selected(it,sel))
+#define VSELECT(it, sel) {deadbeef->pl_set_selected(it,sel);gtk_pl_redraw_item_everywhere (it);}
+#define REF(it) {if (it) deadbeef->pl_item_ref (it);}
+#define UNREF(it) {if (it) deadbeef->pl_item_unref (it);}
+
#if HAVE_NOTIFY
#define NOTIFY_DEFAULT_FORMAT "%a - %t"
#endif
diff --git a/plugins/gtkui/search.c b/plugins/gtkui/search.c
index 8c2055d1..517f7f50 100644
--- a/plugins/gtkui/search.c
+++ b/plugins/gtkui/search.c
@@ -36,12 +36,12 @@
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
-#define PL_HEAD(iter) (deadbeef->pl_get_first(iter))
-#define PL_TAIL(iter) (deadbeef->pl_get_last(iter))
-#define PL_NEXT(it, iter) (deadbeef->pl_get_next(it, iter))
-#define PL_PREV(it, iter) (deadbeef->pl_get_prev(it, iter))
-#define SELECTED(it) (deadbeef->pl_is_selected(it))
-#define SELECT(it, sel) (deadbeef->pl_set_selected(it,sel))
+//#define PL_HEAD(iter) (deadbeef->pl_get_first(iter))
+//#define PL_TAIL(iter) (deadbeef->pl_get_last(iter))
+//#define PL_NEXT(it, iter) (deadbeef->pl_get_next(it, iter))
+//#define PL_PREV(it, iter) (deadbeef->pl_get_prev(it, iter))
+//#define SELECTED(it) (deadbeef->pl_is_selected(it))
+//#define SELECT(it, sel) (deadbeef->pl_set_selected(it,sel))
extern DB_functions_t *deadbeef; // defined in gtkui.c
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
diff --git a/plugins/mpgmad/mpgmad.c b/plugins/mpgmad/mpgmad.c
index 9a925304..df68ba12 100644
--- a/plugins/mpgmad/mpgmad.c
+++ b/plugins/mpgmad/mpgmad.c
@@ -556,6 +556,7 @@ cmp3_init (DB_playItem_t *it) {
if (!info->buffer.file) {
return NULL;
}
+ deadbeef->pl_item_ref (it);
info->buffer.it = it;
info->info.readpos = 0;
if (!info->buffer.file->vfs->streaming) {
@@ -907,6 +908,9 @@ static void
cmp3_free (DB_fileinfo_t *_info) {
mpgmad_info_t *info = (mpgmad_info_t *)_info;
if (info->buffer.file) {
+ if (info->buffer.it) {
+ deadbeef->pl_item_unref (info->buffer.it);
+ }
deadbeef->fclose (info->buffer.file);
info->buffer.file = NULL;
mad_synth_finish (&info->synth);
diff --git a/streamer.c b/streamer.c
index ec28c88c..2297a537 100644
--- a/streamer.c
+++ b/streamer.c
@@ -108,6 +108,7 @@ streamer_move_to_nextsong (int reason) {
if (it) {
pl_playqueue_pop ();
int r = pl_get_idx_of (it);
+ pl_item_unref (it);
streamer_set_nextsong (r, 1);
pl_global_unlock ();
return 0;
@@ -232,16 +233,19 @@ streamer_move_to_nextsong (int reason) {
int
streamer_move_to_prevsong (void) {
+ plt_lock ();
playlist_t *plt = plt_get_curr_ptr ();
pl_playqueue_clear ();
if (!plt->head[PL_MAIN]) {
streamer_set_nextsong (-2, 1);
+ plt_unlock ();
return 0;
}
int pl_order = conf_get_int ("playback.order", 0);
int pl_loop_mode = conf_get_int ("playback.loop", 0);
if (pl_order == PLAYBACK_ORDER_SHUFFLE) { // shuffle
if (!playlist_track) {
+ plt_unlock ();
return streamer_move_to_nextsong (1);
}
else {
@@ -273,6 +277,7 @@ streamer_move_to_prevsong (void) {
}
if (!it) {
+ plt_unlock ();
return -1;
}
int r = pl_get_idx_of (it);
@@ -291,15 +296,18 @@ streamer_move_to_prevsong (void) {
}
}
if (!it) {
+ plt_unlock ();
return -1;
}
int r = pl_get_idx_of (it);
streamer_set_nextsong (r, 1);
+ plt_unlock ();
return 0;
}
else if (pl_order == PLAYBACK_ORDER_RANDOM) { // random
streamer_move_to_randomsong ();
}
+ plt_unlock ();
return -1;
}
@@ -505,18 +513,25 @@ streamer_thread (void *ctx) {
p_stop ();
mutex_lock (decodemutex);
- pl_item_unref (playing_track);
- playing_track = NULL;
- pl_item_unref (streaming_track);
- streaming_track = NULL;
+ if (playing_track) {
+ pl_item_unref (playing_track);
+ playing_track = NULL;
+ }
+ if (streaming_track) {
+ pl_item_unref (streaming_track);
+ streaming_track = NULL;
+ }
mutex_unlock (decodemutex);
messagepump_push (M_SONGCHANGED, 0, -1, -1);
continue;
}
int ret = streamer_set_current (try);
+
if (ret < 0) {
trace ("\033[0;31mfailed to play track %s, skipping (current=%p/%p)...\033[37;0m\n", try->fname, streaming_track, playlist_track);
+ pl_item_unref (try);
+ try = NULL;
// remember bad song number in case of looping
if (badsong == -1) {
badsong = sng;
@@ -527,6 +542,8 @@ streamer_thread (void *ctx) {
usleep (50000);
continue;
}
+ pl_item_unref (try);
+ try = NULL;
badsong = -1;
if (pstate == 0) {
p_stop ();
@@ -556,8 +573,10 @@ streamer_thread (void *ctx) {
plug_trigger_event (DB_EV_SONGFINISHED, 0);
}
streamer_set_current (NULL);
- pl_item_unref (playing_track);
- playing_track = NULL;
+ if (playing_track) {
+ pl_item_unref (playing_track);
+ playing_track = NULL;
+ }
messagepump_push (M_SONGCHANGED, 0, from, -1);
continue;
}