From 43a277e9d2dfaa2055184617495e1d3a48b8d9cc Mon Sep 17 00:00:00 2001 From: waker Date: Mon, 25 Apr 2011 21:49:34 +0200 Subject: new future-proof playlist API, potentially reducing locking, and allowing more flexibility --- deadbeef.h | 80 ++++++++++---- main.c | 12 +-- playlist.c | 246 ++++++++++++++++++++++++++++-------------- playlist.h | 32 ++++-- plugins.c | 41 ++++--- plugins/cdda/cdda.c | 18 +++- plugins/gtkui/callbacks.c | 4 +- plugins/gtkui/ddblistview.c | 2 +- plugins/gtkui/ddbtabstrip.c | 24 ++--- plugins/gtkui/fileman.c | 6 +- plugins/gtkui/gtkui.c | 58 ++++++---- plugins/gtkui/mainplaylist.c | 4 +- plugins/gtkui/plcommon.c | 32 +++--- plugins/gtkui/trkproperties.c | 6 +- plugins/vfs_curl/vfs_curl.c | 12 ++- plugins/vorbis/vorbis.c | 7 +- streamer.c | 46 +++++--- 17 files changed, 422 insertions(+), 208 deletions(-) diff --git a/deadbeef.h b/deadbeef.h index 2e6dfe18..aa1abd66 100644 --- a/deadbeef.h +++ b/deadbeef.h @@ -122,7 +122,12 @@ typedef struct DB_playItem_s { int shufflerating; // sort order for shuffle mode float playtime; // actual playback time of this track in seconds time_t started_timestamp; // result of calling time(NULL) -} DB_playItem_t; +} ddb_playItem_t; + +typedef ddb_playItem_t DB_playItem_t; + +typedef struct { +} ddb_playlist_t; typedef struct DB_metaInfo_s { struct DB_metaInfo_s *next; @@ -373,41 +378,72 @@ typedef struct { int (*cond_signal) (uintptr_t cond); int (*cond_broadcast) (uintptr_t cond); - // playlist management + /////// playlist management ////// + void (*plt_ref) (ddb_playlist_t *plt); + void (*plt_unref) (ddb_playlist_t *plt); + + // total number of playlists int (*plt_get_count) (void); + + // 1st item in playlist nr. 'plt' DB_playItem_t * (*plt_get_head) (int plt); + + // nr. of selected items in playlist nr. 'plt' int (*plt_get_sel_count) (int plt); + + // add new playlist into position before nr. 'before', with title='title' + // returns index of new playlist int (*plt_add) (int before, const char *title); + + // remove playlist nr. plt void (*plt_remove) (int plt); - void (*plt_set_curr) (int plt); - int (*plt_get_curr) (void); + + // clear playlist + void (*plt_clear) (ddb_playlist_t *plt); + + // set current playlist + void (*plt_set_curr) (ddb_playlist_t *plt); + void (*plt_set_curr_idx) (int plt); + + // get current playlist + // note: caller is responsible to call plt_unref after using pointer + // returned by plt_get_curr + ddb_playlist_t *(*plt_get_curr) (void); + int (*plt_get_curr_idx) (void); + + // move playlist nr. 'from' into position before nr. 'before', where + // before=-1 means last position void (*plt_move) (int from, int before); + // playlist saving and loading + DB_playItem_t * (*plt_load) (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data); + int (*plt_save) (ddb_playlist_t *plt, DB_playItem_t *first, DB_playItem_t *last, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data); + // getting and working with a handle must be guarded using plt_lock/unlock - void *(*plt_get_handle) (int idx); - int (*plt_get_title) (void *handle, char *buffer, int bufsize); - int (*plt_set_title) (void *handle, const char *title); + ddb_playlist_t *(*plt_get_for_idx) (int idx); + int (*plt_get_title) (ddb_playlist_t *plt, char *buffer, int bufsize); + int (*plt_set_title) (ddb_playlist_t *plt, const char *title); // increments modification index - void (*plt_modified) (void *handle); + void (*plt_modified) (ddb_playlist_t *handle); // returns modication index // the index is incremented by 1 every time playlist changes - int (*plt_get_modification_idx) (void *handle); + int (*plt_get_modification_idx) (ddb_playlist_t *handle); // playlist metadata // this kind of metadata is stored in playlist (dbpl) files - void (*plt_add_meta) (void *handle, const char *key, const char *value); - void (*plt_replace_meta) (void *handle, const char *key, const char *value); - void (*plt_append_meta) (void *handle, const char *key, const char *value); - void (*plt_set_meta_int) (void *handle, const char *key, int value); - void (*plt_set_meta_float) (void *handle, const char *key, float value); - const char *(*plt_find_meta) (void *handle, const char *key); - DB_metaInfo_t * (*plt_get_metadata_head) (void *handle); // returns head of metadata linked list - void (*plt_delete_metadata) (void *handle, DB_metaInfo_t *meta); - int (*plt_find_meta_int) (void *handle, const char *key, int def); - float (*plt_find_meta_float) (void *handle, const char *key, float def); - void (*plt_delete_all_meta) (void *handle); + void (*plt_add_meta) (ddb_playlist_t *handle, const char *key, const char *value); + void (*plt_replace_meta) (ddb_playlist_t *handle, const char *key, const char *value); + void (*plt_append_meta) (ddb_playlist_t *handle, const char *key, const char *value); + void (*plt_set_meta_int) (ddb_playlist_t *handle, const char *key, int value); + void (*plt_set_meta_float) (ddb_playlist_t *handle, const char *key, float value); + const char *(*plt_find_meta) (ddb_playlist_t *handle, const char *key); + DB_metaInfo_t * (*plt_get_metadata_head) (ddb_playlist_t *handle); // returns head of metadata linked list + void (*plt_delete_metadata) (ddb_playlist_t *handle, DB_metaInfo_t *meta); + int (*plt_find_meta_int) (ddb_playlist_t *handle, const char *key, int def); + float (*plt_find_meta_float) (ddb_playlist_t *handle, const char *key, float def); + void (*plt_delete_all_meta) (ddb_playlist_t *handle); // playlist locking void (*pl_lock) (void); @@ -425,7 +461,7 @@ typedef struct { // this function may return -1 if it is not possible to add files right now. // caller must cancel operation in this case, or wait until previous add // finishes - int (*pl_add_files_begin) (int playlist); + int (*pl_add_files_begin) (ddb_playlist_t *plt); void (*pl_add_files_end) (void); DB_playItem_t *(*pl_insert_item) (DB_playItem_t *after, DB_playItem_t *it); DB_playItem_t *(*pl_insert_dir) (DB_playItem_t *after, const char *dirname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data); @@ -442,8 +478,6 @@ typedef struct { void (*pl_set_selected) (DB_playItem_t *it, int sel); int (*pl_is_selected) (DB_playItem_t *it); void (*pl_clear) (void); - int (*pl_load) (const char *name); - int (*pl_save) (const char *name); int (*pl_save_current) (void); int (*pl_save_all) (void); void (*pl_select_all) (void); diff --git a/main.c b/main.c index 6bcad18f..554c7459 100644 --- a/main.c +++ b/main.c @@ -227,18 +227,19 @@ server_exec_command_line (const char *cmdline, int len, char *sendback, int sbsi idx = plt_add (plt_get_count (), str); } if (idx >= 0) { - plt_set_curr (idx); + plt_set_curr_idx (idx); } } // add files - int curr_plt = plt_get_curr (); + playlist_t *curr_plt = plt_get_curr (); if (!queue) { pl_clear (); plug_trigger_event_playlistchanged (); pl_reset_cursor (); } if (parg < pend) { - if (deadbeef->pl_add_files_begin (curr_plt) != 0) { + if (deadbeef->pl_add_files_begin ((ddb_playlist_t *)curr_plt) != 0) { + plt_unref (curr_plt); snprintf (sendback, sbsize, "it's not allowed to add files to playlist right now, because another file adding operation is in progress. please try again later."); return 0; } @@ -812,7 +813,7 @@ main (int argc, char *argv[]) { exit (-1); } pl_load_all (); - plt_set_curr (conf_get_int ("playlist.current", 0)); + plt_set_curr_idx (conf_get_int ("playlist.current", 0)); // execute server commands in local context int noloadpl = 0; @@ -890,8 +891,7 @@ 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_* - pl_free (); + pl_free (); // may access conf_* conf_free (); messagepump_free (); plug_cleanup (); diff --git a/playlist.c b/playlist.c index 971b1ede..bf4743ae 100644 --- a/playlist.c +++ b/playlist.c @@ -95,7 +95,10 @@ static uintptr_t mutex_plt; #define LOCK {pl_lock();} #define UNLOCK {pl_unlock();} -static playlist_t dummy_playlist; // used at startup to prevent crashes +// used at startup to prevent crashes +static playlist_t dummy_playlist = { + .refc = 1 +}; static int pl_order; // mirrors "playback.order" config variable @@ -130,6 +133,22 @@ pl_init (void) { void pl_free (void) { + trace ("pl_free\n"); + LOCK; + pl_playqueue_clear (); + plt_loading = 1; + while (playlists_head) { + + for (playItem_t *it = playlists_head->head[PL_MAIN]; it; it = it->next[PL_MAIN]) { + if (it->_refc > 1) { + fprintf (stderr, "\033[0;31mWARNING: playitem %p %s has refc=%d at delete time\033[37;0m\n", it, pl_find_meta (it, ":URI"), it->_refc); + } + } + + plt_remove (0); + } + plt_loading = 0; + UNLOCK; #if !DISABLE_LOCKING if (mutex) { mutex_free (mutex); @@ -198,21 +217,53 @@ plt_get_list (void) { } playlist_t * -plt_get_curr_ptr (void) { - return playlist; +plt_get_curr (void) { + LOCK; + playlist_t *plt = playlist; + if (plt) { + plt_ref (plt); + assert (plt->refc > 1); + } + UNLOCK; + return plt; + } playlist_t * -plt_get (int idx) { +plt_get_for_idx (int idx) { + LOCK; playlist_t *p = playlists_head; for (int i = 0; p && i <= idx; i++, p = p->next) { if (i == idx) { + plt_ref (p); + UNLOCK; return p; } } + UNLOCK; return NULL; } +void +plt_ref (playlist_t *plt) { + LOCK; + plt->refc++; + UNLOCK; +} + +void +plt_unref (playlist_t *plt) { + LOCK; + plt->refc--; + if (plt->refc < 0) { + trace ("\033[0;31mplaylist: bad refcount on playlist %p (%s)\033[37;0m\n", plt, plt->title); + } + if (plt->refc <= 0) { + plt_free (plt); + } + UNLOCK; +} + int plt_get_count (void) { return playlists_count; @@ -261,12 +312,11 @@ plt_add (int before, const char *title) { } playlist_t *plt = malloc (sizeof (playlist_t)); memset (plt, 0, sizeof (playlist_t)); + plt->refc = 1; plt->title = strdup (title); plt_modified (plt); - trace ("locking\n"); LOCK; - trace ("locked\n"); playlist_t *p_before = NULL; playlist_t *p_after = playlists_head; @@ -340,7 +390,6 @@ plt_remove (int plt) { prev = p; p = p->next; } - streamer_notify_playlist_deleted (p); if (!plt_loading) { // move files (will decrease number of files by 1) for (int i = plt+1; i < playlists_count; i++) { @@ -387,7 +436,6 @@ plt_remove (int plt) { playlist_t *next = p->next; playlist_t *old = playlist; playlist = p; - pl_clear (); playlist = old; if (p == playlist) { if (next) { @@ -397,17 +445,8 @@ plt_remove (int plt) { playlist = prev ? prev : playlists_head; } } - free (p->title); - - while (p->meta) { - DB_metaInfo_t *m = p->meta; - p->meta = m->next; - metacache_remove_string (m->key); - metacache_remove_string (m->value); - free (m); - } - free (p); + plt_unref (p); playlists_count--; UNLOCK; @@ -430,8 +469,23 @@ plt_find (const char *name) { return -1; } + +void +plt_set_curr (playlist_t *plt) { + LOCK; + if (plt != playlist) { + playlist = plt; + if (!plt_loading) { + messagepump_push (DB_EV_PLAYLISTSWITCHED, 0, 0, 0); + conf_set_int ("playlist.current", plt_get_curr_idx ()); + conf_save (); + } + } + UNLOCK; +} + void -plt_set_curr (int plt) { +plt_set_curr_idx (int plt) { int i; LOCK; playlist_t *p = playlists_head; @@ -442,7 +496,7 @@ plt_set_curr (int plt) { playlist = p; if (!plt_loading) { messagepump_push (DB_EV_PLAYLISTSWITCHED, 0, 0, 0); - conf_set_int ("playlist.current", plt_get_curr ()); + conf_set_int ("playlist.current", plt); conf_save (); } } @@ -450,7 +504,7 @@ plt_set_curr (int plt) { } int -plt_get_curr (void) { +plt_get_curr_idx(void) { int i; LOCK; playlist_t *p = playlists_head; @@ -527,22 +581,21 @@ plt_get_modification_idx (playlist_t *plt) { } void -plt_free (void) { - trace ("plt_free\n"); +plt_free (playlist_t *plt) { LOCK; - pl_playqueue_clear (); - plt_loading = 1; - while (playlists_head) { - - for (playItem_t *it = playlists_head->head[PL_MAIN]; it; it = it->next[PL_MAIN]) { - if (it->_refc > 1) { - fprintf (stderr, "\033[0;31mWARNING: playitem %p %s has refc=%d at delete time\033[37;0m\n", it, pl_find_meta (it, ":URI"), it->_refc); - } - } + streamer_notify_playlist_deleted (plt); + plt_clear (plt); + free (plt->title); - plt_remove (0); + while (plt->meta) { + DB_metaInfo_t *m = plt->meta; + plt->meta = m->next; + metacache_remove_string (m->key); + metacache_remove_string (m->value); + free (m); } - plt_loading = 0; + + free (plt); UNLOCK; } @@ -976,7 +1029,7 @@ pl_insert_cue_from_buffer (playItem_t *after, playItem_t *origin, const uint8_t pl_get_value_from_cue (p + 9, sizeof (date), date); } else if (!strncmp (p, "TRACK ", 6)) { - trace ("cue: adding track: %s %s %s\n", origin->fname, title, track); + trace ("cue: adding track: %s %s %s\n", pl_find_meta (origin, ":URI"), title, track); if (title[0]) { // add previous track const char *filetype = pl_find_meta (origin, ":FILETYPE"); @@ -1609,13 +1662,16 @@ pl_add_dir (const char *dirname, int (*cb)(playItem_t *it, void *data), void *us } int -pl_add_files_begin (int plt) { +pl_add_files_begin (playlist_t *plt) { pl_lock (); if (addfiles_playlist) { pl_unlock (); return -1; } - addfiles_playlist = plt_get (plt); + addfiles_playlist = plt; + if (addfiles_playlist) { + plt_ref (addfiles_playlist); + } pl_unlock (); trace ("adding to playlist %d (%s)\n", plt, addfiles_playlist->title); return 0; @@ -1625,6 +1681,9 @@ void pl_add_files_end (void) { trace ("end adding to playlist %s\n", addfiles_playlist->title); pl_lock (); + if (addfiles_playlist) { + plt_unref (addfiles_playlist); + } addfiles_playlist = NULL; pl_unlock (); } @@ -1931,7 +1990,7 @@ pl_crop_selected (void) { } int -pl_save (const char *fname) { +plt_save (playlist_t *plt, playItem_t *first, playItem_t *last, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) { LOCK; const char *ext = strrchr (fname, '.'); if (ext) { @@ -2153,7 +2212,7 @@ pl_save_n (int n) { playlist_t *orig = playlist; int i; for (i = 0, playlist = playlists_head; playlist && i < n; i++, playlist = playlist->next); - err = pl_save (path); + err = plt_save (playlist, NULL, NULL, path, NULL, NULL, NULL); playlist = orig; plt_loading = 0; UNLOCK; @@ -2162,7 +2221,7 @@ pl_save_n (int n) { int pl_save_current (void) { - return pl_save_n (plt_get_curr ()); + return pl_save_n (plt_get_curr_idx ()); } int @@ -2180,38 +2239,34 @@ pl_save_all (void) { playlist_t *p = playlists_head; int i; int cnt = plt_get_count (); - int curr = plt_get_curr (); + int curr = plt_get_curr_idx (); int err = 0; plt_loading = 1; for (i = 0; i < cnt; i++, p = p->next) { - plt_set_curr (i); if (snprintf (path, sizeof (path), "%s/playlists/%d.dbpl", dbconfdir, i) > sizeof (path)) { fprintf (stderr, "error: failed to make path string for playlist file\n"); err = -1; break; } - err = pl_save (path); + err = plt_save (p, NULL, NULL, path, NULL, NULL, NULL); if (err < 0) { break; } } - plt_set_curr (curr); plt_loading = 0; UNLOCK; return err; } -int -pl_load (const char *fname) { +playItem_t * +plt_load (playlist_t *plt, playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) { FILE *fp = fopen (fname, "rb"); if (!fp) { - return -1; + trace ("plt_load: failed to open %s\n", fname); + return NULL; } LOCK; - playlist_t *plt = playlist; - - plt_clear (plt); // try plugins 1st const char *ext = strrchr (fname, '.'); @@ -2222,13 +2277,14 @@ pl_load (const char *fname) { for (p = 0; plug[p]; p++) { for (e = 0; plug[p]->extensions[e]; e++) { if (plug[p]->load && !strcasecmp (ext, plug[p]->extensions[e])) { - /*DB_playItem_t *it = */plug[p]->load (NULL, fname, NULL, NULL, NULL); + DB_playItem_t *it = plug[p]->load (NULL, fname, NULL, NULL, NULL); UNLOCK; - return 0; + return (playItem_t *)it; } } } } + trace ("plt_load: loading dbpl\n"); uint8_t majorver; uint8_t minorver; @@ -2260,6 +2316,9 @@ pl_load (const char *fname) { if (fread (&cnt, 1, 4, fp) != 4) { goto load_fail; } + + playItem_t *last_added = NULL; + for (uint32_t i = 0; i < cnt; i++) { it = pl_item_alloc (); if (!it) { @@ -2422,8 +2481,10 @@ pl_load (const char *fname) { } } plt_insert_item (plt, plt->tail[PL_MAIN], it); - pl_item_unref (it); - it = NULL; + if (last_added) { + pl_item_unref (last_added); + } + last_added = it; } // load playlist metadata @@ -2467,18 +2528,15 @@ pl_load (const char *fname) { if (fp) { fclose (fp); } - return 0; + trace ("plt_load: success\n"); + return last_added; load_fail: fprintf (stderr, "playlist load fail (%s)!\n", fname); - if (it) { - pl_item_unref (it); - } - pl_clear (); UNLOCK; if (fp) { fclose (fp); } - return -1; + return last_added; } int @@ -2498,7 +2556,14 @@ pl_load_all (void) { if (plt_add (plt_get_count (), _("Default")) < 0) { return -1; } - return pl_load (defpl); + + playlist_t *plt = plt_get_for_idx (0); + playItem_t *it = plt_load (plt, NULL, defpl, NULL, NULL, NULL); + if (it) { + pl_item_unref (it); + } + plt_unref (plt); + return 0; } trace ("pl_load_all started\n"); LOCK; @@ -2510,7 +2575,7 @@ pl_load_all (void) { if (plt_add (plt_get_count (), it->value) < 0) { return -1; } - plt_set_curr (plt_get_count () - 1); + plt_set_curr_idx (plt_get_count () - 1); } err = 0; if (snprintf (path, sizeof (path), "%s/playlists/%d.dbpl", dbconfdir, i) > sizeof (path)) { @@ -2519,9 +2584,16 @@ pl_load_all (void) { } else { fprintf (stderr, "INFO: from file %s\n", path); - int load_err = pl_load (path); - if (load_err != 0) { - fprintf (stderr, "WARNING: failed to load playlist '%s' (%s)\n", it->value, path); + + playlist_t *plt = plt_get_curr (); + playItem_t *trk = plt_load (plt, NULL, path, NULL, NULL, NULL); + if (trk) { + pl_item_unref (trk); + } + plt_unref (plt); + + if (!it) { + fprintf (stderr, "WARNING: there were errors while loading playlist '%s' (%s)\n", it->value, path); } } it = conf_find ("playlist.tab.", it); @@ -3358,15 +3430,16 @@ void pl_move_items (int iter, int plt_from, playItem_t *drop_before, uint32_t *indexes, int count) { LOCK; - playlist_t *playlist = playlists_head; - playlist_t *to = plt_get_curr_ptr (); - - int i; - for (i = 0; i < plt_from; i++) { - playlist = playlist->next; - } + playlist_t *playlist = plt_get_for_idx (plt_from); + playlist_t *to = plt_get_curr (); if (!playlist || !to) { + if (to) { + plt_unref (to); + } + if (playlist) { + plt_unref (playlist); + } UNLOCK; return; } @@ -3405,6 +3478,12 @@ pl_move_items (int iter, int plt_from, playItem_t *drop_before, uint32_t *indexe } } no_remove_notify = 0; + if (to) { + plt_unref (to); + } + if (playlist) { + plt_unref (playlist); + } UNLOCK; } @@ -3412,20 +3491,21 @@ void pl_copy_items (int iter, int plt_from, playItem_t *before, uint32_t *indices, int cnt) { pl_lock (); - playlist_t *from = playlists_head; - playlist_t *to = plt_get_curr_ptr (); - - int i; - for (i = 0; i < plt_from; i++) { - from = from->next; - } + playlist_t *from = plt_get_for_idx (plt_from); + playlist_t *to = plt_get_curr (); if (!from || !to) { + if (to) { + plt_unref (to); + } + if (from) { + plt_unref (from); + } pl_unlock (); return; } - for (i = 0; i < cnt; i++) { + for (int i = 0; i < cnt; i++) { playItem_t *it = from->head[iter]; int idx = 0; while (it && idx < indices[i]) { @@ -3444,6 +3524,12 @@ pl_copy_items (int iter, int plt_from, playItem_t *before, uint32_t *indices, in pl_item_unref (it_new); } + if (to) { + plt_unref (to); + } + if (from) { + plt_unref (from); + } pl_unlock (); } diff --git a/playlist.h b/playlist.h index cf156a81..f097198e 100644 --- a/playlist.h +++ b/playlist.h @@ -57,6 +57,7 @@ typedef struct playlist_s { playItem_t *tail[PL_MAX_ITERATORS]; // tail of linked list int current_row[PL_MAX_ITERATORS]; // current row (cursor) struct DB_metaInfo_s *meta; // linked list storing metainfo + int refc; } playlist_t; // global playlist control functions @@ -85,7 +86,16 @@ playlist_t * plt_get_curr_ptr (void); playlist_t * -plt_get (int idx); +plt_get_for_idx (int idx); + +void +plt_ref (playlist_t *plt); + +void +plt_unref (playlist_t *plt); + +void +plt_free (playlist_t *plt); int plt_get_count (void); @@ -109,12 +119,15 @@ int plt_find (const char *name); void -plt_free (void); +plt_set_curr_idx (int plt); + +int +plt_get_curr_idx (void); void -plt_set_curr (int plt); +plt_set_curr (playlist_t *plt); -int +playlist_t * plt_get_curr (void); int @@ -140,6 +153,9 @@ plt_move (int from, int to); void pl_clear (void); +void +plt_clear (playlist_t *plt); + int pl_add_dir (const char *dirname, int (*cb)(playItem_t *it, void *data), void *user_data); @@ -147,7 +163,7 @@ int pl_add_file (const char *fname, int (*cb)(playItem_t *it, void *data), void *user_data); int -pl_add_files_begin (int plt); +pl_add_files_begin (playlist_t *plt); void pl_add_files_end (void); @@ -246,7 +262,7 @@ void pl_crop_selected (void); int -pl_save (const char *fname); +plt_save (playlist_t *plt, playItem_t *first, playItem_t *last, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data); int pl_save_n (int n); @@ -257,8 +273,8 @@ pl_save_current (void); int pl_save_all (void); -int -pl_load (const char *fname); +playItem_t * +plt_load (playlist_t *plt, playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data); int pl_load_all (void); diff --git a/plugins.c b/plugins.c index 399663bc..d589b518 100644 --- a/plugins.c +++ b/plugins.c @@ -105,28 +105,37 @@ static DB_functions_t deadbeef_api = { .cond_signal = cond_signal, .cond_broadcast = cond_broadcast, // playlist management + .plt_ref = (void (*) (ddb_playlist_t *plt))plt_ref, + .plt_unref = (void (*) (ddb_playlist_t *plt))plt_unref, .plt_get_count = plt_get_count, .plt_get_head = (DB_playItem_t * (*) (int plt))plt_get_head, .plt_get_sel_count = plt_get_sel_count, .plt_add = plt_add, .plt_remove = plt_remove, - .plt_set_curr = plt_set_curr, - .plt_get_curr = plt_get_curr, + .plt_clear = (void (*)(ddb_playlist_t *))plt_clear, + .plt_set_curr = (void (*) (ddb_playlist_t *plt))plt_set_curr, + .plt_get_curr = (ddb_playlist_t *(*) (void))plt_get_curr, + .plt_set_curr_idx = (void (*) (int plt))plt_set_curr_idx, + .plt_get_curr_idx = (int (*) (void))plt_get_curr_idx, .plt_move = plt_move, - .plt_get_handle = (void *(*)(int idx))plt_get, - .plt_get_title = (int (*)(void *handle, char *buffer, int sz))plt_get_title, - .plt_set_title = (int (*)(void *handle, const char *buffer))plt_set_title, - .plt_modified = (void (*) (void *handle))plt_modified, - .plt_get_modification_idx = (int (*) (void *handle))plt_get_modification_idx, + // playlist saving and loading + .plt_load = (DB_playItem_t * (*) (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data))plt_load, + .plt_save = (int (*)(ddb_playlist_t *plt, DB_playItem_t *first, DB_playItem_t *last, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data))plt_save, + // getting and working with a handle must be guarded using plt_lock/unlock + .plt_get_for_idx = (ddb_playlist_t *(*)(int idx))plt_get_for_idx, + .plt_get_title = (int (*)(ddb_playlist_t *handle, char *buffer, int sz))plt_get_title, + .plt_set_title = (int (*)(ddb_playlist_t *handle, const char *buffer))plt_set_title, + .plt_modified = (void (*) (ddb_playlist_t *handle))plt_modified, + .plt_get_modification_idx = (int (*) (ddb_playlist_t *handle))plt_get_modification_idx, // playlist metadata - .plt_add_meta = (void (*) (void *handle, const char *key, const char *value))plt_add_meta, - .plt_replace_meta = (void (*) (void *handle, const char *key, const char *value))plt_replace_meta, - .plt_append_meta = (void (*) (void *handle, const char *key, const char *value))plt_append_meta, - .plt_set_meta_int = (void (*) (void *handle, const char *key, int value))plt_set_meta_int, - .plt_set_meta_float = (void (*) (void *handle, const char *key, float value))plt_set_meta_float, - .plt_find_meta = (const char *(*) (void *handle, const char *key))plt_find_meta, - .plt_get_metadata_head = (DB_metaInfo_t * (*) (void *handle))plt_get_metadata_head, + .plt_add_meta = (void (*) (ddb_playlist_t *handle, const char *key, const char *value))plt_add_meta, + .plt_replace_meta = (void (*) (ddb_playlist_t *handle, const char *key, const char *value))plt_replace_meta, + .plt_append_meta = (void (*) (ddb_playlist_t *handle, const char *key, const char *value))plt_append_meta, + .plt_set_meta_int = (void (*) (ddb_playlist_t *handle, const char *key, int value))plt_set_meta_int, + .plt_set_meta_float = (void (*) (ddb_playlist_t *handle, const char *key, float value))plt_set_meta_float, + .plt_find_meta = (const char *(*) (ddb_playlist_t *handle, const char *key))plt_find_meta, + .plt_get_metadata_head = (DB_metaInfo_t * (*) (ddb_playlist_t *handle))plt_get_metadata_head, // playlist access .pl_lock = pl_lock, @@ -140,7 +149,7 @@ static DB_functions_t deadbeef_api = { .pl_item_copy = (void (*)(DB_playItem_t *, DB_playItem_t *))pl_item_copy, .pl_add_file = (int (*) (const char *, int (*cb)(DB_playItem_t *it, void *data), void *))pl_add_file, .pl_add_dir = (int (*) (const char *dirname, int (*cb)(DB_playItem_t *it, void *data), void *user_data))pl_add_dir, - .pl_add_files_begin = pl_add_files_begin, + .pl_add_files_begin = (int (*) (ddb_playlist_t *plt))pl_add_files_begin, .pl_add_files_end = pl_add_files_end, .pl_insert_item = (DB_playItem_t *(*) (DB_playItem_t *after, DB_playItem_t *it))pl_insert_item, .pl_insert_dir = (DB_playItem_t *(*) (DB_playItem_t *after, const char *dirname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data))pl_insert_dir, @@ -165,8 +174,6 @@ static DB_functions_t deadbeef_api = { .pl_set_selected = (void (*) (DB_playItem_t *, int))pl_set_selected, .pl_is_selected = (int (*) (DB_playItem_t *))pl_is_selected, .pl_clear = pl_clear, - .pl_load = pl_load, - .pl_save = pl_save, .pl_save_current = pl_save_current, .pl_save_all = pl_save_all, .pl_select_all = pl_select_all, diff --git a/plugins/cdda/cdda.c b/plugins/cdda/cdda.c index b8b0f84e..9df88719 100644 --- a/plugins/cdda/cdda.c +++ b/plugins/cdda/cdda.c @@ -395,7 +395,11 @@ cddb_thread (void *items_i) } cddb_disc_destroy (disc); cleanup_thread_params (params); - deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ())); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + deadbeef->plt_modified (plt); + deadbeef->plt_unref (plt); + } deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, 0, 0); } @@ -584,10 +588,14 @@ cda_insert (DB_playItem_t *after, const char *fname) { static int cda_action_add_cd (DB_plugin_action_t *act, DB_playItem_t *it) { - deadbeef->pl_add_files_begin (deadbeef->plt_get_curr ()); - deadbeef->pl_add_file ("all.cda", NULL, NULL); - deadbeef->pl_add_files_end (); - deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ())); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + deadbeef->pl_add_files_begin (plt); + deadbeef->pl_add_file ("all.cda", NULL, NULL); + deadbeef->pl_add_files_end (); + deadbeef->plt_modified (plt); + deadbeef->plt_unref (plt); + } deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, 0, 0); } diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c index 1cbbe523..3bf04373 100644 --- a/plugins/gtkui/callbacks.c +++ b/plugins/gtkui/callbacks.c @@ -354,7 +354,7 @@ on_mainwin_key_press_event (GtkWidget *widget, else if ((maskedstate == GDK_MOD1_MASK || maskedstate == 0) && event->keyval >= GDK_1 && event->keyval <= GDK_9) { int pl = event->keyval - GDK_1; if (pl >= 0 && pl < deadbeef->plt_get_count ()) { - deadbeef->plt_set_curr (pl); + deadbeef->plt_set_curr_idx (pl); deadbeef->conf_set_int ("playlist.current", pl); } } @@ -983,7 +983,7 @@ on_new_playlist1_activate (GtkMenuItem *menuitem, { int pl = gtkui_add_new_playlist (); if (pl != -1) { - deadbeef->plt_set_curr (pl); + deadbeef->plt_set_curr_idx (pl); deadbeef->conf_set_int ("playlist.current", pl); } } diff --git a/plugins/gtkui/ddblistview.c b/plugins/gtkui/ddblistview.c index 588439c6..14dd9a70 100644 --- a/plugins/gtkui/ddblistview.c +++ b/plugins/gtkui/ddblistview.c @@ -1687,7 +1687,7 @@ ddb_listview_list_mousemove (DdbListview *ps, GdkEventMotion *ev, int ex, int ey GtkWidget *widget = ps->list; if (gtk_drag_check_threshold (widget, ps->lastpos[0], ex, ps->lastpos[1], ey)) { ps->dragwait = 0; - ps->drag_source_playlist = deadbeef->plt_get_curr (); + ps->drag_source_playlist = deadbeef->plt_get_curr_idx (); GtkTargetEntry entry = { .target = "DDB_URI_LIST", .flags = GTK_TARGET_SAME_WIDGET, diff --git a/plugins/gtkui/ddbtabstrip.c b/plugins/gtkui/ddbtabstrip.c index 8885d51f..8539a10d 100644 --- a/plugins/gtkui/ddbtabstrip.c +++ b/plugins/gtkui/ddbtabstrip.c @@ -48,7 +48,7 @@ plt_get_title_wrapper (int plt, char *buffer, int len) { return; } deadbeef->pl_lock (); - void *p = deadbeef->plt_get_handle (plt); + void *p = deadbeef->plt_get_for_idx (plt); deadbeef->plt_get_title (p, buffer, len); deadbeef->pl_unlock (); char *end; @@ -353,7 +353,7 @@ ddb_tabstrip_draw_tab (GtkWidget *widget, GdkDrawable *drawable, int idx, int se GdkColor clr; int fallback = 1; deadbeef->pl_lock (); - void *plt = deadbeef->plt_get_handle (idx); + void *plt = deadbeef->plt_get_for_idx (idx); const char *bgclr = deadbeef->plt_find_meta (plt, "gui.bgcolor"); if (bgclr) { int r, g, b; @@ -476,7 +476,7 @@ tabstrip_adjust_hscroll (DdbTabStrip *ts) { ts->hscrollpos = w - (widget->allocation.width - arrow_widget_width*2); deadbeef->conf_set_int ("gtkui.tabscroll", ts->hscrollpos); } - tabstrip_scroll_to_tab_int (ts, deadbeef->plt_get_curr (), 0); + tabstrip_scroll_to_tab_int (ts, deadbeef->plt_get_curr_idx (), 0); } else { ts->hscrollpos = 0; @@ -491,7 +491,7 @@ set_tab_text_color (int idx, int selected) { return; } deadbeef->pl_lock (); - void *plt = deadbeef->plt_get_handle (idx); + void *plt = deadbeef->plt_get_for_idx (idx); int fallback = 1; const char *clr = deadbeef->plt_find_meta (plt, "gui.color"); if (clr) { @@ -534,7 +534,7 @@ tabstrip_render (DdbTabStrip *ts) { text_right_padding = h - 3; const char *detail = "button"; - int tab_selected = deadbeef->plt_get_curr (); + int tab_selected = deadbeef->plt_get_curr_idx (); if (tab_selected == -1) { return; } @@ -655,7 +655,7 @@ get_tab_under_cursor (DdbTabStrip *ts, int x) { int idx; int cnt = deadbeef->plt_get_count (); int fw = tabs_left_margin - hscroll; - int tab_selected = deadbeef->plt_get_curr (); + int tab_selected = deadbeef->plt_get_curr_idx (); for (idx = 0; idx < cnt; idx++) { char title[100]; plt_get_title_wrapper (idx, title, sizeof (title)); @@ -693,7 +693,7 @@ on_rename_playlist1_activate (GtkMenuItem *menuitem, if (res == GTK_RESPONSE_OK) { const char *text = gtk_entry_get_text (GTK_ENTRY (e)); deadbeef->pl_lock (); - void *p = deadbeef->plt_get_handle (tab_clicked); + void *p = deadbeef->plt_get_for_idx (tab_clicked); deadbeef->plt_set_title (p, text); deadbeef->pl_unlock (); } @@ -710,7 +710,7 @@ on_remove_playlist1_activate (GtkMenuItem *menuitem, DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist")); ddb_listview_refresh (pl, DDB_LIST_CHANGED | DDB_REFRESH_LIST | DDB_REFRESH_VSCROLL); search_refresh (); - int playlist = deadbeef->plt_get_curr (); + int playlist = deadbeef->plt_get_curr_idx (); deadbeef->conf_set_int ("playlist.current", playlist); } } @@ -772,7 +772,7 @@ create_plmenu (void) static void tabstrip_scroll_left (DdbTabStrip *ts) { - int tab = deadbeef->plt_get_curr (); + int tab = deadbeef->plt_get_curr_idx (); if (tab > 0) { tab--; gtkui_playlist_set_curr (tab); @@ -782,7 +782,7 @@ tabstrip_scroll_left (DdbTabStrip *ts) { static void tabstrip_scroll_right (DdbTabStrip *ts) { - int tab = deadbeef->plt_get_curr (); + int tab = deadbeef->plt_get_curr_idx (); if (tab < deadbeef->plt_get_count ()-1) { tab++; gtkui_playlist_set_curr (tab); @@ -907,7 +907,7 @@ on_tabstrip_button_press_event(GtkWidget *widget, DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist")); ddb_listview_refresh (pl, DDB_LIST_CHANGED | DDB_REFRESH_LIST | DDB_REFRESH_VSCROLL); search_refresh (); - int playlist = deadbeef->plt_get_curr (); + int playlist = deadbeef->plt_get_curr_idx (); deadbeef->conf_set_int ("playlist.current", playlist); } } @@ -1039,7 +1039,7 @@ on_tabstrip_drag_motion_event (GtkWidget *widget, guint time) { int tab = get_tab_under_cursor (DDB_TABSTRIP (widget), x); - int prev = deadbeef->plt_get_curr (); + int prev = deadbeef->plt_get_curr_idx (); if (tab != -1 && tab != prev) { gtkui_playlist_set_curr (tab); } diff --git a/plugins/gtkui/fileman.c b/plugins/gtkui/fileman.c index 6ff981b4..a832df09 100644 --- a/plugins/gtkui/fileman.c +++ b/plugins/gtkui/fileman.c @@ -26,9 +26,8 @@ gtkpl_add_dirs (GSList *lst) { deadbeef->pl_add_files_begin (deadbeef->plt_get_curr ()); if (g_slist_length (lst) == 1 && deadbeef->conf_get_int ("gtkui.name_playlist_from_folder", 0)) { - int plt = deadbeef->plt_get_curr (); - if (plt != -1) { - void *p = deadbeef->plt_get_handle (plt); + ddb_playlist_t *p = deadbeef->plt_get_curr (); + if (p) { char t[1000]; if (!deadbeef->plt_get_title (p, t, sizeof (t))) { char *def = _("New Playlist"); @@ -40,6 +39,7 @@ gtkpl_add_dirs (GSList *lst) { deadbeef->plt_set_title (p, folder+1); } } + deadbeef->plt_unref (p); } } deadbeef->pl_unlock (); diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c index 4d682d6e..7b0583c2 100644 --- a/plugins/gtkui/gtkui.c +++ b/plugins/gtkui/gtkui.c @@ -473,7 +473,7 @@ gtkui_playlist_changed (void) { static gboolean playlistswitch_cb (gpointer none) { GtkWidget *tabstrip = lookup_widget (mainwin, "tabstrip"); - int curr = deadbeef->plt_get_curr (); + int curr = deadbeef->plt_get_curr_idx (); char conf[100]; snprintf (conf, sizeof (conf), "playlist.scroll.%d", curr); int scroll = deadbeef->conf_get_int (conf, 0); @@ -577,10 +577,11 @@ gtkui_hide_status_icon () { int gtkui_get_curr_playlist_mod (void) { - deadbeef->pl_lock (); - void *plt = deadbeef->plt_get_handle (deadbeef->plt_get_curr ()); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); int res = plt ? deadbeef->plt_get_modification_idx (plt) : 0; - deadbeef->pl_unlock (); + if (plt) { + deadbeef->plt_unref (plt); + } return res; } @@ -672,9 +673,13 @@ save_playlist_as (void) { gtk_widget_destroy (dlg); if (fname) { - int res = deadbeef->pl_save (fname); - if (res >= 0 && strlen (fname) < 1024) { - strcpy (last_playlist_save_name, fname); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + int res = deadbeef->plt_save (plt, NULL, NULL, fname, NULL, NULL, NULL); + if (res >= 0 && strlen (fname) < 1024) { + strcpy (last_playlist_save_name, fname); + } + deadbeef->plt_unref (plt); } g_free (fname); } @@ -692,7 +697,11 @@ on_playlist_save_activate (GtkMenuItem *menuitem, save_playlist_as (); } else { - /*int res = */deadbeef->pl_save (last_playlist_save_name); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + deadbeef->plt_save (plt, NULL, NULL, last_playlist_save_name, NULL, NULL, NULL); + deadbeef->plt_unref (plt); + } } } @@ -763,7 +772,15 @@ on_playlist_load_activate (GtkMenuItem *menuitem, gchar *fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg)); gtk_widget_destroy (dlg); if (fname) { - /*int res = */deadbeef->pl_load (fname); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + deadbeef->plt_clear (plt); + DB_playItem_t *it = deadbeef->plt_load (plt, NULL, fname, NULL, NULL, NULL); + if (it) { + deadbeef->pl_item_unref (it); + } + deadbeef->plt_unref (plt); + } g_free (fname); main_refresh (); search_refresh (); @@ -798,22 +815,21 @@ on_add_location_activate (GtkMenuItem *menuitem, static void songchanged (DdbListview *ps, DB_playItem_t *from, DB_playItem_t *to) { - int plt = deadbeef->plt_get_curr (); int to_idx = -1; if (!ddb_listview_is_scrolling (ps) && to) { int cursor_follows_playback = deadbeef->conf_get_int ("playlist.scroll.cursorfollowplayback", 0); int scroll_follows_playback = deadbeef->conf_get_int ("playlist.scroll.followplayback", 0); int plt = deadbeef->streamer_get_current_playlist (); if (plt != -1) { - if (cursor_follows_playback && plt != deadbeef->plt_get_curr ()) { - deadbeef->plt_set_curr (plt); + if (cursor_follows_playback && plt != deadbeef->plt_get_curr_idx ()) { + deadbeef->plt_set_curr_idx (plt); } to_idx = deadbeef->pl_get_idx_of (to); if (to_idx != -1) { if (cursor_follows_playback) { ddb_listview_set_cursor_noscroll (ps, to_idx); } - if (scroll_follows_playback && plt == deadbeef->plt_get_curr ()) { + if (scroll_follows_playback && plt == deadbeef->plt_get_curr_idx ()) { ddb_listview_scroll_to (ps, to_idx); } } @@ -891,7 +907,7 @@ gtkui_add_new_playlist (void) { deadbeef->pl_lock (); for (i = 0; i < cnt; i++) { char t[100]; - void *plt = deadbeef->plt_get_handle (i); + void *plt = deadbeef->plt_get_for_idx (i); deadbeef->plt_get_title (plt, t, sizeof (t)); if (!strcasecmp (t, name)) { break; @@ -1127,7 +1143,7 @@ gtkui_add_file_info_cb (DB_playItem_t *it, void *data) { int (*gtkui_original_pl_add_dir) (const char *dirname, int (*cb)(DB_playItem_t *it, void *data), void *user_data); int (*gtkui_original_pl_add_file) (const char *fname, int (*cb)(DB_playItem_t *it, void *data), void *user_data); -void (*gtkui_original_pl_add_files_begin) (int plt); +int (*gtkui_original_pl_add_files_begin) (ddb_playlist_t *plt); void (*gtkui_original_pl_add_files_end) (void); int @@ -1142,10 +1158,10 @@ gtkui_pl_add_file (const char *filename, int (*cb)(DB_playItem_t *it, void *data return res; } -void -gtkui_pl_add_files_begin (int plt) { +int +gtkui_pl_add_files_begin (ddb_playlist_t *plt) { g_idle_add (gtkui_progress_show_idle, NULL); - gtkui_original_pl_add_files_begin (plt); + return gtkui_original_pl_add_files_begin (plt); } void @@ -1159,8 +1175,8 @@ gtkui_focus_on_playing_track (void) { DB_playItem_t *it = deadbeef->streamer_get_playing_track (); if (it) { int plt = deadbeef->streamer_get_current_playlist (); - if (plt != deadbeef->plt_get_curr ()) { - deadbeef->plt_set_curr (plt); + if (plt != deadbeef->plt_get_curr_idx ()) { + deadbeef->plt_set_curr_idx (plt); } int idx = deadbeef->pl_get_idx_of (it); if (idx != -1) { @@ -1174,7 +1190,7 @@ gtkui_focus_on_playing_track (void) { void gtkui_playlist_set_curr (int playlist) { - deadbeef->plt_set_curr (playlist); + deadbeef->plt_set_curr_idx (playlist); deadbeef->conf_set_int ("playlist.current", playlist); } diff --git a/plugins/gtkui/mainplaylist.c b/plugins/gtkui/mainplaylist.c index e1537ea0..57b693f8 100644 --- a/plugins/gtkui/mainplaylist.c +++ b/plugins/gtkui/mainplaylist.c @@ -109,7 +109,7 @@ int main_get_idx (DdbListviewIter it) { void main_drag_n_drop (DdbListviewIter before, int from_playlist, uint32_t *indices, int length, int copy) { deadbeef->pl_lock (); - int curr = deadbeef->plt_get_curr (); +// int curr = deadbeef->plt_get_curr_idx (); if (copy) { deadbeef->pl_copy_items (PL_MAIN, from_playlist, (DB_playItem_t *)before, indices, length); } @@ -238,7 +238,7 @@ void main_col_free_user_data (void *data) { void main_vscroll_changed (int pos) { coverart_reset_queue (); - int curr = deadbeef->plt_get_curr (); + int curr = deadbeef->plt_get_curr_idx (); char conf[100]; snprintf (conf, sizeof (conf), "playlist.scroll.%d", curr); deadbeef->conf_set_int (conf, pos); diff --git a/plugins/gtkui/plcommon.c b/plugins/gtkui/plcommon.c index 6945e5d3..e319ac56 100644 --- a/plugins/gtkui/plcommon.c +++ b/plugins/gtkui/plcommon.c @@ -538,9 +538,11 @@ on_group_by_none_activate (GtkMenuItem *menuitem, strcpy (group_by_str, ""); deadbeef->conf_set_str ("playlist.group_by", group_by_str); - deadbeef->pl_lock (); - deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ())); - deadbeef->pl_unlock (); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + deadbeef->plt_modified (plt); + deadbeef->plt_unref (plt); + } main_refresh (); } @@ -550,9 +552,11 @@ on_group_by_artist_date_album_activate (GtkMenuItem *menuitem, { strcpy (group_by_str, "%a - [%y] %b"); deadbeef->conf_set_str ("playlist.group_by", group_by_str); - deadbeef->pl_lock (); - deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ())); - deadbeef->pl_unlock (); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + deadbeef->plt_modified (plt); + deadbeef->plt_unref (plt); + } main_refresh (); } @@ -562,9 +566,11 @@ on_group_by_artist_activate (GtkMenuItem *menuitem, { strcpy (group_by_str, "%a"); deadbeef->conf_set_str ("playlist.group_by", group_by_str); - deadbeef->pl_lock (); - deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ())); - deadbeef->pl_unlock (); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + deadbeef->plt_modified (plt); + deadbeef->plt_unref (plt); + } main_refresh (); } @@ -585,9 +591,11 @@ on_group_by_custom_activate (GtkMenuItem *menuitem, strncpy (group_by_str, text, sizeof (group_by_str)); group_by_str[sizeof (group_by_str)-1] = 0; deadbeef->conf_set_str ("playlist.group_by", group_by_str); - deadbeef->pl_lock (); - deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ())); - deadbeef->pl_unlock (); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + deadbeef->plt_modified (plt); + deadbeef->plt_unref (plt); + } main_refresh (); } gtk_widget_destroy (dlg); diff --git a/plugins/gtkui/trkproperties.c b/plugins/gtkui/trkproperties.c index 12e51924..4e865eee 100644 --- a/plugins/gtkui/trkproperties.c +++ b/plugins/gtkui/trkproperties.c @@ -462,7 +462,11 @@ static gboolean write_finished_cb (void *ctx) { gtk_widget_destroy (progressdlg); progressdlg = NULL; - deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ())); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + deadbeef->plt_modified (plt); + deadbeef->plt_unref (plt); + } main_refresh (); search_refresh (); trkproperties_modified = 0; diff --git a/plugins/vfs_curl/vfs_curl.c b/plugins/vfs_curl/vfs_curl.c index 0ef5cc6a..acb0b561 100644 --- a/plugins/vfs_curl/vfs_curl.c +++ b/plugins/vfs_curl/vfs_curl.c @@ -212,7 +212,11 @@ http_parse_shoutcast_meta (HTTP_FILE *fp, const char *meta, int size) { else { vfs_curl_set_meta (fp->track, "title", title); } - deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ())); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + deadbeef->plt_modified (plt); + deadbeef->plt_unref (plt); + } deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, 0, 0); } return 0; @@ -468,7 +472,11 @@ http_content_header_handler (void *ptr, size_t size, size_t nmemb, void *stream) fp->wait_meta = fp->icy_metaint; } } - deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ())); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + deadbeef->plt_modified (plt); + deadbeef->plt_unref (plt); + } if (refresh_playlist) { deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, 0, 0); } diff --git a/plugins/vorbis/vorbis.c b/plugins/vorbis/vorbis.c index 27275eec..ee1871a4 100644 --- a/plugins/vorbis/vorbis.c +++ b/plugins/vorbis/vorbis.c @@ -165,7 +165,12 @@ update_vorbis_comments (DB_playItem_t *it, vorbis_comment *vc, int refresh_playl f &= ~DDB_TAG_MASK; f |= DDB_TAG_VORBISCOMMENTS; deadbeef->pl_set_item_flags (it, f); - deadbeef->plt_modified (deadbeef->plt_get_handle (deadbeef->plt_get_curr ())); + ddb_playlist_t *plt = deadbeef->plt_get_curr (); + if (plt) { + deadbeef->plt_modified (plt); + deadbeef->plt_unref (plt); + } + if (refresh_playlist) { deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, 0, 0); } diff --git a/streamer.c b/streamer.c index 82f12f97..b6aee683 100644 --- a/streamer.c +++ b/streamer.c @@ -199,7 +199,7 @@ int str_get_idx_of (playItem_t *it) { pl_lock (); if (!streamer_playlist) { - streamer_playlist = plt_get_curr_ptr (); + streamer_playlist = plt_get_curr (); } playItem_t *c = streamer_playlist->head[PL_MAIN]; int idx = 0; @@ -219,7 +219,7 @@ playItem_t * str_get_for_idx (int idx) { pl_lock (); if (!streamer_playlist) { - streamer_playlist = plt_get_curr_ptr (); + streamer_playlist = plt_get_curr (); } playItem_t *it = streamer_playlist->head[PL_MAIN]; while (idx--) { @@ -242,7 +242,7 @@ streamer_move_to_nextsong (int reason) { trace ("streamer_move_to_nextsong (%d)\n", reason); pl_lock (); if (!streamer_playlist) { - streamer_playlist = plt_get_curr_ptr (); + streamer_playlist = plt_get_curr (); } while (pl_playqueue_getcount ()) { trace ("pl_playqueue_getnext\n"); @@ -284,7 +284,11 @@ streamer_move_to_nextsong (int reason) { playItem_t *curr = playlist_track; if (reason == 1) { - streamer_playlist = plt_get_curr_ptr (); + if (streamer_playlist) { + plt_unref (streamer_playlist); + streamer_playlist = NULL; + } + streamer_playlist = plt_get_curr (); // check if prev song is in this playlist if (-1 == str_get_idx_of (curr)) { curr = NULL; @@ -424,10 +428,11 @@ streamer_move_to_nextsong (int reason) { int streamer_move_to_prevsong (void) { pl_lock (); - if (!streamer_playlist) { - streamer_playlist = plt_get_curr_ptr (); + if (streamer_playlist) { + plt_unref (streamer_playlist); + streamer_playlist = NULL; } - streamer_playlist = plt_get_curr_ptr (); + streamer_playlist = plt_get_curr (); // check if prev song is in this playlist if (-1 == str_get_idx_of (playlist_track)) { playlist_track = NULL; @@ -527,7 +532,7 @@ streamer_move_to_prevsong (void) { int streamer_move_to_randomsong (void) { if (!streamer_playlist) { - streamer_playlist = plt_get_curr_ptr (); + streamer_playlist = plt_get_curr (); } playlist_t *plt = streamer_playlist; int cnt = plt->count[PL_MAIN]; @@ -797,7 +802,11 @@ streamer_set_nextsong (int song, int pstate) { if (output->state () == OUTPUT_STATE_STOPPED) { if (pstate == 1) { // means user initiated this pl_lock (); - streamer_playlist = plt_get_curr_ptr (); + if (streamer_playlist) { + plt_unref (streamer_playlist); + streamer_playlist = NULL; + } + streamer_playlist = plt_get_curr (); pl_unlock (); } // no sense to wait until end of previous song, reset buffer @@ -1498,6 +1507,10 @@ streamer_free (void) { if (playlist_track) { playlist_track = NULL; } + if (streamer_playlist) { + plt_unref (streamer_playlist); + streamer_playlist = NULL; + } decodemutex = 0; mutex_free (mutex); @@ -1827,7 +1840,7 @@ streamer_configchanged (void) { void streamer_play_current_track (void) { - playlist_t *plt = plt_get_curr_ptr (); + playlist_t *plt = plt_get_curr (); DB_output_t *output = plug_get_output (); if (output->state () == OUTPUT_STATE_PAUSED && playing_track) { // unpause currently paused track @@ -1852,6 +1865,7 @@ streamer_play_current_track (void) { streamer_set_nextsong (idx, 1); pl_lock (); streamer_playlist = plt; + plt_ref (plt); pl_unlock (); } else { @@ -1859,6 +1873,9 @@ streamer_play_current_track (void) { output->stop (); streamer_set_nextsong (0, 1); } + if (plt) { + plt_unref (plt); + } } struct DB_fileinfo_s * @@ -1869,7 +1886,11 @@ streamer_get_current_fileinfo (void) { void streamer_set_current_playlist (int plt) { pl_lock (); - streamer_playlist = plt_get (plt); + if (streamer_playlist) { + plt_unref (streamer_playlist); + streamer_playlist = NULL; + } + streamer_playlist = plt_get_for_idx (plt); pl_unlock (); } @@ -1877,7 +1898,7 @@ int streamer_get_current_playlist (void) { pl_lock (); if (!streamer_playlist) { - streamer_playlist = plt_get_curr_ptr (); + streamer_playlist = plt_get_curr (); } int idx = plt_get_idx_of (streamer_playlist); pl_unlock (); @@ -1888,6 +1909,7 @@ void streamer_notify_playlist_deleted (playlist_t *plt) { // this is only called from playlist code, no lock required if (plt == streamer_playlist) { + plt_unref (streamer_playlist); streamer_playlist = NULL; } } -- cgit v1.2.3