Skip to content

Commit dc56360

Browse files
medialib: disable mutex locking when sorting medialib playlist; fix bugs/tests
1 parent 0f1ef90 commit dc56360

File tree

9 files changed

+212
-91
lines changed

9 files changed

+212
-91
lines changed

Tests/DDBTestInitializer.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "vfs.h"
1515
#include "plugins.h"
1616
#include "playmodes.h"
17+
#include "tf.h"
1718

1819
@implementation DDBTestInitializer
1920
- (instancetype)init {
@@ -23,6 +24,7 @@ - (instancetype)init {
2324

2425
ddb_logger_init ();
2526
conf_init ();
27+
tf_init();
2628
conf_enable_saving (0);
2729
streamer_playmodes_init();
2830
pl_init ();

include/deadbeef/deadbeef.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ extern "C" {
7373
// that there's a better replacement in the newer deadbeef versions.
7474

7575
// API version history:
76+
// 1.19 -- deadbeef-1.10.1
7677
// 1.18 -- deadbeef-1.10.0
7778
// 1.17 -- deadbeef-1.9.6
7879
// 1.16 -- deadbeef-1.9.4
@@ -104,7 +105,7 @@ extern "C" {
104105
// 0.1 -- deadbeef-0.2.0
105106

106107
#define DB_API_VERSION_MAJOR 1
107-
#define DB_API_VERSION_MINOR 18
108+
#define DB_API_VERSION_MINOR 19
108109

109110
#if defined(__clang__)
110111

@@ -141,6 +142,12 @@ extern "C" {
141142
#define DDB_API_LEVEL DB_API_VERSION_MINOR
142143
#endif
143144

145+
#if (DDB_WARN_DEPRECATED && DDB_API_LEVEL >= 19)
146+
#define DEPRECATED_119 DDB_DEPRECATED("since deadbeef API 1.19")
147+
#else
148+
#define DEPRECATED_119
149+
#endif
150+
144151
#if (DDB_WARN_DEPRECATED && DDB_API_LEVEL >= 18)
145152
#define DEPRECATED_118 DDB_DEPRECATED("since deadbeef API 1.18")
146153
#else
@@ -1797,6 +1804,11 @@ typedef struct {
17971804
/// Usually it should be called by UI code, when appropriate.
17981805
void (*plt_autosort)(ddb_playlist_t *plt);
17991806
#endif
1807+
1808+
#if (DDB_API_LEVEL >= 18)
1809+
// sort using title formatting v2, with more direct control over tf evaluation
1810+
void (*plt_sort_v3) (ddb_tf_context_t *tf_ctx, const char *tf_bytecode, int iter, int id, int order);
1811+
#endif
18001812
} DB_functions_t;
18011813

18021814
// NOTE: an item placement must be selected like this

plugins/medialib/medialibtree.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,18 @@ _create_tf_tree(medialib_source_t *source, ml_tree_item_t *root, int selected, c
232232
}
233233
*curr = 0;
234234

235-
deadbeef->plt_sort_v2(source->ml_playlist, PL_MAIN, -1, tf_sort, DDB_SORT_ASCENDING);
235+
ddb_tf_context_t ctx = {
236+
._size = sizeof (ddb_tf_context_t),
237+
.flags = DDB_TF_CONTEXT_NO_DYNAMIC | DDB_TF_CONTEXT_NO_MUTEX_LOCK,
238+
.plt = source->ml_playlist,
239+
.idx = -1,
240+
};
241+
242+
char *tf_bytecode = deadbeef->tf_compile(tf_sort);
243+
244+
deadbeef->plt_sort_v3(&ctx, tf_bytecode, PL_MAIN, -1, DDB_SORT_ASCENDING);
245+
246+
deadbeef->tf_free(tf_bytecode);
236247

237248
_create_sorted_tree(source->ml_playlist, root, selected, NULL, bcs, text_bcs, tfs_count, 0);
238249

src/plmeta.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@
3535
#define UNLOCK {pl_unlock();}
3636

3737
DB_metaInfo_t *
38-
pl_meta_for_key_with_override (playItem_t *it, const char *key) {
39-
pl_ensure_lock ();
38+
pl_meta_for_key_with_override_needs_mutex_lock (playItem_t *it, const char *key, int needs_mutex_lock) {
39+
if (needs_mutex_lock) {
40+
pl_ensure_lock ();
41+
}
4042
DB_metaInfo_t *m = it->meta;
4143

4244
// try to find an override
@@ -58,8 +60,15 @@ pl_meta_for_key_with_override (playItem_t *it, const char *key) {
5860
}
5961

6062
DB_metaInfo_t *
61-
pl_meta_for_cached_key (playItem_t *it, const char *key) {
62-
pl_ensure_lock ();
63+
pl_meta_for_key_with_override (playItem_t *it, const char *key) {
64+
return pl_meta_for_key_with_override_needs_mutex_lock(it, key, 1);
65+
}
66+
67+
DB_metaInfo_t *
68+
pl_meta_for_cached_key (playItem_t *it, const char *key, int needs_mutex_lock) {
69+
if (needs_mutex_lock) {
70+
pl_ensure_lock ();
71+
}
6372
DB_metaInfo_t *m = it->meta;
6473

6574
m = it->meta;

src/plmeta.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ DB_metaInfo_t *
7373
pl_meta_for_key_with_override (playItem_t *it, const char *key);
7474

7575
DB_metaInfo_t *
76-
pl_meta_for_cached_key (playItem_t *it, const char *key);
76+
pl_meta_for_key_with_override_needs_mutex_lock (playItem_t *it, const char *key, int needs_mutex_lock);
77+
78+
DB_metaInfo_t *
79+
pl_meta_for_cached_key (playItem_t *it, const char *key, int needs_mutex_lock);
7780

7881
int
7982
pl_get_meta_with_override (playItem_t *it, const char *key, char *val, size_t size);

src/plugins.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,8 @@ static DB_functions_t deadbeef_api = {
614614
.plt_save_to_buffer = (ssize_t (*) (ddb_playlist_t *plt, uint8_t **out_buffer))plt_save_to_buffer,
615615
.plug_register_for_async_deinit = _plug_register_for_async_deinit,
616616
.plt_autosort = (void (*)(ddb_playlist_t *plt))plt_autosort,
617+
618+
.plt_sort_v3 = plt_sort_v3,
617619
};
618620

619621
DB_functions_t *deadbeef = &deadbeef_api;

src/sort.c

Lines changed: 79 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@
3939
#define trace(fmt,...)
4040

4141
static void
42-
plt_sort_internal (playlist_t *playlist, int iter, int id, const char *format, int order, int version, int is_autosorting);
42+
plt_sort_internal (playlist_t *playlist, int iter, int id, ddb_tf_context_t *tf_context, const char *tf_bytecode, const char *format, int order, int version, int is_autosorting);
4343

4444
static void
45-
plt_sort_v2_internal (playlist_t *plt, int iter, int id, const char *format, int order, int is_autosorting) {
45+
plt_sort_v2_internal (playlist_t *plt, int iter, int id, ddb_tf_context_t *tf_context, const char *tf_bytecode, const char *format, int order, int is_autosorting) {
4646
ddb_undobuffer_t *undobuffer = ddb_undomanager_get_buffer (ddb_undomanager_shared ());
4747
if (plt->undo_enabled) {
4848
pl_lock ();
@@ -58,7 +58,7 @@ plt_sort_v2_internal (playlist_t *plt, int iter, int id, const char *format, int
5858
}
5959
}
6060

61-
plt_sort_internal (plt, iter, id, format, order, 1, is_autosorting);
61+
plt_sort_internal (plt, iter, id, tf_context, tf_bytecode, format, order, 1, is_autosorting);
6262

6363
if (plt->undo_enabled) {
6464
int count = plt->count[PL_MAIN];
@@ -77,13 +77,35 @@ plt_sort_v2_internal (playlist_t *plt, int iter, int id, const char *format, int
7777

7878
void
7979
plt_sort_v2 (playlist_t *plt, int iter, int id, const char *format, int order) {
80-
plt_sort_v2_internal(plt, iter, id, format, order, 0);
80+
plt_sort_v2_internal(plt, iter, id, NULL, NULL, format, order, 0);
81+
}
82+
83+
void
84+
plt_sort_v3 (ddb_tf_context_t *tf_ctx, const char *tf_bytecode, int iter, int id, int order) {
85+
playlist_t *plt = NULL;
86+
if (tf_ctx != NULL) {
87+
plt = (playlist_t *)tf_ctx->plt;
88+
}
89+
plt_sort_v2_internal(plt, iter, id, tf_ctx, tf_bytecode, NULL, order, 0);
8190
}
8291

8392
// sort for title formatting v1
8493
void
8594
plt_sort (playlist_t *playlist, int iter, int id, const char *format, int order) {
86-
plt_sort_internal (playlist, iter, id, format, order, 0, 0);
95+
ddb_tf_context_t ctx;
96+
ddb_tf_context_t *ctxptr = NULL;
97+
char *tf_bytecode = NULL;
98+
if (format != NULL) {
99+
tf_bytecode = tf_compile (format);
100+
ctx._size = sizeof (ctx);
101+
ctx.it = NULL;
102+
ctx.plt = (ddb_playlist_t *)playlist;
103+
ctx.idx = -1;
104+
ctx.id = id;
105+
ctxptr = &ctx;
106+
}
107+
108+
plt_sort_internal (playlist, iter, id, ctxptr, tf_bytecode, NULL, order, 0, 0);
87109
}
88110

89111
static int pl_sort_is_duration;
@@ -92,7 +114,7 @@ static int pl_sort_ascending;
92114
static int pl_sort_id;
93115
static int pl_sort_version; // 0: use pl_sort_format, 1: use pl_sort_tf_bytecode
94116
static const char *pl_sort_format;
95-
static char *pl_sort_tf_bytecode;
117+
static const char *pl_sort_tf_bytecode;
96118
static ddb_tf_context_t pl_sort_tf_ctx;
97119

98120
static int
@@ -230,47 +252,62 @@ plt_sort_random (playlist_t *playlist, int iter) {
230252
// version 0: title formatting v1
231253
// version 1: title formatting v2
232254
static void
233-
plt_sort_internal (playlist_t *playlist, int iter, int id, const char *format, int order, int version, int is_autosorting) {
234-
if (order == DDB_SORT_RANDOM) {
235-
if (!is_autosorting) {
236-
plt_replace_meta (playlist, "autosort_mode", "random");
237-
}
238-
plt_sort_random (playlist, iter);
239-
return;
240-
}
255+
plt_sort_internal (playlist_t *playlist, int iter, int id, ddb_tf_context_t *tf_context, const char *tf_bytecode, const char *format, int order, int version, int is_autosorting) {
241256
int ascending = order == DDB_SORT_DESCENDING ? 0 : 1;
242-
if (!is_autosorting)
243-
{
244-
plt_set_meta_int (playlist, "autosort_ascending", ascending);
245-
if (version != 0 && format != NULL) {
246-
plt_replace_meta (playlist, "autosort_mode", "tf");
247-
plt_replace_meta (playlist, "autosort_tf", format);
257+
258+
if (tf_bytecode == NULL) {
259+
if (order == DDB_SORT_RANDOM) {
260+
if (!is_autosorting) {
261+
plt_replace_meta (playlist, "autosort_mode", "random");
262+
}
263+
plt_sort_random (playlist, iter);
264+
return;
265+
}
266+
if (!is_autosorting)
267+
{
268+
plt_set_meta_int (playlist, "autosort_ascending", ascending);
269+
if (version != 0 && format != NULL) {
270+
plt_replace_meta (playlist, "autosort_mode", "tf");
271+
plt_replace_meta (playlist, "autosort_tf", format);
272+
}
248273
}
249-
}
250274

251-
if (format == NULL || id == DB_COLUMN_FILENUMBER || !playlist->head[iter] || !playlist->head[iter]->next[iter]) {
252-
return;
275+
if (format == NULL || id == DB_COLUMN_FILENUMBER || !playlist->head[iter] || !playlist->head[iter]->next[iter]) {
276+
return;
277+
}
253278
}
279+
254280
pl_lock ();
255281
struct timeval tm1;
256282
gettimeofday (&tm1, NULL);
257283
pl_sort_ascending = ascending;
258284
trace ("ascending: %d\n", ascending);
259285
pl_sort_id = id;
260286

287+
288+
char *free_tf_bytecode = NULL;
289+
261290
pl_sort_version = version;
262-
if (version == 0) {
263-
pl_sort_format = format;
264-
pl_sort_tf_bytecode = NULL;
291+
if (tf_bytecode == NULL) {
292+
if (version == 0) {
293+
pl_sort_format = format;
294+
pl_sort_tf_bytecode = NULL;
295+
}
296+
else {
297+
pl_sort_format = NULL;
298+
free_tf_bytecode = tf_compile (format);
299+
pl_sort_tf_bytecode = free_tf_bytecode;
300+
pl_sort_tf_ctx._size = sizeof (pl_sort_tf_ctx);
301+
pl_sort_tf_ctx.it = NULL;
302+
pl_sort_tf_ctx.plt = (ddb_playlist_t *)playlist;
303+
pl_sort_tf_ctx.idx = -1;
304+
pl_sort_tf_ctx.id = id;
305+
}
265306
}
266307
else {
267308
pl_sort_format = NULL;
268-
pl_sort_tf_bytecode = tf_compile (format);
269-
pl_sort_tf_ctx._size = sizeof (pl_sort_tf_ctx);
270-
pl_sort_tf_ctx.it = NULL;
271-
pl_sort_tf_ctx.plt = (ddb_playlist_t *)playlist;
272-
pl_sort_tf_ctx.idx = -1;
273-
pl_sort_tf_ctx.id = id;
309+
pl_sort_tf_bytecode = tf_bytecode;
310+
memcpy (&pl_sort_tf_ctx, tf_context, tf_context->_size);
274311
}
275312

276313
if (format && id == -1
@@ -340,7 +377,10 @@ plt_sort_internal (playlist_t *playlist, int iter, int id, const char *format, i
340377
}
341378

342379
if (version == 1) {
343-
tf_free (pl_sort_tf_bytecode);
380+
if (free_tf_bytecode != NULL) {
381+
tf_free (free_tf_bytecode);
382+
free_tf_bytecode = NULL;
383+
}
344384
pl_sort_tf_bytecode = NULL;
345385
memset (&pl_sort_tf_ctx, 0, sizeof (pl_sort_tf_ctx));
346386
}
@@ -366,7 +406,8 @@ sort_track_array (playlist_t *playlist, playItem_t **tracks, int num_tracks, con
366406

367407
pl_sort_version = 1;
368408
pl_sort_format = NULL;
369-
pl_sort_tf_bytecode = tf_compile (format);
409+
char *tf_bytecode = tf_compile (format);
410+
pl_sort_tf_bytecode = tf_bytecode;
370411
pl_sort_tf_ctx._size = sizeof (pl_sort_tf_ctx);
371412
pl_sort_tf_ctx.it = NULL;
372413
pl_sort_tf_ctx.plt = (ddb_playlist_t *)playlist;
@@ -394,7 +435,8 @@ sort_track_array (playlist_t *playlist, playItem_t **tracks, int num_tracks, con
394435
qsort (tracks, num_tracks, sizeof (playItem_t *), qsort_cmp_func);
395436
#endif
396437

397-
tf_free (pl_sort_tf_bytecode);
438+
tf_free (tf_bytecode);
439+
tf_bytecode = NULL;
398440
pl_sort_tf_bytecode = NULL;
399441
memset (&pl_sort_tf_ctx, 0, sizeof (pl_sort_tf_ctx));
400442

@@ -419,10 +461,10 @@ plt_autosort (playlist_t *plt) {
419461
if (!fmt) {
420462
return;
421463
}
422-
plt_sort_v2_internal (plt, PL_MAIN, -1, fmt, ascending ? DDB_SORT_ASCENDING : DDB_SORT_DESCENDING, 1);
464+
plt_sort_v2_internal (plt, PL_MAIN, -1, NULL, NULL, fmt, ascending ? DDB_SORT_ASCENDING : DDB_SORT_DESCENDING, 1);
423465
}
424466
else if (!strcmp (autosort_mode, "random")) {
425-
plt_sort_v2_internal (plt, PL_MAIN, -1, NULL, DDB_SORT_RANDOM, 1);
467+
plt_sort_v2_internal (plt, PL_MAIN, -1, NULL, NULL, NULL, DDB_SORT_RANDOM, 1);
426468
}
427469

428470
plt_save_config (plt);

src/sort.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ extern "C" {
3333
void
3434
plt_sort_v2 (playlist_t *plt, int iter, int id, const char *format, int order);
3535

36+
void
37+
plt_sort_v3 (ddb_tf_context_t *tf_ctx, const char *tf_bytecode, int iter, int id, int order);
38+
3639
void
3740
sort_track_array (playlist_t *playlist, playItem_t **tracks, int num_tracks, const char *format, int order);
3841

0 commit comments

Comments
 (0)