summaryrefslogtreecommitdiff
path: root/apps/tagtree.c
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2009-06-20 16:17:54 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2009-06-20 16:17:54 +0000
commit8e2bdcaab6857daed1174487e4262d1a4c5db9ab (patch)
tree66441264df232454d909ca94bdfdc9a915842e59 /apps/tagtree.c
parentd79d239382e53fc570cf49e8ea4b5150b42c906e (diff)
downloadrockbox-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.c68
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
99static struct tagcache_search tcs, tcs2;
100static bool sort_inverse; 102static bool sort_inverse;
101 103
102/* 104/*
@@ -642,6 +644,8 @@ static int compare(const void *p1, const void *p2)
642 644
643static void tagtree_buffer_event(struct mp3entry *id3) 645static 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
720bool tagtree_export(void) 724bool 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
1043static int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, 1049static 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
1550int tagtree_get_filename(struct tree_context* c, char *buf, int buflen) 1558int 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
1570static bool insert_all_playlist(struct tree_context *c, int position, bool queue) 1579static 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");