From 6498b5187f44a48571aac268c9c377b7c3e6af7b Mon Sep 17 00:00:00 2001 From: waker Date: Tue, 24 Apr 2012 19:40:56 +0200 Subject: shellexec[ui]: cleaned up api, fixed memleaks, add/remove/edit works without restarting player, Disabled flag is not user-editable and is not saved to config --- deadbeef.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'deadbeef.h') diff --git a/deadbeef.h b/deadbeef.h index f5b999ad..a42dd4ba 100644 --- a/deadbeef.h +++ b/deadbeef.h @@ -268,6 +268,7 @@ enum { DB_EV_OUTPUTCHANGED = 17, // sound output plugin changed DB_EV_PLAYLISTSWITCHED = 18, // playlist switch occured DB_EV_SEEK = 19, // seek current track to position p1 (ms) + DB_EV_ACTIONSCHANGED = 20, // plugin actions were changed, e.g. for reinitializing gui DB_EV_FIRST = 1000, DB_EV_SONGCHANGED = 1000, // current song changed from one to another, ctx=ddb_event_trackchange_t @@ -859,7 +860,8 @@ typedef struct DB_plugin_s { // cmdline_size is number of bytes pointed by cmdline int (*exec_cmdline) (const char *cmdline, int cmdline_size); - // @returns linked list of actions + // @returns linked list of actions for the specified track + // when it is NULL -- the plugin must return list of all actions DB_plugin_action_t* (*get_actions) (DB_playItem_t *it); // mainloop will call this function for every plugin -- cgit v1.2.3 From ec73fcadec7634c074897ecd9c19f42baf190ef7 Mon Sep 17 00:00:00 2001 From: waker Date: Thu, 26 Apr 2012 21:00:47 +0200 Subject: added new DB_EV_DSPCHANGED event --- deadbeef.h | 1 + streamer.c | 1 + 2 files changed, 2 insertions(+) (limited to 'deadbeef.h') diff --git a/deadbeef.h b/deadbeef.h index a42dd4ba..73452c4e 100644 --- a/deadbeef.h +++ b/deadbeef.h @@ -269,6 +269,7 @@ enum { DB_EV_PLAYLISTSWITCHED = 18, // playlist switch occured DB_EV_SEEK = 19, // seek current track to position p1 (ms) DB_EV_ACTIONSCHANGED = 20, // plugin actions were changed, e.g. for reinitializing gui + DB_EV_DSPCHAINCHANGED = 21, // emitted when any parameter of the main dsp chain has been changed DB_EV_FIRST = 1000, DB_EV_SONGCHANGED = 1000, // current song changed from one to another, ctx=ddb_event_trackchange_t diff --git a/streamer.c b/streamer.c index 69db8029..1c5241c5 100644 --- a/streamer.c +++ b/streamer.c @@ -2221,6 +2221,7 @@ streamer_set_dsp_chain (ddb_dsp_context_t *chain) { if (playing_track && output->state () != OUTPUT_STATE_STOPPED) { streamer_set_seek (playpos); } + messagepump_push (DB_EV_DSPCHAINCHANGED, 0, 0, 0); } void -- cgit v1.2.3 From 816d87e1d38dc0fecbe1fa47794b2d7a18d2e321 Mon Sep 17 00:00:00 2001 From: waker Date: Thu, 17 May 2012 20:50:47 +0200 Subject: fixed many calls to pl_find_meta[_raw] being called without pl_lock; added debug pl_ensure_lock function which asserts when pl_lock is not set when it is required; added new API functions for thread-safe metadata access --- deadbeef.h | 11 +++++ playlist.c | 20 +++++++++- playlist.h | 15 +++++++ plmeta.c | 45 +++++++++++++++++---- pltmeta.c | 13 ++++++ plugins.c | 5 +++ plugins/gtkui/gtkui.c | 6 +-- plugins/gtkui/plcommon.c | 12 +++++- plugins/gtkui/trkproperties.c | 18 +++++++-- plugins/lastfm/lastfm.c | 93 +++++++++++++++++++++---------------------- plugins/mpgmad/mpgmad.c | 23 +++++++---- plugins/shellexec/shellexec.c | 2 + streamer.c | 4 ++ 13 files changed, 194 insertions(+), 73 deletions(-) (limited to 'deadbeef.h') diff --git a/deadbeef.h b/deadbeef.h index 73452c4e..6de9e9d0 100644 --- a/deadbeef.h +++ b/deadbeef.h @@ -61,6 +61,7 @@ extern "C" { // api version history: // 9.9 -- devel +// 1.4 -- deadbeef-0.5.5 // 1.3 -- deadbeef-0.5.3 // 1.2 -- deadbeef-0.5.2 // 1.1 -- deadbeef-0.5.1 @@ -750,10 +751,20 @@ typedef struct { void (*metacache_unref) (const char *str); // this function must return original un-overriden value (ignoring the keys prefixed with '!') + // it's not thread-safe, and must be used under the same conditions as the + // pl_find_meta const char *(*pl_find_meta_raw) (DB_playItem_t *it, const char *key); // ******* new 1.3 APIs ******** int (*streamer_dsp_chain_save) (void); + + // ******* new 1.4 APIs ******** + int (*pl_get_meta) (DB_playItem_t *it, const char *key, char *val, int size); + int (*pl_get_meta_raw) (DB_playItem_t *it, const char *key, char *val, int size); + int (*plt_get_meta) (ddb_playlist_t *handle, const char *key, char *val, int size); + + // fast way to test if a field exists in playitem + int (*pl_meta_exists) (DB_playItem_t *it, const char *key); } DB_functions_t; // NOTE: an item placement must be selected like this diff --git a/playlist.c b/playlist.c index 11a280c1..d50bff77 100644 --- a/playlist.c +++ b/playlist.c @@ -55,7 +55,7 @@ #define DISABLE_LOCKING 0 #define DEBUG_LOCKING 0 -//#define DETECT_PL_LOCK_RC 1 +#define DETECT_PL_LOCK_RC 1 // file format revision history // 1.1->1.2 changelog: @@ -186,7 +186,7 @@ pl_lock (void) { #if !DISABLE_LOCKING mutex_lock (mutex); #if DETECT_PL_LOCK_RC - pl_lock_tid = pthread_self(); + pl_lock_tid = pthread_self (); tids[ntids++] = pl_lock_tid; #endif @@ -1170,10 +1170,12 @@ error: playItem_t * plt_insert_cue (playlist_t *plt, playItem_t *after, playItem_t *origin, int numsamples, int samplerate) { trace ("pl_insert_cue numsamples=%d, samplerate=%d\n", numsamples, samplerate); + pl_lock (); const char *fname = pl_find_meta_raw (origin, ":URI"); int len = strlen (fname); char cuename[len+5]; strcpy (cuename, fname); + pl_unlock (); strcpy (cuename+len, ".cue"); DB_FILE *fp = vfs_fopen (cuename); if (!fp) { @@ -3812,3 +3814,17 @@ int plt_is_fast_mode (playlist_t *plt) { return plt->fast_mode; } + +void +pl_ensure_lock (void) { +#if DETECT_PL_LOCK_RC + pthread_t tid = pthread_self (); + for (int i = 0; i < ntids; i++) { + if (tids[i] == tid) { + return; + } + } + fprintf (stderr, "\033[0;31mnon-thread-safe playlist access function was called outside of pl_lock. please make a backtrace and post a bug. thank you.\033[37;0m\n"); + assert(0); +#endif +} diff --git a/playlist.h b/playlist.h index fefb3943..06966bde 100644 --- a/playlist.h +++ b/playlist.h @@ -454,4 +454,19 @@ plt_set_fast_mode (playlist_t *plt, int fast); int plt_is_fast_mode (playlist_t *plt); +void +pl_ensure_lock (void); + +int +pl_get_meta (playItem_t *it, const char *key, char *val, int size); + +int +pl_get_meta_raw (playItem_t *it, const char *key, char *val, int size); + +int +pl_meta_exists (playItem_t *it, const char *key); + +int +plt_get_meta (playlist_t *handle, const char *key, char *val, int size); + #endif // __PLAYLIST_H diff --git a/plmeta.c b/plmeta.c index cf17f341..4b8e9a8a 100644 --- a/plmeta.c +++ b/plmeta.c @@ -190,14 +190,13 @@ pl_delete_meta (playItem_t *it, const char *key) { const char * pl_find_meta (playItem_t *it, const char *key) { - pl_lock (); + pl_ensure_lock (); DB_metaInfo_t *m = it->meta; if (key && key[0] == ':') { // try to find an override while (m) { if (m->key[0] == '!' && !strcasecmp (key+1, m->key+1)) { - pl_unlock (); return m->value; } m = m->next; @@ -207,27 +206,23 @@ pl_find_meta (playItem_t *it, const char *key) { m = it->meta; while (m) { if (!strcasecmp (key, m->key)) { - pl_unlock (); return m->value; } m = m->next; } - pl_unlock (); return NULL; } const char * pl_find_meta_raw (playItem_t *it, const char *key) { - pl_lock (); + pl_ensure_lock (); DB_metaInfo_t *m = it->meta; while (m) { if (!strcasecmp (key, m->key)) { - pl_unlock (); return m->value; } m = m->next; } - pl_unlock (); return NULL; } @@ -303,3 +298,39 @@ pl_delete_all_meta (playItem_t *it) { } UNLOCK; } + +int +pl_get_meta (playItem_t *it, const char *key, char *val, int size) { + *val = 0; + pl_lock (); + const char *v = pl_find_meta (it, key); + if (!val) { + pl_unlock (); + return 0; + } + strncpy (val, v, size); + pl_unlock (); + return 1; +} + +int +pl_get_meta_raw (playItem_t *it, const char *key, char *val, int size) { + *val = 0; + pl_lock (); + const char *v = pl_find_meta_raw (it, key); + if (!val) { + pl_unlock (); + return 0; + } + strncpy (val, v, size); + pl_unlock (); + return 1; +} + +int +pl_meta_exists (playItem_t *it, const char *key) { + pl_lock (); + const char *v = pl_find_meta (it, key); + pl_unlock (); + return v ? 1 : 0; +} diff --git a/pltmeta.c b/pltmeta.c index e2e6cd04..63c7279c 100644 --- a/pltmeta.c +++ b/pltmeta.c @@ -234,3 +234,16 @@ plt_delete_all_meta (playlist_t *it) { UNLOCK; } +int +plt_get_meta (playlist_t *handle, const char *key, char *val, int size) { + *val = 0; + LOCK; + const char *v = plt_find_meta (handle, key); + if (!v) { + UNLOCK; + return 0; + } + strncpy (val, v, size); + UNLOCK; + return 1; +} diff --git a/plugins.c b/plugins.c index 522930de..c5f56c4f 100644 --- a/plugins.c +++ b/plugins.c @@ -331,6 +331,11 @@ static DB_functions_t deadbeef_api = { .pl_find_meta_raw = (const char *(*) (DB_playItem_t *it, const char *key))pl_find_meta_raw, // ******* new 1.3 APIs ******** .streamer_dsp_chain_save = streamer_dsp_chain_save, + // ******* new 1.4 APIs ******** + .pl_get_meta = (int (*) (DB_playItem_t *it, const char *key, char *val, int size))pl_get_meta, + .pl_get_meta_raw = (int (*) (DB_playItem_t *it, const char *key, char *val, int size))pl_get_meta_raw, + .plt_get_meta = (int (*) (ddb_playlist_t *handle, const char *key, char *val, int size))plt_get_meta, + .pl_meta_exists = (int (*) (DB_playItem_t *it, const char *key))pl_meta_exists, }; DB_functions_t *deadbeef = &deadbeef_api; diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c index 7ded4f6d..b96eb301 100644 --- a/plugins/gtkui/gtkui.c +++ b/plugins/gtkui/gtkui.c @@ -192,9 +192,9 @@ update_songinfo (gpointer ctx) { } } const char *spaused = deadbeef->get_output ()->state () == OUTPUT_STATE_PAUSED ? _("Paused | ") : ""; - const char *filetype = deadbeef->pl_find_meta (track, ":FILETYPE"); - if (!filetype) { - filetype = "-"; + char filetype[20]; + if (!deadbeef->pl_get_meta (track, ":FILETYPE", filetype, sizeof (filetype))) { + strcpy (filetype, "-"); } snprintf (sbtext_new, sizeof (sbtext_new), _("%s%s %s| %dHz | %d bit | %s | %d:%02d / %s | %d tracks | %s total playtime"), spaused, filetype, sbitrate, samplerate, bitspersample, mode, minpos, secpos, t, deadbeef->pl_getcount (PL_MAIN), totaltime_str); } diff --git a/plugins/gtkui/plcommon.c b/plugins/gtkui/plcommon.c index 406b2f16..f0c36a24 100644 --- a/plugins/gtkui/plcommon.c +++ b/plugins/gtkui/plcommon.c @@ -256,8 +256,16 @@ main_reload_metadata_activate DdbListview *ps = DDB_LISTVIEW (g_object_get_data (G_OBJECT (menuitem), "ps")); DB_playItem_t *it = deadbeef->pl_get_first (PL_MAIN); while (it) { - const char *decoder_id = deadbeef->pl_find_meta (it, ":DECODER"); - if (deadbeef->pl_is_selected (it) && deadbeef->is_local_file (deadbeef->pl_find_meta (it, ":URI")) && decoder_id) { + deadbeef->pl_lock (); + char decoder_id[100]; + const char *dec = deadbeef->pl_find_meta (it, ":DECODER"); + if (dec) { + strncpy (decoder_id, dec, sizeof (decoder_id)); + } + int match = deadbeef->pl_is_selected (it) && deadbeef->is_local_file (deadbeef->pl_find_meta (it, ":URI")) && dec; + deadbeef->pl_unlock (); + + if (match) { uint32_t f = deadbeef->pl_get_item_flags (it); if (!(f & DDB_IS_SUBTRACK)) { f &= ~DDB_TAG_MASK; diff --git a/plugins/gtkui/trkproperties.c b/plugins/gtkui/trkproperties.c index 590bf1fa..75b1f256 100644 --- a/plugins/gtkui/trkproperties.c +++ b/plugins/gtkui/trkproperties.c @@ -107,6 +107,7 @@ get_field_value (char *out, int size, const char *key, const char *(*getter)(DB_ return 0; } char *p = out; + deadbeef->pl_lock (); const char **prev = malloc (sizeof (const char *) * numtracks); memset (prev, 0, sizeof (const char *) * numtracks); for (int i = 0; i < numtracks; i++) { @@ -142,6 +143,7 @@ get_field_value (char *out, int size, const char *key, const char *(*getter)(DB_ break; } } + deadbeef->pl_unlock (); if (size <= 1) { gchar *prev = g_utf8_prev_char (out-4); strcpy (prev, "..."); @@ -491,8 +493,9 @@ static gboolean set_progress_cb (void *ctx) { DB_playItem_t *track = ctx; GtkWidget *progressitem = lookup_widget (progressdlg, "progresstitle"); - const char *fname = deadbeef->pl_find_meta_raw (track, ":URI"); - gtk_entry_set_text (GTK_ENTRY (progressitem), fname); + deadbeef->pl_lock (); + gtk_entry_set_text (GTK_ENTRY (progressitem), deadbeef->pl_find_meta_raw (track, ":URI")); + deadbeef->pl_unlock (); deadbeef->pl_item_unref (track); return FALSE; } @@ -504,8 +507,15 @@ write_meta_worker (void *ctx) { break; } DB_playItem_t *track = tracks[t]; - const char *decoder_id = deadbeef->pl_find_meta_raw (track, ":DECODER"); - if (track && decoder_id) { + deadbeef->pl_lock (); + const char *dec = deadbeef->pl_find_meta_raw (track, ":DECODER"); + char decoder_id[100]; + if (dec) { + strncpy (decoder_id, dec, sizeof (decoder_id)); + } + int match = track && dec; + deadbeef->pl_unlock (); + if (match) { int is_subtrack = deadbeef->pl_get_item_flags (track) & DDB_IS_SUBTRACK; if (is_subtrack) { continue; diff --git a/plugins/lastfm/lastfm.c b/plugins/lastfm/lastfm.c index 8ab6c5f8..1e4fec70 100644 --- a/plugins/lastfm/lastfm.c +++ b/plugins/lastfm/lastfm.c @@ -49,6 +49,8 @@ static uintptr_t lfm_cond; static int lfm_stopthread; static intptr_t lfm_tid; +#define META_FIELD_SIZE 200 + DB_plugin_t * lastfm_load (DB_functions_t *api) { deadbeef = api; @@ -317,50 +319,41 @@ fail: } static int -lfm_fetch_song_info (DB_playItem_t *song, const char **a, const char **t, const char **b, float *l, const char **n, const char **m) { +lfm_fetch_song_info (DB_playItem_t *song, char *a, char *t, char *b, float *l, char *n, char *m) { if (deadbeef->conf_get_int ("lastfm.prefer_album_artist", 0)) { - *a = deadbeef->pl_find_meta (song, "band"); - if (!(*a)) { - *a = deadbeef->pl_find_meta (song, "album artist"); - } - if (!(*a)) { - *a = deadbeef->pl_find_meta (song, "albumartist"); - } - if (!(*a)) { - *a = deadbeef->pl_find_meta (song, "artist"); + if (!deadbeef->pl_get_meta (song, "band", a, META_FIELD_SIZE)) { + if (!deadbeef->pl_get_meta (song, "album artist", a, META_FIELD_SIZE)) { + if (!deadbeef->pl_get_meta (song, "albumartist", a, META_FIELD_SIZE)) { + if (!deadbeef->pl_get_meta (song, "artist", a, META_FIELD_SIZE)) { + return -1; + } + } + } } } else { - *a = deadbeef->pl_find_meta (song, "artist"); - if (!(*a)) { - *a = deadbeef->pl_find_meta (song, "band"); - } - if (!(*a)) { - *a = deadbeef->pl_find_meta (song, "album artist"); - } - if (!(*a)) { - *a = deadbeef->pl_find_meta (song, "albumartist"); + if (!deadbeef->pl_get_meta (song, "artist", a, META_FIELD_SIZE)) { + if (!deadbeef->pl_get_meta (song, "band", a, META_FIELD_SIZE)) { + if (!deadbeef->pl_get_meta (song, "album artist", a, META_FIELD_SIZE)) { + if (!deadbeef->pl_get_meta (song, "albumartist", a, META_FIELD_SIZE)) { + return -1; + } + } + } } } - if (!*a) { - return -1; - } - *t = deadbeef->pl_find_meta (song, "title"); - if (!*t) { + if (!deadbeef->pl_get_meta (song, "title", t, META_FIELD_SIZE)) { return -1; } - *b = deadbeef->pl_find_meta (song, "album"); - if (!*b) { - *b = ""; + if (!deadbeef->pl_get_meta (song, "album", b, META_FIELD_SIZE)) { + *b = 0; } *l = deadbeef->pl_get_item_duration (song); - *n = deadbeef->pl_find_meta (song, "track"); - if (!*n) { - *n = ""; + if (!deadbeef->pl_get_meta (song, "track", n, META_FIELD_SIZE)) { + *n = 0; } - *m = deadbeef->pl_find_meta (song, "mbid"); - if (!*m) { - *m = ""; + if (!deadbeef->pl_get_meta (song, "mbid", m, META_FIELD_SIZE)) { + *m = 0; } return 0; } @@ -443,12 +436,12 @@ lfm_format_uri (int subm, DB_playItem_t *song, char *out, int outl, time_t start return -1; } int sz = outl; - const char *a; // artist - const char *t; // title - const char *b; // album + char a[META_FIELD_SIZE]; // artist + char t[META_FIELD_SIZE]; // title + char b[META_FIELD_SIZE]; // album float l; // duration - const char *n; // tracknum - const char *m; // muzicbrainz id + char n[META_FIELD_SIZE]; // tracknum + char m[META_FIELD_SIZE]; // muzicbrainz id char ka[6] = "a"; char kt[6] = "t"; @@ -466,7 +459,7 @@ lfm_format_uri (int subm, DB_playItem_t *song, char *out, int outl, time_t start strcpy (km+1, ka+1); } - if (lfm_fetch_song_info (song, &a, &t, &b, &l, &n, &m) == 0) { + if (lfm_fetch_song_info (song, a, t, b, &l, n, m) == 0) { // trace ("playtime: %f\nartist: %s\ntitle: %s\nalbum: %s\nduration: %f\ntracknum: %s\n---\n", song->playtime, a, t, b, l, n); } else { @@ -559,9 +552,8 @@ lastfm_songchanged (ddb_event_trackchange_t *ev, uintptr_t data) { #endif - if (!deadbeef->pl_find_meta (ev->from, "artist") - || !deadbeef->pl_find_meta (ev->from, "title") -// || !deadbeef->pl_find_meta (ev->from, "album") + if (!deadbeef->pl_meta_exists (ev->from, "artist") + || !deadbeef->pl_meta_exists (ev->from, "title") ) { trace ("lfm: not enough metadata for submission, artist=%s, title=%s, album=%s\n", deadbeef->pl_find_meta (ev->from, "artist"), deadbeef->pl_find_meta (ev->from, "title"), deadbeef->pl_find_meta (ev->from, "album")); return 0; @@ -876,11 +868,14 @@ lastfm_stop (void) { static int lfm_action_lookup (DB_plugin_action_t *action, DB_playItem_t *it) { - const char *artist = deadbeef->pl_find_meta (it, "artist"); - const char *title = deadbeef->pl_find_meta (it, "title"); - - if (!title || !artist) + char artist[META_FIELD_SIZE]; + if (!deadbeef->pl_get_meta (it, "artist", artist, sizeof (artist))) { + return 0; + } + char title[META_FIELD_SIZE]; + if (!deadbeef->pl_get_meta (it, "title", title, sizeof (title))) { return 0; + } char eartist [strlen (artist) * 3 + 1]; char etitle [strlen (title) * 3 + 1]; @@ -925,9 +920,10 @@ static DB_plugin_action_t lookup_action = { static DB_plugin_action_t * lfm_get_actions (DB_playItem_t *it) { + deadbeef->pl_lock (); if (!it || - !deadbeef->pl_find_meta (it, "artist") || - !deadbeef->pl_find_meta (it, "title")) + !deadbeef->pl_meta_exists (it, "artist") || + !deadbeef->pl_meta_exists (it, "title")) { love_action.flags |= DB_ACTION_DISABLED; lookup_action.flags |= DB_ACTION_DISABLED; @@ -937,6 +933,7 @@ lfm_get_actions (DB_playItem_t *it) love_action.flags &= ~DB_ACTION_DISABLED; lookup_action.flags &= ~DB_ACTION_DISABLED; } + deadbeef->pl_unlock (); return &lookup_action; } diff --git a/plugins/mpgmad/mpgmad.c b/plugins/mpgmad/mpgmad.c index 32f4022f..0e06bbeb 100644 --- a/plugins/mpgmad/mpgmad.c +++ b/plugins/mpgmad/mpgmad.c @@ -793,7 +793,9 @@ cmp3_init (DB_fileinfo_t *_info, DB_playItem_t *it) { mpgmad_info_t *info = (mpgmad_info_t *)_info; _info->plugin = &plugin; memset (&info->buffer, 0, sizeof (info->buffer)); + deadbeef->pl_lock (); info->buffer.file = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI")); + deadbeef->pl_unlock (); if (!info->buffer.file) { return -1; } @@ -1357,15 +1359,20 @@ cmp3_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) { deadbeef->plt_set_item_duration (plt, it, buffer.duration); deadbeef->fclose (fp); - const char *cuesheet = deadbeef->pl_find_meta (it, "cuesheet"); - if (cuesheet) { - DB_playItem_t *last = deadbeef->plt_insert_cue_from_buffer (plt, after, it, cuesheet, strlen (cuesheet), buffer.totalsamples-buffer.delay-buffer.padding, buffer.samplerate); - if (last) { - deadbeef->pl_item_unref (it); - deadbeef->pl_item_unref (last); - return last; + deadbeef->pl_lock (); + { + const char *cuesheet = deadbeef->pl_find_meta (it, "cuesheet"); + if (cuesheet) { + DB_playItem_t *last = deadbeef->plt_insert_cue_from_buffer (plt, after, it, cuesheet, strlen (cuesheet), buffer.totalsamples-buffer.delay-buffer.padding, buffer.samplerate); + deadbeef->pl_unlock (); + if (last) { + deadbeef->pl_item_unref (it); + deadbeef->pl_item_unref (last); + return last; + } } } + deadbeef->pl_unlock (); // FIXME! bad numsamples passed to cue @@ -1383,7 +1390,9 @@ cmp3_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) { int cmp3_read_metadata (DB_playItem_t *it) { + deadbeef->pl_lock (); DB_FILE *fp = deadbeef->fopen (deadbeef->pl_find_meta (it, ":URI")); + deadbeef->pl_unlock (); if (!fp) { return -1; } diff --git a/plugins/shellexec/shellexec.c b/plugins/shellexec/shellexec.c index b419a4c9..7d49c2d6 100644 --- a/plugins/shellexec/shellexec.c +++ b/plugins/shellexec/shellexec.c @@ -103,7 +103,9 @@ shx_callback (Shx_action_t *action, DB_playItem_t *it) static DB_plugin_action_t * shx_get_plugin_actions (DB_playItem_t *it) { + deadbeef->pl_lock (); int is_local = it ? deadbeef->is_local_file (deadbeef->pl_find_meta (it, ":URI")) : 1; + deadbeef->pl_unlock (); Shx_action_t *action; for (action = actions; action; action = (Shx_action_t *)action->parent.next) diff --git a/streamer.c b/streamer.c index 2a5d22bc..53993d9c 100644 --- a/streamer.c +++ b/streamer.c @@ -813,7 +813,9 @@ streamer_set_current (playItem_t *it) { pl_item_ref (i); int res = -1; while (i) { + pl_lock (); pl_replace_meta (it, "!URI", pl_find_meta_raw (i, ":URI")); + pl_unlock (); res = streamer_set_current (it); if (!res) { pl_item_unref (i); @@ -2244,6 +2246,7 @@ streamer_notify_order_changed (int prev_order, int new_order) { playItem_t *curr = playing_track; if (curr) { + pl_lock (); const char *alb = pl_find_meta_raw (curr, "album"); const char *art = pl_find_meta_raw (curr, "artist"); playItem_t *next = curr->prev[PL_MAIN]; @@ -2256,6 +2259,7 @@ streamer_notify_order_changed (int prev_order, int new_order) { break; } } + pl_unlock (); } streamer_unlock (); } -- cgit v1.2.3 From f81a65b6b502adb2f1d071d2f58a824944841bf3 Mon Sep 17 00:00:00 2001 From: waker Date: Fri, 18 May 2012 11:42:23 +0200 Subject: fixed plt_find_meta calls to use pl_lock --- deadbeef.h | 2 ++ pltmeta.c | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'deadbeef.h') diff --git a/deadbeef.h b/deadbeef.h index 6de9e9d0..8775bf6d 100644 --- a/deadbeef.h +++ b/deadbeef.h @@ -458,6 +458,8 @@ typedef struct { 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); + + // plt_find_meta must always be used in the pl_lock/unlock block 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); diff --git a/pltmeta.c b/pltmeta.c index 63c7279c..fac97b37 100644 --- a/pltmeta.c +++ b/pltmeta.c @@ -64,6 +64,7 @@ plt_add_meta (playlist_t *it, const char *key, const char *value) { void plt_append_meta (playlist_t *it, const char *key, const char *value) { + pl_lock (); const char *old = plt_find_meta (it, key); size_t newlen = strlen (value); if (!old) { @@ -85,6 +86,7 @@ plt_append_meta (playlist_t *it, const char *key, const char *value) { } if (len == newlen && !memcmp (str, value, len)) { + pl_unlock (); return; } @@ -95,6 +97,7 @@ plt_append_meta (playlist_t *it, const char *key, const char *value) { snprintf (out, sz, "%s\n%s", old, value); plt_replace_meta (it, key, out); } + pl_unlock (); } void @@ -170,14 +173,20 @@ plt_find_meta (playlist_t *it, const char *key) { int plt_find_meta_int (playlist_t *it, const char *key, int def) { + pl_lock (); const char *val = plt_find_meta (it, key); - return val ? atoi (val) : def; + int res = val ? atoi (val) : def; + pl_unlock (); + return res; } float plt_find_meta_float (playlist_t *it, const char *key, float def) { + pl_lock (); const char *val = plt_find_meta (it, key); - return val ? atof (val) : def; + float res = val ? atof (val) : def; + pl_unlock (); + return res; } DB_metaInfo_t * -- cgit v1.2.3 From 2b90261fad9288df60d4a215083eb16c7818102f Mon Sep 17 00:00:00 2001 From: waker Date: Wed, 30 May 2012 21:42:13 +0200 Subject: gtkui: run_dialog now supports specifying parent window --- deadbeef.h | 5 ++++- plugins/converter/convgui.c | 2 +- plugins/gtkui/gtkui.c | 3 ++- plugins/gtkui/pluginconf.c | 3 +++ 4 files changed, 10 insertions(+), 3 deletions(-) (limited to 'deadbeef.h') diff --git a/deadbeef.h b/deadbeef.h index 8775bf6d..6d797fe0 100644 --- a/deadbeef.h +++ b/deadbeef.h @@ -1129,9 +1129,12 @@ enum { typedef struct DB_gui_s { DB_plugin_t plugin; + // obsolete, don't use + int (*run_dialog_1) (ddb_dialog_t *dlg, uint32_t buttons, int (*callback)(int button, void *ctx), void *ctx); + // returns response code (ddb_button_*) // buttons is a bitset, e.g. (1<gui.run_dialog (&conf, 0, NULL, NULL); + gtkui_plugin->gui.run_dialog (toplevel, &conf, 0, NULL, NULL); current_dsp_context = NULL; } diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c index 4a1e82cf..894ff2e5 100644 --- a/plugins/gtkui/gtkui.c +++ b/plugins/gtkui/gtkui.c @@ -1464,6 +1464,7 @@ static ddb_gtkui_t plugin = { .gui.plugin.disconnect = gtkui_disconnect, .gui.plugin.configdialog = settings_dlg, .gui.plugin.message = gtkui_message, - .gui.run_dialog = gtkui_run_dialog_root, + .gui.run_dialog_1 = gtkui_run_dialog_root, + .gui.run_dialog = (int (*) (void *parentwindow, ddb_dialog_t *dlg, uint32_t buttons, int (*callback)(int button, void *ctx), void *ctx))gtkui_run_dialog, .get_mainwin = gtkui_get_mainwin, }; diff --git a/plugins/gtkui/pluginconf.c b/plugins/gtkui/pluginconf.c index 1f265372..cdd646cc 100644 --- a/plugins/gtkui/pluginconf.c +++ b/plugins/gtkui/pluginconf.c @@ -212,6 +212,9 @@ ddb_button_from_gtk_response (int response) { int gtkui_run_dialog (GtkWidget *parentwin, ddb_dialog_t *conf, uint32_t buttons, int (*callback)(int button, void *ctx), void *ctx) { + if (!parentwin) { + parentwin = mainwin; + } // create window char title[200]; snprintf (title, sizeof (title), _("Configure %s"), conf->title); -- cgit v1.2.3 From fef7f804693185729c4cf253c187c983afb71ae4 Mon Sep 17 00:00:00 2001 From: waker Date: Sat, 2 Jun 2012 16:08:57 +0200 Subject: plugin api version bumped to 1.4 for 0.5.5 release --- deadbeef.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'deadbeef.h') diff --git a/deadbeef.h b/deadbeef.h index 6d797fe0..51e39b10 100644 --- a/deadbeef.h +++ b/deadbeef.h @@ -79,7 +79,7 @@ extern "C" { // 0.1 -- deadbeef-0.2.0 #define DB_API_VERSION_MAJOR 1 -#define DB_API_VERSION_MINOR 3 +#define DB_API_VERSION_MINOR 4 #define DDB_PLUGIN_SET_API_VERSION\ .plugin.api_vmajor = DB_API_VERSION_MAJOR,\ -- cgit v1.2.3 From d23b8dd63bd2821dd1a4103504af143495dc0ae1 Mon Sep 17 00:00:00 2001 From: waker Date: Mon, 4 Jun 2012 08:50:26 +0200 Subject: fixed accidental API break caused by run_dialog --- deadbeef.h | 8 ++++---- plugins/converter/convgui.c | 3 ++- plugins/gtkui/gtkui.c | 3 +-- plugins/gtkui/pluginconf.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'deadbeef.h') diff --git a/deadbeef.h b/deadbeef.h index 51e39b10..a8f49039 100644 --- a/deadbeef.h +++ b/deadbeef.h @@ -1114,6 +1114,9 @@ typedef struct { const char *layout; void (*set_param) (const char *key, const char *value); void (*get_param) (const char *key, char *value, int len, const char *def); + + // parent was added in 1.4 API + void *parent; } ddb_dialog_t; enum { @@ -1129,12 +1132,9 @@ enum { typedef struct DB_gui_s { DB_plugin_t plugin; - // obsolete, don't use - int (*run_dialog_1) (ddb_dialog_t *dlg, uint32_t buttons, int (*callback)(int button, void *ctx), void *ctx); - // returns response code (ddb_button_*) // buttons is a bitset, e.g. (1<plugin->configdialog, .set_param = dsp_ctx_set_param, .get_param = dsp_ctx_get_param, + .parent = toplevel }; - gtkui_plugin->gui.run_dialog (toplevel, &conf, 0, NULL, NULL); + gtkui_plugin->gui.run_dialog (&conf, 0, NULL, NULL); current_dsp_context = NULL; } diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c index 7482ed49..4f7e5cac 100644 --- a/plugins/gtkui/gtkui.c +++ b/plugins/gtkui/gtkui.c @@ -1468,7 +1468,6 @@ static ddb_gtkui_t plugin = { .gui.plugin.disconnect = gtkui_disconnect, .gui.plugin.configdialog = settings_dlg, .gui.plugin.message = gtkui_message, - .gui.run_dialog_1 = gtkui_run_dialog_root, - .gui.run_dialog = (int (*) (void *parentwindow, ddb_dialog_t *dlg, uint32_t buttons, int (*callback)(int button, void *ctx), void *ctx))gtkui_run_dialog, + .gui.run_dialog = gtkui_run_dialog_root, .get_mainwin = gtkui_get_mainwin, }; diff --git a/plugins/gtkui/pluginconf.c b/plugins/gtkui/pluginconf.c index cdd646cc..33532f67 100644 --- a/plugins/gtkui/pluginconf.c +++ b/plugins/gtkui/pluginconf.c @@ -534,5 +534,5 @@ gtkui_run_dialog (GtkWidget *parentwin, ddb_dialog_t *conf, uint32_t buttons, in int gtkui_run_dialog_root (ddb_dialog_t *conf, uint32_t buttons, int (*callback)(int button, void *ctx), void *ctx) { - return gtkui_run_dialog (mainwin, conf, buttons, callback, ctx); + return gtkui_run_dialog (conf->parent ? conf->parent : mainwin, conf, buttons, callback, ctx); } -- cgit v1.2.3 From 7c72658a7f2352d167a9611caeaaa54aac170361 Mon Sep 17 00:00:00 2001 From: waker Date: Fri, 3 Aug 2012 21:22:27 +0200 Subject: added itunes tags type support to track flags --- deadbeef.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'deadbeef.h') diff --git a/deadbeef.h b/deadbeef.h index a8f49039..b2cc0446 100644 --- a/deadbeef.h +++ b/deadbeef.h @@ -116,8 +116,9 @@ enum { DDB_TAG_VORBISCOMMENTS = (1<<13), DDB_TAG_CUESHEET = (1<<14), DDB_TAG_ICY = (1<<15), + DDB_TAG_ITUNES = (1<<16), - DDB_TAG_MASK = 0x0000ff00 + DDB_TAG_MASK = 0x000fff00 }; // playlist item -- cgit v1.2.3 From 4fe3bbd274ffc5d479bb8a85aeb7e806adbfa4dd Mon Sep 17 00:00:00 2001 From: waker Date: Sun, 5 Aug 2012 14:02:26 +0200 Subject: removed DB_COLUMN_ID_MAX from the API header, it's unused and doesn't make sense --- deadbeef.h | 1 - 1 file changed, 1 deletion(-) (limited to 'deadbeef.h') diff --git a/deadbeef.h b/deadbeef.h index b2cc0446..c362a512 100644 --- a/deadbeef.h +++ b/deadbeef.h @@ -288,7 +288,6 @@ enum pl_column_t { DB_COLUMN_FILENUMBER = 0, DB_COLUMN_PLAYING = 1, DB_COLUMN_ALBUM_ART = 8, - DB_COLUMN_ID_MAX }; // replaygain constants -- cgit v1.2.3