diff options
Diffstat (limited to 'apps/tagcache.c')
-rw-r--r-- | apps/tagcache.c | 72 |
1 files changed, 58 insertions, 14 deletions
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, |