diff options
-rw-r--r-- | apps/onplay.c | 2 | ||||
-rw-r--r-- | apps/tagcache.c | 72 | ||||
-rw-r--r-- | apps/tagcache.h | 1 | ||||
-rw-r--r-- | apps/tagtree.c | 10 | ||||
-rw-r--r-- | firmware/common/dircache.c | 11 |
5 files changed, 74 insertions, 22 deletions
diff --git a/apps/onplay.c b/apps/onplay.c index 53058b3bc9..4558da72fe 100644 --- a/apps/onplay.c +++ b/apps/onplay.c | |||
@@ -850,7 +850,7 @@ int onplay(char* file, int attr, int from) | |||
850 | 850 | ||
851 | if (context == CONTEXT_WPS || | 851 | if (context == CONTEXT_WPS || |
852 | context == CONTEXT_TREE || | 852 | context == CONTEXT_TREE || |
853 | (context == CONTEXT_ID3DB)) | 853 | context == CONTEXT_ID3DB) |
854 | { | 854 | { |
855 | items[i].desc = ID2P(LANG_PLAYLIST); | 855 | items[i].desc = ID2P(LANG_PLAYLIST); |
856 | items[i].function = playlist_options; | 856 | items[i].function = playlist_options; |
diff --git a/apps/tagcache.c b/apps/tagcache.c index d6a8a798e3..1485ed8e51 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -43,9 +43,9 @@ | |||
43 | * | | | | +--x--------x---------+ | | 43 | * | | | | +--x--------x---------+ | |
44 | * | | | | | Temporary Commit DB | | | 44 | * | | | | | Temporary Commit DB | | |
45 | * | | | | +---------------------+ | | 45 | * | | | | +---------------------+ | |
46 | * +-x----x---x---x--+ | | 46 | * +-x----x-------x--+ | |
47 | * | TagCache RAM DB x==\(W) +-----------------+ | | 47 | * | TagCache RAM DB x==\(W) +-----------------+ | |
48 | * +-x----x---x---x--+ \===x | | | 48 | * +-----------------+ \===x | | |
49 | * | | | | (R) | Ram DB Loader x============x DirCache | 49 | * | | | | (R) | Ram DB Loader x============x DirCache |
50 | * +-x----x---x---x---+ /==x | | (optional) | 50 | * +-x----x---x---x---+ /==x | | (optional) |
51 | * | Tagcache Disk DB x==/ +-----------------+ | | 51 | * | Tagcache Disk DB x==/ +-----------------+ | |
@@ -191,6 +191,10 @@ static int total_entry_count = 0; | |||
191 | static int data_size = 0; | 191 | static int data_size = 0; |
192 | static int processed_dir_count; | 192 | static int processed_dir_count; |
193 | 193 | ||
194 | /* Thread safe locking */ | ||
195 | static volatile int write_lock; | ||
196 | static volatile int read_lock; | ||
197 | |||
194 | int tagcache_str_to_tag(const char *str) | 198 | int tagcache_str_to_tag(const char *str) |
195 | { | 199 | { |
196 | int i; | 200 | int i; |
@@ -516,6 +520,7 @@ static bool write_index(int masterfd, int idxid, struct index_entry *idx) | |||
516 | sizeof(struct index_entry)) | 520 | sizeof(struct index_entry)) |
517 | { | 521 | { |
518 | logf("write error #3"); | 522 | logf("write error #3"); |
523 | logf("idxid: %d", idxid); | ||
519 | return false; | 524 | return false; |
520 | } | 525 | } |
521 | 526 | ||
@@ -818,9 +823,12 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) | |||
818 | struct master_header master_hdr; | 823 | struct master_header master_hdr; |
819 | int i; | 824 | int i; |
820 | 825 | ||
821 | if (tcs->valid) | 826 | if (tcs->initialized) |
822 | tagcache_search_finish(tcs); | 827 | tagcache_search_finish(tcs); |
823 | 828 | ||
829 | while (read_lock) | ||
830 | sleep(1); | ||
831 | |||
824 | memset(tcs, 0, sizeof(struct tagcache_search)); | 832 | memset(tcs, 0, sizeof(struct tagcache_search)); |
825 | if (stat.commit_step > 0 || !stat.ready) | 833 | if (stat.commit_step > 0 || !stat.ready) |
826 | return false; | 834 | return false; |
@@ -830,7 +838,6 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) | |||
830 | tcs->seek_pos = 0; | 838 | tcs->seek_pos = 0; |
831 | tcs->seek_list_count = 0; | 839 | tcs->seek_list_count = 0; |
832 | tcs->filter_count = 0; | 840 | tcs->filter_count = 0; |
833 | tcs->valid = true; | ||
834 | tcs->masterfd = -1; | 841 | tcs->masterfd = -1; |
835 | 842 | ||
836 | for (i = 0; i < TAG_COUNT; i++) | 843 | for (i = 0; i < TAG_COUNT; i++) |
@@ -848,18 +855,28 @@ bool tagcache_search(struct tagcache_search *tcs, int tag) | |||
848 | #endif | 855 | #endif |
849 | { | 856 | { |
850 | if (tagcache_is_numeric_tag(tcs->type)) | 857 | if (tagcache_is_numeric_tag(tcs->type)) |
858 | { | ||
859 | tcs->valid = true; | ||
860 | tcs->initialized = true; | ||
851 | return true; | 861 | return true; |
862 | } | ||
852 | 863 | ||
853 | tcs->idxfd[tcs->type] = open_tag_fd(&tag_hdr, tcs->type, false); | 864 | tcs->idxfd[tcs->type] = open_tag_fd(&tag_hdr, tcs->type, false); |
854 | if (tcs->idxfd[tcs->type] < 0) | 865 | if (tcs->idxfd[tcs->type] < 0) |
855 | return false; | 866 | return false; |
856 | 867 | ||
857 | tcs->masterfd = open_master_fd(&master_hdr, false); | 868 | /* Always open as R/W so we can pass tcs to functions that modify data also |
869 | * without failing. */ | ||
870 | tcs->masterfd = open_master_fd(&master_hdr, true); | ||
858 | 871 | ||
859 | if (tcs->masterfd < 0) | 872 | if (tcs->masterfd < 0) |
860 | return false; | 873 | return false; |
861 | } | 874 | } |
862 | 875 | ||
876 | tcs->valid = true; | ||
877 | tcs->initialized = true; | ||
878 | write_lock++; | ||
879 | |||
863 | return true; | 880 | return true; |
864 | } | 881 | } |
865 | 882 | ||
@@ -1153,6 +1170,9 @@ void tagcache_search_finish(struct tagcache_search *tcs) | |||
1153 | { | 1170 | { |
1154 | int i; | 1171 | int i; |
1155 | 1172 | ||
1173 | if (!tcs->initialized) | ||
1174 | return; | ||
1175 | |||
1156 | if (tcs->masterfd >= 0) | 1176 | if (tcs->masterfd >= 0) |
1157 | { | 1177 | { |
1158 | close(tcs->masterfd); | 1178 | close(tcs->masterfd); |
@@ -1170,6 +1190,9 @@ void tagcache_search_finish(struct tagcache_search *tcs) | |||
1170 | 1190 | ||
1171 | tcs->ramsearch = false; | 1191 | tcs->ramsearch = false; |
1172 | tcs->valid = false; | 1192 | tcs->valid = false; |
1193 | tcs->initialized = 0; | ||
1194 | if (write_lock > 0) | ||
1195 | write_lock--; | ||
1173 | } | 1196 | } |
1174 | 1197 | ||
1175 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | 1198 | #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) |
@@ -2076,6 +2099,9 @@ static bool commit(void) | |||
2076 | 2099 | ||
2077 | logf("committing tagcache"); | 2100 | logf("committing tagcache"); |
2078 | 2101 | ||
2102 | while (write_lock) | ||
2103 | sleep(1); | ||
2104 | |||
2079 | tmpfd = open(TAGCACHE_FILE_TEMP, O_RDONLY); | 2105 | tmpfd = open(TAGCACHE_FILE_TEMP, O_RDONLY); |
2080 | if (tmpfd < 0) | 2106 | if (tmpfd < 0) |
2081 | { | 2107 | { |
@@ -2103,6 +2129,8 @@ static bool commit(void) | |||
2103 | return true; | 2129 | return true; |
2104 | } | 2130 | } |
2105 | 2131 | ||
2132 | read_lock++; | ||
2133 | |||
2106 | /* Try to steal every buffer we can :) */ | 2134 | /* Try to steal every buffer we can :) */ |
2107 | if (tempbuf_size == 0) | 2135 | if (tempbuf_size == 0) |
2108 | local_allocation = true; | 2136 | local_allocation = true; |
@@ -2138,6 +2166,7 @@ static bool commit(void) | |||
2138 | logf("delaying commit until next boot"); | 2166 | logf("delaying commit until next boot"); |
2139 | stat.commit_delayed = true; | 2167 | stat.commit_delayed = true; |
2140 | close(tmpfd); | 2168 | close(tmpfd); |
2169 | read_lock--; | ||
2141 | return false; | 2170 | return false; |
2142 | } | 2171 | } |
2143 | 2172 | ||
@@ -2169,6 +2198,7 @@ static bool commit(void) | |||
2169 | else | 2198 | else |
2170 | stat.commit_delayed = true; | 2199 | stat.commit_delayed = true; |
2171 | stat.commit_step = 0; | 2200 | stat.commit_step = 0; |
2201 | read_lock--; | ||
2172 | return false; | 2202 | return false; |
2173 | } | 2203 | } |
2174 | } | 2204 | } |
@@ -2178,8 +2208,11 @@ static bool commit(void) | |||
2178 | 2208 | ||
2179 | /* Update the master index headers. */ | 2209 | /* Update the master index headers. */ |
2180 | if ( (masterfd = open_master_fd(&tcmh, true)) < 0) | 2210 | if ( (masterfd = open_master_fd(&tcmh, true)) < 0) |
2211 | { | ||
2212 | read_lock--; | ||
2181 | return false; | 2213 | return false; |
2182 | 2214 | } | |
2215 | |||
2183 | tcmh.tch.entry_count += tch.entry_count; | 2216 | tcmh.tch.entry_count += tch.entry_count; |
2184 | tcmh.tch.datasize = sizeof(struct master_header) | 2217 | tcmh.tch.datasize = sizeof(struct master_header) |
2185 | + sizeof(struct index_entry) * tcmh.tch.entry_count | 2218 | + sizeof(struct index_entry) * tcmh.tch.entry_count |
@@ -2212,6 +2245,7 @@ static bool commit(void) | |||
2212 | #endif | 2245 | #endif |
2213 | 2246 | ||
2214 | queue_post(&tagcache_queue, Q_IMPORT_CHANGELOG, 0); | 2247 | queue_post(&tagcache_queue, Q_IMPORT_CHANGELOG, 0); |
2248 | read_lock--; | ||
2215 | 2249 | ||
2216 | return true; | 2250 | return true; |
2217 | } | 2251 | } |
@@ -2263,6 +2297,9 @@ long tagcache_increase_serial(void) | |||
2263 | if (!stat.ready) | 2297 | if (!stat.ready) |
2264 | return -2; | 2298 | return -2; |
2265 | 2299 | ||
2300 | while (read_lock) | ||
2301 | sleep(1); | ||
2302 | |||
2266 | if (!update_current_serial(current_serial + 1)) | 2303 | if (!update_current_serial(current_serial + 1)) |
2267 | return -1; | 2304 | return -1; |
2268 | 2305 | ||
@@ -2478,6 +2515,9 @@ bool tagcache_import_changelog(void) | |||
2478 | if (!stat.ready) | 2515 | if (!stat.ready) |
2479 | return false; | 2516 | return false; |
2480 | 2517 | ||
2518 | while (read_lock) | ||
2519 | sleep(1); | ||
2520 | |||
2481 | clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY); | 2521 | clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY); |
2482 | if (clfd < 0) | 2522 | if (clfd < 0) |
2483 | { | 2523 | { |
@@ -2491,6 +2531,8 @@ bool tagcache_import_changelog(void) | |||
2491 | return false; | 2531 | return false; |
2492 | } | 2532 | } |
2493 | 2533 | ||
2534 | write_lock++; | ||
2535 | |||
2494 | /* Fast readline */ | 2536 | /* Fast readline */ |
2495 | while ( 1 ) | 2537 | while ( 1 ) |
2496 | { | 2538 | { |
@@ -2530,6 +2572,8 @@ bool tagcache_import_changelog(void) | |||
2530 | close(clfd); | 2572 | close(clfd); |
2531 | close(masterfd); | 2573 | close(masterfd); |
2532 | 2574 | ||
2575 | write_lock--; | ||
2576 | |||
2533 | update_current_serial(current_serial); | 2577 | update_current_serial(current_serial); |
2534 | 2578 | ||
2535 | return true; | 2579 | return true; |
@@ -2724,12 +2768,11 @@ static bool delete_entry(long idx_id) | |||
2724 | #ifdef HAVE_TC_RAMCACHE | 2768 | #ifdef HAVE_TC_RAMCACHE |
2725 | static bool allocate_tagcache(void) | 2769 | static bool allocate_tagcache(void) |
2726 | { | 2770 | { |
2771 | struct master_header tcmh; | ||
2727 | int fd; | 2772 | int fd; |
2728 | 2773 | ||
2729 | /* Load the header. */ | 2774 | /* Load the header. */ |
2730 | hdr = (struct ramcache_header *)(((long)audiobuf & ~0x03) + 0x04); | 2775 | if ( (fd = open_master_fd(&tcmh, false)) < 0) |
2731 | memset(hdr, 0, sizeof(struct ramcache_header)); | ||
2732 | if ( (fd = open_master_fd(&hdr->h, false)) < 0) | ||
2733 | { | 2776 | { |
2734 | hdr = NULL; | 2777 | hdr = NULL; |
2735 | return false; | 2778 | return false; |
@@ -2737,17 +2780,17 @@ static bool allocate_tagcache(void) | |||
2737 | 2780 | ||
2738 | close(fd); | 2781 | close(fd); |
2739 | 2782 | ||
2740 | hdr->indices = (struct index_entry *)(hdr + 1); | ||
2741 | |||
2742 | /** | 2783 | /** |
2743 | * Now calculate the required cache size plus | 2784 | * Now calculate the required cache size plus |
2744 | * some extra space for alignment fixes. | 2785 | * some extra space for alignment fixes. |
2745 | */ | 2786 | */ |
2746 | stat.ramcache_allocated = hdr->h.tch.datasize + 128 + TAGCACHE_RESERVE + | 2787 | stat.ramcache_allocated = tcmh.tch.datasize + 128 + TAGCACHE_RESERVE + |
2747 | sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *); | 2788 | sizeof(struct ramcache_header) + TAG_COUNT*sizeof(void *); |
2789 | hdr = buffer_alloc(stat.ramcache_allocated + 128); | ||
2790 | memset(hdr, 0, sizeof(struct ramcache_header)); | ||
2791 | memcpy(&hdr->h, &tcmh, sizeof(struct master_header)); | ||
2792 | hdr->indices = (struct index_entry *)(hdr + 1); | ||
2748 | logf("tagcache: %d bytes allocated.", stat.ramcache_allocated); | 2793 | logf("tagcache: %d bytes allocated.", stat.ramcache_allocated); |
2749 | logf("at: 0x%04x", audiobuf); | ||
2750 | audiobuf += (long)((stat.ramcache_allocated & ~0x03) + 128); | ||
2751 | 2794 | ||
2752 | return true; | 2795 | return true; |
2753 | } | 2796 | } |
@@ -3361,6 +3404,7 @@ void tagcache_init(void) | |||
3361 | memset(&stat, 0, sizeof(struct tagcache_stat)); | 3404 | memset(&stat, 0, sizeof(struct tagcache_stat)); |
3362 | filenametag_fd = -1; | 3405 | filenametag_fd = -1; |
3363 | current_serial = 0; | 3406 | current_serial = 0; |
3407 | write_lock = read_lock = 0; | ||
3364 | 3408 | ||
3365 | queue_init(&tagcache_queue); | 3409 | queue_init(&tagcache_queue); |
3366 | create_thread(tagcache_thread, tagcache_stack, | 3410 | create_thread(tagcache_thread, tagcache_stack, |
diff --git a/apps/tagcache.h b/apps/tagcache.h index 1752d3ec45..450c21c26e 100644 --- a/apps/tagcache.h +++ b/apps/tagcache.h | |||
@@ -113,6 +113,7 @@ struct tagcache_search { | |||
113 | long position; | 113 | long position; |
114 | int entry_count; | 114 | int entry_count; |
115 | bool valid; | 115 | bool valid; |
116 | bool initialized; | ||
116 | 117 | ||
117 | /* Exported variables. */ | 118 | /* Exported variables. */ |
118 | bool ramsearch; | 119 | bool ramsearch; |
diff --git a/apps/tagtree.c b/apps/tagtree.c index b5ec10b04f..4061e9d8d7 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c | |||
@@ -379,11 +379,17 @@ static void tagtree_unbuffer_event(struct mp3entry *id3, bool last_track) | |||
379 | 379 | ||
380 | /* Do not gather data unless proper setting has been enabled. */ | 380 | /* Do not gather data unless proper setting has been enabled. */ |
381 | if (!global_settings.runtimedb) | 381 | if (!global_settings.runtimedb) |
382 | { | ||
383 | logf("runtimedb gathering not enabled"); | ||
382 | return; | 384 | return; |
385 | } | ||
383 | 386 | ||
384 | /* Don't process unplayed tracks. */ | 387 | /* Don't process unplayed tracks. */ |
385 | if (id3->elapsed == 0) | 388 | if (id3->elapsed == 0) |
389 | { | ||
390 | logf("not logging unplayed track"); | ||
386 | return; | 391 | return; |
392 | } | ||
387 | 393 | ||
388 | if (!tagcache_find_index(&tcs, id3->path)) | 394 | if (!tagcache_find_index(&tcs, id3->path)) |
389 | { | 395 | { |
@@ -399,7 +405,11 @@ static void tagtree_unbuffer_event(struct mp3entry *id3, bool last_track) | |||
399 | 405 | ||
400 | lastplayed = tagcache_increase_serial(); | 406 | lastplayed = tagcache_increase_serial(); |
401 | if (lastplayed < 0) | 407 | if (lastplayed < 0) |
408 | { | ||
409 | logf("incorrect tc serial:%d", lastplayed); | ||
410 | tagcache_search_finish(&tcs); | ||
402 | return; | 411 | return; |
412 | } | ||
403 | 413 | ||
404 | /* Ignore the last 15s (crossfade etc.) */ | 414 | /* Ignore the last 15s (crossfade etc.) */ |
405 | playtime += MIN(id3->length, id3->elapsed + 15 * 1000); | 415 | playtime += MIN(id3->length, id3->elapsed + 15 * 1000); |
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 7599c1b6c5..6167aa3933 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c | |||
@@ -623,14 +623,10 @@ int dircache_build(int last_size) | |||
623 | return 2; | 623 | return 2; |
624 | } | 624 | } |
625 | 625 | ||
626 | dircache_root = (struct dircache_entry *)(((long)audiobuf & ~0x03) + 0x04); | ||
627 | |||
628 | if (last_size > DIRCACHE_RESERVE && last_size < DIRCACHE_LIMIT ) | 626 | if (last_size > DIRCACHE_RESERVE && last_size < DIRCACHE_LIMIT ) |
629 | { | 627 | { |
630 | allocated_size = last_size + DIRCACHE_RESERVE; | 628 | allocated_size = last_size + DIRCACHE_RESERVE; |
631 | 629 | dircache_root = (struct dircache_entry *)buffer_alloc(allocated_size); | |
632 | /* We have to long align the audiobuf to keep the buffer access fast. */ | ||
633 | audiobuf += (long)((allocated_size & ~0x03) + 0x04); | ||
634 | thread_enabled = true; | 630 | thread_enabled = true; |
635 | 631 | ||
636 | /* Start a transparent rebuild. */ | 632 | /* Start a transparent rebuild. */ |
@@ -638,6 +634,8 @@ int dircache_build(int last_size) | |||
638 | return 3; | 634 | return 3; |
639 | } | 635 | } |
640 | 636 | ||
637 | dircache_root = (struct dircache_entry *)(((long)audiobuf & ~0x03) + 0x04); | ||
638 | |||
641 | /* Start a non-transparent rebuild. */ | 639 | /* Start a non-transparent rebuild. */ |
642 | return dircache_do_rebuild(); | 640 | return dircache_do_rebuild(); |
643 | } | 641 | } |
@@ -672,8 +670,7 @@ void dircache_init(void) | |||
672 | memset(opendirs, 0, sizeof(opendirs)); | 670 | memset(opendirs, 0, sizeof(opendirs)); |
673 | for (i = 0; i < MAX_OPEN_DIRS; i++) | 671 | for (i = 0; i < MAX_OPEN_DIRS; i++) |
674 | { | 672 | { |
675 | opendirs[i].secondary_entry.d_name = audiobuf; | 673 | opendirs[i].secondary_entry.d_name = buffer_alloc(MAX_PATH); |
676 | audiobuf += MAX_PATH; | ||
677 | } | 674 | } |
678 | 675 | ||
679 | queue_init(&dircache_queue); | 676 | queue_init(&dircache_queue); |