diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2009-06-20 16:17:54 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2009-06-20 16:17:54 +0000 |
commit | 8e2bdcaab6857daed1174487e4262d1a4c5db9ab (patch) | |
tree | 66441264df232454d909ca94bdfdc9a915842e59 /apps/tagtree.c | |
parent | d79d239382e53fc570cf49e8ea4b5150b42c906e (diff) | |
download | rockbox-8e2bdcaab6857daed1174487e4262d1a4c5db9ab.tar.gz rockbox-8e2bdcaab6857daed1174487e4262d1a4c5db9ab.zip |
A bunch of stability fixes into tagcache engine and database browser. Mainly data retrieval problems, races, data corruption of sorted index files at the end with junk data, access to unitialized memory and so on. Should fix FS#8710 and may fix FS#8414.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21402 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/tagtree.c')
-rw-r--r-- | apps/tagtree.c | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/apps/tagtree.c b/apps/tagtree.c index 9635052ef3..691b2273de 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c | |||
@@ -23,6 +23,9 @@ | |||
23 | * Basic structure on this file was copied from dbtree.c and modified to | 23 | * Basic structure on this file was copied from dbtree.c and modified to |
24 | * support the tag cache interface. | 24 | * support the tag cache interface. |
25 | */ | 25 | */ |
26 | |||
27 | /* #define LOGF_ENABLE */ | ||
28 | |||
26 | #include <stdio.h> | 29 | #include <stdio.h> |
27 | #include <string.h> | 30 | #include <string.h> |
28 | #include <stdlib.h> | 31 | #include <stdlib.h> |
@@ -96,7 +99,6 @@ static long *uniqbuf; | |||
96 | #define MAX_TAGS 5 | 99 | #define MAX_TAGS 5 |
97 | #define MAX_MENU_ID_SIZE 32 | 100 | #define MAX_MENU_ID_SIZE 32 |
98 | 101 | ||
99 | static struct tagcache_search tcs, tcs2; | ||
100 | static bool sort_inverse; | 102 | static bool sort_inverse; |
101 | 103 | ||
102 | /* | 104 | /* |
@@ -642,6 +644,8 @@ static int compare(const void *p1, const void *p2) | |||
642 | 644 | ||
643 | static void tagtree_buffer_event(struct mp3entry *id3) | 645 | static void tagtree_buffer_event(struct mp3entry *id3) |
644 | { | 646 | { |
647 | struct tagcache_search tcs; | ||
648 | |||
645 | /* Do not gather data unless proper setting has been enabled. */ | 649 | /* Do not gather data unless proper setting has been enabled. */ |
646 | if (!global_settings.runtimedb) | 650 | if (!global_settings.runtimedb) |
647 | return; | 651 | return; |
@@ -719,6 +723,8 @@ static void tagtree_track_finish_event(struct mp3entry *id3) | |||
719 | 723 | ||
720 | bool tagtree_export(void) | 724 | bool tagtree_export(void) |
721 | { | 725 | { |
726 | struct tagcache_search tcs; | ||
727 | |||
722 | splash(0, str(LANG_CREATING)); | 728 | splash(0, str(LANG_CREATING)); |
723 | if (!tagcache_create_changelog(&tcs)) | 729 | if (!tagcache_create_changelog(&tcs)) |
724 | { | 730 | { |
@@ -1040,9 +1046,9 @@ static int format_str(struct tagcache_search *tcs, struct display_format *fmt, | |||
1040 | return 0; | 1046 | return 0; |
1041 | } | 1047 | } |
1042 | 1048 | ||
1043 | static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | 1049 | static int retrieve_entries(struct tree_context *c, int offset, bool init) |
1044 | int offset, bool init) | ||
1045 | { | 1050 | { |
1051 | struct tagcache_search tcs; | ||
1046 | struct tagentry *dptr = (struct tagentry *)c->dircache; | 1052 | struct tagentry *dptr = (struct tagentry *)c->dircache; |
1047 | struct display_format *fmt; | 1053 | struct display_format *fmt; |
1048 | int i; | 1054 | int i; |
@@ -1055,15 +1061,16 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1055 | int sort_limit; | 1061 | int sort_limit; |
1056 | int strip; | 1062 | int strip; |
1057 | 1063 | ||
1058 | if (init | 1064 | if (init && (tagcache_is_busy() |
1059 | #ifdef HAVE_TC_RAMCACHE | 1065 | #ifdef HAVE_TC_RAMCACHE |
1060 | && !tagcache_is_ramcache() | 1066 | || !tagcache_is_ramcache() |
1061 | #endif | 1067 | #endif |
1062 | ) | 1068 | ) ) |
1063 | { | 1069 | { |
1064 | /* Show search progress straight away if the disk needs to spin up, | 1070 | /* Show search progress straight away if the disk needs to spin up, |
1065 | otherwise show it after the normal 1/2 second delay */ | 1071 | otherwise show it after the normal 1/2 second delay */ |
1066 | show_search_progress( | 1072 | show_search_progress( |
1073 | !tagcache_is_busy() && | ||
1067 | #ifdef HAVE_DISK_STORAGE | 1074 | #ifdef HAVE_DISK_STORAGE |
1068 | storage_disk_is_active() | 1075 | storage_disk_is_active() |
1069 | #else | 1076 | #else |
@@ -1080,11 +1087,11 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1080 | else | 1087 | else |
1081 | tag = csi->tagorder[level]; | 1088 | tag = csi->tagorder[level]; |
1082 | 1089 | ||
1083 | if (!tagcache_search(tcs, tag)) | 1090 | if (!tagcache_search(&tcs, tag)) |
1084 | return -1; | 1091 | return -1; |
1085 | 1092 | ||
1086 | /* Prevent duplicate entries in the search list. */ | 1093 | /* Prevent duplicate entries in the search list. */ |
1087 | tagcache_search_set_uniqbuf(tcs, uniqbuf, UNIQBUF_SIZE); | 1094 | tagcache_search_set_uniqbuf(&tcs, uniqbuf, UNIQBUF_SIZE); |
1088 | 1095 | ||
1089 | if (level || csi->clause_count[0] || TAGCACHE_IS_NUMERIC(tag)) | 1096 | if (level || csi->clause_count[0] || TAGCACHE_IS_NUMERIC(tag)) |
1090 | sort = true; | 1097 | sort = true; |
@@ -1100,11 +1107,11 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1100 | cc.type = clause_is; | 1107 | cc.type = clause_is; |
1101 | cc.numeric = true; | 1108 | cc.numeric = true; |
1102 | cc.numeric_data = csi->result_seek[i]; | 1109 | cc.numeric_data = csi->result_seek[i]; |
1103 | tagcache_search_add_clause(tcs, &cc); | 1110 | tagcache_search_add_clause(&tcs, &cc); |
1104 | } | 1111 | } |
1105 | else | 1112 | else |
1106 | { | 1113 | { |
1107 | tagcache_search_add_filter(tcs, csi->tagorder[i], | 1114 | tagcache_search_add_filter(&tcs, csi->tagorder[i], |
1108 | csi->result_seek[i]); | 1115 | csi->result_seek[i]); |
1109 | } | 1116 | } |
1110 | } | 1117 | } |
@@ -1114,7 +1121,7 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1114 | int j; | 1121 | int j; |
1115 | 1122 | ||
1116 | for (j = 0; j < csi->clause_count[i]; j++) | 1123 | for (j = 0; j < csi->clause_count[i]; j++) |
1117 | tagcache_search_add_clause(tcs, csi->clause[i][j]); | 1124 | tagcache_search_add_clause(&tcs, csi->clause[i][j]); |
1118 | } | 1125 | } |
1119 | 1126 | ||
1120 | current_offset = offset; | 1127 | current_offset = offset; |
@@ -1164,7 +1171,7 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1164 | 1171 | ||
1165 | total_count += special_entry_count; | 1172 | total_count += special_entry_count; |
1166 | 1173 | ||
1167 | while (tagcache_get_next(tcs)) | 1174 | while (tagcache_get_next(&tcs)) |
1168 | { | 1175 | { |
1169 | if (total_count++ < offset) | 1176 | if (total_count++ < offset) |
1170 | continue; | 1177 | continue; |
@@ -1173,10 +1180,10 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1173 | if (tag == tag_title || tag == tag_filename) | 1180 | if (tag == tag_title || tag == tag_filename) |
1174 | { | 1181 | { |
1175 | dptr->newtable = PLAYTRACK; | 1182 | dptr->newtable = PLAYTRACK; |
1176 | dptr->extraseek = tcs->idx_id; | 1183 | dptr->extraseek = tcs.idx_id; |
1177 | } | 1184 | } |
1178 | else | 1185 | else |
1179 | dptr->extraseek = tcs->result_seek; | 1186 | dptr->extraseek = tcs.result_seek; |
1180 | 1187 | ||
1181 | fmt = NULL; | 1188 | fmt = NULL; |
1182 | /* Check the format */ | 1189 | /* Check the format */ |
@@ -1185,7 +1192,7 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1185 | if (formats[i]->group_id != csi->format_id[level]) | 1192 | if (formats[i]->group_id != csi->format_id[level]) |
1186 | continue; | 1193 | continue; |
1187 | 1194 | ||
1188 | if (tagcache_check_clauses(tcs, formats[i]->clause, | 1195 | if (tagcache_check_clauses(&tcs, formats[i]->clause, |
1189 | formats[i]->clause_count)) | 1196 | formats[i]->clause_count)) |
1190 | { | 1197 | { |
1191 | fmt = formats[i]; | 1198 | fmt = formats[i]; |
@@ -1193,15 +1200,16 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1193 | } | 1200 | } |
1194 | } | 1201 | } |
1195 | 1202 | ||
1196 | if (!tcs->ramresult || fmt) | 1203 | if (!tcs.ramresult || fmt) |
1197 | { | 1204 | { |
1198 | char buf[MAX_PATH]; | 1205 | char buf[MAX_PATH]; |
1199 | 1206 | ||
1200 | if (fmt) | 1207 | if (fmt) |
1201 | { | 1208 | { |
1202 | if (format_str(tcs, fmt, buf, sizeof buf) < 0) | 1209 | if (format_str(&tcs, fmt, buf, sizeof buf) < 0) |
1203 | { | 1210 | { |
1204 | logf("format_str() failed"); | 1211 | logf("format_str() failed"); |
1212 | tagcache_search_finish(&tcs); | ||
1205 | return 0; | 1213 | return 0; |
1206 | } | 1214 | } |
1207 | } | 1215 | } |
@@ -1210,7 +1218,7 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1210 | if (fmt) | 1218 | if (fmt) |
1211 | namebufused += strlen(buf)+1; | 1219 | namebufused += strlen(buf)+1; |
1212 | else | 1220 | else |
1213 | namebufused += tcs->result_len; | 1221 | namebufused += tcs.result_len; |
1214 | 1222 | ||
1215 | if (namebufused >= c->name_buffer_size) | 1223 | if (namebufused >= c->name_buffer_size) |
1216 | { | 1224 | { |
@@ -1222,10 +1230,10 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1222 | if (fmt) | 1230 | if (fmt) |
1223 | strcpy(dptr->name, buf); | 1231 | strcpy(dptr->name, buf); |
1224 | else | 1232 | else |
1225 | strcpy(dptr->name, tcs->result); | 1233 | strcpy(dptr->name, tcs.result); |
1226 | } | 1234 | } |
1227 | else | 1235 | else |
1228 | dptr->name = tcs->result; | 1236 | dptr->name = tcs.result; |
1229 | 1237 | ||
1230 | dptr++; | 1238 | dptr++; |
1231 | current_entry_count++; | 1239 | current_entry_count++; |
@@ -1238,11 +1246,11 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1238 | break ; | 1246 | break ; |
1239 | } | 1247 | } |
1240 | 1248 | ||
1241 | if (init && !tcs->ramsearch) | 1249 | if (init && !tcs.ramsearch) |
1242 | { | 1250 | { |
1243 | if (!show_search_progress(false, total_count)) | 1251 | if (!show_search_progress(false, total_count)) |
1244 | { | 1252 | { |
1245 | tagcache_search_finish(tcs); | 1253 | tagcache_search_finish(&tcs); |
1246 | return current_entry_count; | 1254 | return current_entry_count; |
1247 | } | 1255 | } |
1248 | } | 1256 | } |
@@ -1255,13 +1263,13 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1255 | 1263 | ||
1256 | if (!init) | 1264 | if (!init) |
1257 | { | 1265 | { |
1258 | tagcache_search_finish(tcs); | 1266 | tagcache_search_finish(&tcs); |
1259 | return current_entry_count; | 1267 | return current_entry_count; |
1260 | } | 1268 | } |
1261 | 1269 | ||
1262 | while (tagcache_get_next(tcs)) | 1270 | while (tagcache_get_next(&tcs)) |
1263 | { | 1271 | { |
1264 | if (!tcs->ramsearch) | 1272 | if (!tcs.ramsearch) |
1265 | { | 1273 | { |
1266 | if (!show_search_progress(false, total_count)) | 1274 | if (!show_search_progress(false, total_count)) |
1267 | break; | 1275 | break; |
@@ -1269,7 +1277,7 @@ static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, | |||
1269 | total_count++; | 1277 | total_count++; |
1270 | } | 1278 | } |
1271 | 1279 | ||
1272 | tagcache_search_finish(tcs); | 1280 | tagcache_search_finish(&tcs); |
1273 | 1281 | ||
1274 | if (!sort && (sort_inverse || sort_limit)) | 1282 | if (!sort && (sort_inverse || sort_limit)) |
1275 | { | 1283 | { |
@@ -1363,7 +1371,7 @@ int tagtree_load(struct tree_context* c) | |||
1363 | case NAVIBROWSE: | 1371 | case NAVIBROWSE: |
1364 | logf("navibrowse..."); | 1372 | logf("navibrowse..."); |
1365 | cpu_boost(true); | 1373 | cpu_boost(true); |
1366 | count = retrieve_entries(c, &tcs, 0, true); | 1374 | count = retrieve_entries(c, 0, true); |
1367 | cpu_boost(false); | 1375 | cpu_boost(false); |
1368 | break; | 1376 | break; |
1369 | 1377 | ||
@@ -1549,6 +1557,7 @@ void tagtree_exit(struct tree_context* c) | |||
1549 | 1557 | ||
1550 | int tagtree_get_filename(struct tree_context* c, char *buf, int buflen) | 1558 | int tagtree_get_filename(struct tree_context* c, char *buf, int buflen) |
1551 | { | 1559 | { |
1560 | struct tagcache_search tcs; | ||
1552 | struct tagentry *entry; | 1561 | struct tagentry *entry; |
1553 | 1562 | ||
1554 | entry = tagtree_get_entry(c, c->selected_item); | 1563 | entry = tagtree_get_entry(c, c->selected_item); |
@@ -1569,6 +1578,7 @@ int tagtree_get_filename(struct tree_context* c, char *buf, int buflen) | |||
1569 | 1578 | ||
1570 | static bool insert_all_playlist(struct tree_context *c, int position, bool queue) | 1579 | static bool insert_all_playlist(struct tree_context *c, int position, bool queue) |
1571 | { | 1580 | { |
1581 | struct tagcache_search tcs; | ||
1572 | int i; | 1582 | int i; |
1573 | char buf[MAX_PATH]; | 1583 | char buf[MAX_PATH]; |
1574 | int from, to, direction; | 1584 | int from, to, direction; |
@@ -1639,7 +1649,7 @@ bool tagtree_insert_selection_playlist(int position, bool queue) | |||
1639 | int dirlevel = tc->dirlevel; | 1649 | int dirlevel = tc->dirlevel; |
1640 | 1650 | ||
1641 | /* We need to set the table to allsubentries. */ | 1651 | /* We need to set the table to allsubentries. */ |
1642 | show_search_progress(true, 0); | 1652 | show_search_progress(!tagcache_is_busy(), 0); |
1643 | 1653 | ||
1644 | dptr = tagtree_get_entry(tc, tc->selected_item); | 1654 | dptr = tagtree_get_entry(tc, tc->selected_item); |
1645 | 1655 | ||
@@ -1732,7 +1742,7 @@ struct tagentry* tagtree_get_entry(struct tree_context *c, int id) | |||
1732 | if (realid >= current_entry_count || realid < 0) | 1742 | if (realid >= current_entry_count || realid < 0) |
1733 | { | 1743 | { |
1734 | cpu_boost(true); | 1744 | cpu_boost(true); |
1735 | if (retrieve_entries(c, &tcs2, MAX(0, id - (current_entry_count / 2)), | 1745 | if (retrieve_entries(c, MAX(0, id - (current_entry_count / 2)), |
1736 | false) < 0) | 1746 | false) < 0) |
1737 | { | 1747 | { |
1738 | logf("retrieve failed"); | 1748 | logf("retrieve failed"); |