summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/gui/icon.c8
-rw-r--r--apps/gui/skin_engine/skin_backdrops.c14
-rw-r--r--apps/gui/skin_engine/skin_parser.c16
-rw-r--r--apps/tagcache.c13
-rw-r--r--apps/tagtree.c66
-rw-r--r--apps/tree.c15
-rw-r--r--apps/tree.h13
7 files changed, 55 insertions, 90 deletions
diff --git a/apps/gui/icon.c b/apps/gui/icon.c
index 9fe7090f4a..e78aa6841c 100644
--- a/apps/gui/icon.c
+++ b/apps/gui/icon.c
@@ -63,7 +63,6 @@ static struct iconset {
63 struct bitmap bmp; 63 struct bitmap bmp;
64 bool loaded; 64 bool loaded;
65 int handle; 65 int handle;
66 int handle_locked;
67} iconsets[Iconset_Count][NB_SCREENS]; 66} iconsets[Iconset_Count][NB_SCREENS];
68 67
69#define ICON_HEIGHT(screen) (!iconsets[Iconset_user][screen].loaded ? \ 68#define ICON_HEIGHT(screen) (!iconsets[Iconset_user][screen].loaded ? \
@@ -160,8 +159,6 @@ static int buflib_move_callback(int handle, void* current, void* new)
160 struct iconset *set = &iconsets[i][j]; 159 struct iconset *set = &iconsets[i][j];
161 if (set->bmp.data == current) 160 if (set->bmp.data == current)
162 { 161 {
163 if (set->handle_locked > 0)
164 return BUFLIB_CB_CANNOT_MOVE;
165 set->bmp.data = new; 162 set->bmp.data = new;
166 return BUFLIB_CB_OK; 163 return BUFLIB_CB_OK;
167 } 164 }
@@ -201,11 +198,10 @@ static void load_icons(const char* filename, enum Iconset iconset,
201 goto finished; 198 goto finished;
202 } 199 }
203 lseek(fd, 0, SEEK_SET); 200 lseek(fd, 0, SEEK_SET);
201 core_pin(ic->handle);
204 ic->bmp.data = core_get_data(ic->handle); 202 ic->bmp.data = core_get_data(ic->handle);
205
206 ic->handle_locked = 1;
207 size_read = read_bmp_fd(fd, &ic->bmp, buf_size, bmpformat, NULL); 203 size_read = read_bmp_fd(fd, &ic->bmp, buf_size, bmpformat, NULL);
208 ic->handle_locked = 0; 204 core_unpin(ic->handle);
209 205
210 if (size_read < 0) 206 if (size_read < 0)
211 { 207 {
diff --git a/apps/gui/skin_engine/skin_backdrops.c b/apps/gui/skin_engine/skin_backdrops.c
index 1def0812da..215667d585 100644
--- a/apps/gui/skin_engine/skin_backdrops.c
+++ b/apps/gui/skin_engine/skin_backdrops.c
@@ -41,7 +41,6 @@ static struct skin_backdrop {
41} backdrops[NB_BDROPS]; 41} backdrops[NB_BDROPS];
42 42
43#define NB_BDROPS SKINNABLE_SCREENS_COUNT*NB_SCREENS 43#define NB_BDROPS SKINNABLE_SCREENS_COUNT*NB_SCREENS
44static int handle_being_loaded;
45static int current_lcd_backdrop[NB_SCREENS]; 44static int current_lcd_backdrop[NB_SCREENS];
46 45
47bool skin_backdrop_get_debug(int index, char **path, int *ref_count, size_t *size) 46bool skin_backdrop_get_debug(int index, char **path, int *ref_count, size_t *size)
@@ -65,8 +64,8 @@ bool skin_backdrop_get_debug(int index, char **path, int *ref_count, size_t *siz
65 64
66static int buflib_move_callback(int handle, void* current, void* new) 65static int buflib_move_callback(int handle, void* current, void* new)
67{ 66{
68 if (handle == handle_being_loaded) 67 (void)handle;
69 return BUFLIB_CB_CANNOT_MOVE; 68
70 for (int i=0; i<NB_BDROPS; i++) 69 for (int i=0; i<NB_BDROPS; i++)
71 { 70 {
72 if (backdrops[i].buffer == current) 71 if (backdrops[i].buffer == current)
@@ -96,7 +95,6 @@ bool skin_backdrop_init(void)
96 } 95 }
97 FOR_NB_SCREENS(i) 96 FOR_NB_SCREENS(i)
98 current_lcd_backdrop[i] = -1; 97 current_lcd_backdrop[i] = -1;
99 handle_being_loaded = -1;
100 first_go = false; 98 first_go = false;
101 } 99 }
102 return go_status; 100 return go_status;
@@ -182,16 +180,16 @@ bool skin_backdrops_preload(void)
182 backdrops[i].buffer = core_get_data(backdrops[i].buflib_handle); 180 backdrops[i].buffer = core_get_data(backdrops[i].buflib_handle);
183 if (strcmp(filename, BACKDROP_BUFFERNAME)) 181 if (strcmp(filename, BACKDROP_BUFFERNAME))
184 { 182 {
185 handle_being_loaded = backdrops[i].buflib_handle; 183 core_pin(backdrops[i].buflib_handle);
186 backdrops[i].loaded = 184 backdrops[i].loaded =
187 screens[screen].backdrop_load(filename, backdrops[i].buffer); 185 screens[screen].backdrop_load(filename, backdrops[i].buffer);
186 core_unpin(backdrops[i].buflib_handle);
188 if (!backdrops[i].loaded) 187 if (!backdrops[i].loaded)
189 { 188 {
190 core_free(backdrops[i].buflib_handle); 189 core_free(backdrops[i].buflib_handle);
191 backdrops[i].buflib_handle = -1; 190 backdrops[i].buflib_handle = -1;
192 retval = false; 191 retval = false;
193 } 192 }
194 handle_being_loaded = -1;
195 } 193 }
196 else 194 else
197 backdrops[i].loaded = true; 195 backdrops[i].loaded = true;
@@ -295,12 +293,12 @@ void skin_backdrop_load_setting(void)
295 return; 293 return;
296 } 294 }
297 bool loaded; 295 bool loaded;
296 core_pin(backdrops[i].buflib_handle);
298 backdrops[i].buffer = core_get_data(backdrops[i].buflib_handle); 297 backdrops[i].buffer = core_get_data(backdrops[i].buflib_handle);
299 handle_being_loaded = backdrops[i].buflib_handle;
300 loaded = screens[SCREEN_MAIN].backdrop_load( 298 loaded = screens[SCREEN_MAIN].backdrop_load(
301 global_settings.backdrop_file, 299 global_settings.backdrop_file,
302 backdrops[i].buffer); 300 backdrops[i].buffer);
303 handle_being_loaded = -1; 301 core_unpin(backdrops[i].buflib_handle);
304 backdrops[i].name[2] = loaded ? '.' : '\0'; 302 backdrops[i].name[2] = loaded ? '.' : '\0';
305 backdrops[i].loaded = loaded; 303 backdrops[i].loaded = loaded;
306 return; 304 return;
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 047c4735a0..2eef2af7c0 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -1870,13 +1870,11 @@ static void skin_data_reset(struct wps_data *wps_data)
1870} 1870}
1871 1871
1872#ifndef __PCTOOL__ 1872#ifndef __PCTOOL__
1873static int currently_loading_handle = -1;
1874static int buflib_move_callback(int handle, void* current, void* new) 1873static int buflib_move_callback(int handle, void* current, void* new)
1875{ 1874{
1875 (void)handle;
1876 (void)current; 1876 (void)current;
1877 (void)new; 1877 (void)new;
1878 if (handle == currently_loading_handle)
1879 return BUFLIB_CB_CANNOT_MOVE;
1880 /* Any active skins may be scrolling - which means using viewports which 1878 /* Any active skins may be scrolling - which means using viewports which
1881 * will be moved after this callback returns. This is a hammer to make that 1879 * will be moved after this callback returns. This is a hammer to make that
1882 * safe. TODO: use a screwdriver instead. 1880 * safe. TODO: use a screwdriver instead.
@@ -1890,14 +1888,6 @@ static int buflib_move_callback(int handle, void* current, void* new)
1890 return BUFLIB_CB_OK; 1888 return BUFLIB_CB_OK;
1891} 1889}
1892static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL}; 1890static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL};
1893static void lock_handle(int handle)
1894{
1895 currently_loading_handle = handle;
1896}
1897static void unlock_handle(void)
1898{
1899 currently_loading_handle = -1;
1900}
1901#endif 1891#endif
1902 1892
1903static int load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir) 1893static int load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir)
@@ -1944,12 +1934,12 @@ static int load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char*
1944 _stats->buflib_handles++; 1934 _stats->buflib_handles++;
1945 _stats->images_size += buf_size; 1935 _stats->images_size += buf_size;
1946 lseek(fd, 0, SEEK_SET); 1936 lseek(fd, 0, SEEK_SET);
1947 lock_handle(handle); 1937 core_pin(handle);
1948 bitmap->data = core_get_data(handle); 1938 bitmap->data = core_get_data(handle);
1949 int ret = read_bmp_fd(fd, bitmap, buf_size, format, NULL); 1939 int ret = read_bmp_fd(fd, bitmap, buf_size, format, NULL);
1950 bitmap->data = NULL; /* do this to force a crash later if the 1940 bitmap->data = NULL; /* do this to force a crash later if the
1951 caller doesnt call core_get_data() */ 1941 caller doesnt call core_get_data() */
1952 unlock_handle(); 1942 core_unpin(handle);
1953 close(fd); 1943 close(fd);
1954 if (ret > 0) 1944 if (ret > 0)
1955 { 1945 {
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 8db1569379..b6c86d7ddb 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -277,17 +277,16 @@ static struct tcramcache
277{ 277{
278 struct ramcache_header *hdr; /* allocated ramcache_header */ 278 struct ramcache_header *hdr; /* allocated ramcache_header */
279 int handle; /* buffer handle */ 279 int handle; /* buffer handle */
280 int move_lock;
281} tcramcache; 280} tcramcache;
282 281
283static inline void tcrc_buffer_lock(void) 282static inline void tcrc_buffer_lock(void)
284{ 283{
285 tcramcache.move_lock++; 284 core_pin(tcramcache.handle);
286} 285}
287 286
288static inline void tcrc_buffer_unlock(void) 287static inline void tcrc_buffer_unlock(void)
289{ 288{
290 tcramcache.move_lock--; 289 core_unpin(tcramcache.handle);
291} 290}
292 291
293#else /* ndef HAVE_TC_RAMCACHE */ 292#else /* ndef HAVE_TC_RAMCACHE */
@@ -3861,10 +3860,9 @@ static bool delete_entry(long idx_id)
3861 struct tagfile_entry *tfe; 3860 struct tagfile_entry *tfe;
3862 int32_t *seek = &tcramcache.hdr->indices[idx_id].tag_seek[tag]; 3861 int32_t *seek = &tcramcache.hdr->indices[idx_id].tag_seek[tag];
3863 3862
3863 /* crc_32 is assumed not to yield (why would it...?) */
3864 tfe = (struct tagfile_entry *)&tcramcache.hdr->tags[tag][*seek]; 3864 tfe = (struct tagfile_entry *)&tcramcache.hdr->tags[tag][*seek];
3865 tcrc_buffer_lock(); /* protect tfe and seek if crc_32() yield()s */
3866 *seek = crc_32(tfe->tag_data, strlen(tfe->tag_data), 0xffffffff); 3865 *seek = crc_32(tfe->tag_data, strlen(tfe->tag_data), 0xffffffff);
3867 tcrc_buffer_unlock();
3868 myidx.tag_seek[tag] = *seek; 3866 myidx.tag_seek[tag] = *seek;
3869 } 3867 }
3870 else 3868 else
@@ -4005,9 +4003,6 @@ static void fix_ramcache(void* old_addr, void* new_addr)
4005static int move_cb(int handle, void* current, void* new) 4003static int move_cb(int handle, void* current, void* new)
4006{ 4004{
4007 (void)handle; 4005 (void)handle;
4008 if (tcramcache.move_lock > 0)
4009 return BUFLIB_CB_CANNOT_MOVE;
4010
4011 fix_ramcache(current, new); 4006 fix_ramcache(current, new);
4012 tcramcache.hdr = new; 4007 tcramcache.hdr = new;
4013 return BUFLIB_CB_OK; 4008 return BUFLIB_CB_OK;
@@ -4092,8 +4087,8 @@ static bool tagcache_dumpload(void)
4092 return false; 4087 return false;
4093 } 4088 }
4094 4089
4095 tcrc_buffer_lock();
4096 tcramcache.handle = handle; 4090 tcramcache.handle = handle;
4091 tcrc_buffer_lock();
4097 tcramcache.hdr = core_get_data(handle); 4092 tcramcache.hdr = core_get_data(handle);
4098 rc = read(fd, tcramcache.hdr, shdr.tc_stat.ramcache_allocated); 4093 rc = read(fd, tcramcache.hdr, shdr.tc_stat.ramcache_allocated);
4099 tcrc_buffer_unlock(); 4094 tcrc_buffer_unlock();
diff --git a/apps/tagtree.c b/apps/tagtree.c
index 39bc0ab37c..2ebab7949c 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -192,7 +192,7 @@ static int current_entry_count;
192static struct tree_context *tc; 192static struct tree_context *tc;
193 193
194/* a few memory alloc helper */ 194/* a few memory alloc helper */
195static int tagtree_handle, lock_count; 195static int tagtree_handle;
196static size_t tagtree_bufsize, tagtree_buf_used; 196static size_t tagtree_bufsize, tagtree_buf_used;
197 197
198#define UPDATE(x, y) { x = (typeof(x))((char*)(x) + (y)); } 198#define UPDATE(x, y) { x = (typeof(x))((char*)(x) + (y)); }
@@ -201,9 +201,6 @@ static int move_callback(int handle, void* current, void* new)
201 (void)handle; (void)current; (void)new; 201 (void)handle; (void)current; (void)new;
202 ptrdiff_t diff = new - current; 202 ptrdiff_t diff = new - current;
203 203
204 if (lock_count > 0)
205 return BUFLIB_CB_CANNOT_MOVE;
206
207 if (menu) 204 if (menu)
208 UPDATE(menu, diff); 205 UPDATE(menu, diff);
209 206
@@ -251,16 +248,6 @@ static int move_callback(int handle, void* current, void* new)
251} 248}
252#undef UPDATE 249#undef UPDATE
253 250
254static inline void tagtree_lock(void)
255{
256 lock_count++;
257}
258
259static inline void tagtree_unlock(void)
260{
261 lock_count--;
262}
263
264static struct buflib_callbacks ops = { 251static struct buflib_callbacks ops = {
265 .move_callback = move_callback, 252 .move_callback = move_callback,
266 .shrink_callback = NULL, 253 .shrink_callback = NULL,
@@ -623,7 +610,7 @@ static int add_format(const char *buf)
623 int clause_count = 0; 610 int clause_count = 0;
624 strp++; 611 strp++;
625 612
626 tagtree_lock(); 613 core_pin(tagtree_handle);
627 while (1) 614 while (1)
628 { 615 {
629 struct tagcache_search_clause *new_clause; 616 struct tagcache_search_clause *new_clause;
@@ -646,7 +633,7 @@ static int add_format(const char *buf)
646 633
647 clause_count++; 634 clause_count++;
648 } 635 }
649 tagtree_unlock(); 636 core_unpin(tagtree_handle);
650 637
651 formats[format_count]->clause_count = clause_count; 638 formats[format_count]->clause_count = clause_count;
652 } 639 }
@@ -719,9 +706,9 @@ static int get_condition(struct search_instruction *inst)
719 } 706 }
720 else 707 else
721 { 708 {
722 tagtree_lock(); 709 core_pin(tagtree_handle);
723 bool ret = read_clause(new_clause); 710 bool ret = read_clause(new_clause);
724 tagtree_unlock(); 711 core_unpin(tagtree_handle);
725 if (!ret) 712 if (!ret)
726 return -1; 713 return -1;
727 } 714 }
@@ -812,9 +799,9 @@ static bool parse_search(struct menu_entry *entry, const char *str)
812 799
813 logf("tag: %d", inst->tagorder[inst->tagorder_count]); 800 logf("tag: %d", inst->tagorder[inst->tagorder_count]);
814 801
815 tagtree_lock(); 802 core_pin(tagtree_handle);
816 while ( (ret = get_condition(inst)) > 0 ) ; 803 while ( (ret = get_condition(inst)) > 0 ) ;
817 tagtree_unlock(); 804 core_unpin(tagtree_handle);
818 805
819 if (ret < 0) 806 if (ret < 0)
820 return false; 807 return false;
@@ -1176,10 +1163,10 @@ static int parse_line(int n, char *buf, void *parameters)
1176 logf("tagtree failed to allocate %s", "menu items"); 1163 logf("tagtree failed to allocate %s", "menu items");
1177 return -2; 1164 return -2;
1178 } 1165 }
1179 tagtree_lock(); 1166 core_pin(tagtree_handle);
1180 if (parse_search(menu->items[menu->itemcount], buf)) 1167 if (parse_search(menu->items[menu->itemcount], buf))
1181 menu->itemcount++; 1168 menu->itemcount++;
1182 tagtree_unlock(); 1169 core_unpin(tagtree_handle);
1183 1170
1184 return 0; 1171 return 0;
1185} 1172}
@@ -1212,8 +1199,8 @@ static bool parse_menu(const char *filename)
1212 1199
1213static void tagtree_unload(struct tree_context *c) 1200static void tagtree_unload(struct tree_context *c)
1214{ 1201{
1215 int i; 1202 /* may be spurious... */
1216 tagtree_lock(); 1203 core_pin(tagtree_handle);
1217 1204
1218 remove_event(PLAYBACK_EVENT_TRACK_BUFFER, tagtree_buffer_event); 1205 remove_event(PLAYBACK_EVENT_TRACK_BUFFER, tagtree_buffer_event);
1219 remove_event(PLAYBACK_EVENT_TRACK_FINISH, tagtree_track_finish_event); 1206 remove_event(PLAYBACK_EVENT_TRACK_FINISH, tagtree_track_finish_event);
@@ -1229,7 +1216,7 @@ static void tagtree_unload(struct tree_context *c)
1229 return; 1216 return;
1230 } 1217 }
1231 1218
1232 for (i = 0; i < menu->itemcount; i++) 1219 for (int i = 0; i < menu->itemcount; i++)
1233 { 1220 {
1234 dptr->name = NULL; 1221 dptr->name = NULL;
1235 dptr->newtable = 0; 1222 dptr->newtable = 0;
@@ -1238,11 +1225,11 @@ static void tagtree_unload(struct tree_context *c)
1238 } 1225 }
1239 } 1226 }
1240 1227
1241 for (i = 0; i < menu_count; i++) 1228 for (int i = 0; i < menu_count; i++)
1242 menus[i] = NULL; 1229 menus[i] = NULL;
1243 menu_count = 0; 1230 menu_count = 0;
1244 1231
1245 for (i = 0; i < format_count; i++) 1232 for (int i = 0; i < format_count; i++)
1246 formats[i] = NULL; 1233 formats[i] = NULL;
1247 format_count = 0; 1234 format_count = 0;
1248 1235
@@ -1253,9 +1240,6 @@ static void tagtree_unload(struct tree_context *c)
1253 1240
1254 if (c) 1241 if (c)
1255 tree_unlock_cache(c); 1242 tree_unlock_cache(c);
1256 tagtree_unlock();
1257 if (lock_count > 0)
1258 tagtree_unlock();/* second unlock to enable re-init */
1259} 1243}
1260 1244
1261void tagtree_init(void) 1245void tagtree_init(void)
@@ -1285,8 +1269,6 @@ void tagtree_init(void)
1285 if (sizeof(struct tagentry) != sizeof(struct entry)) 1269 if (sizeof(struct tagentry) != sizeof(struct entry))
1286 panicf("tagentry(%zu) and entry mismatch(%zu)", 1270 panicf("tagentry(%zu) and entry mismatch(%zu)",
1287 sizeof(struct tagentry), sizeof(struct entry)); 1271 sizeof(struct tagentry), sizeof(struct entry));
1288 if (lock_count > 0)
1289 panicf("tagtree locked after parsing");
1290 1272
1291 /* If no root menu is set, assume it's the first single menu 1273 /* If no root menu is set, assume it's the first single menu
1292 * we have. That shouldn't normally happen. */ 1274 * we have. That shouldn't normally happen. */
@@ -1502,7 +1484,7 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
1502 1484
1503 /* because tagcache saves the clauses, we need to lock the buffer 1485 /* because tagcache saves the clauses, we need to lock the buffer
1504 * for the entire duration of the search */ 1486 * for the entire duration of the search */
1505 tagtree_lock(); 1487 core_pin(tagtree_handle);
1506 for (i = 0; i <= level; i++) 1488 for (i = 0; i <= level; i++)
1507 { 1489 {
1508 int j; 1490 int j;
@@ -1579,7 +1561,7 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
1579 1561
1580 fmt = NULL; 1562 fmt = NULL;
1581 /* Check the format */ 1563 /* Check the format */
1582 tagtree_lock(); 1564 core_pin(tagtree_handle);
1583 for (i = 0; i < format_count; i++) 1565 for (i = 0; i < format_count; i++)
1584 { 1566 {
1585 if (formats[i]->group_id != csi->format_id[level]) 1567 if (formats[i]->group_id != csi->format_id[level])
@@ -1592,7 +1574,7 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
1592 break; 1574 break;
1593 } 1575 }
1594 } 1576 }
1595 tagtree_unlock(); 1577 core_unpin(tagtree_handle);
1596 1578
1597 if (strcmp(tcs.result, UNTAGGED) == 0) 1579 if (strcmp(tcs.result, UNTAGGED) == 0)
1598 { 1580 {
@@ -1634,7 +1616,7 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
1634 logf("format_str() failed"); 1616 logf("format_str() failed");
1635 tagcache_search_finish(&tcs); 1617 tagcache_search_finish(&tcs);
1636 tree_unlock_cache(c); 1618 tree_unlock_cache(c);
1637 tagtree_unlock(); 1619 core_unpin(tagtree_handle);
1638 return 0; 1620 return 0;
1639 } 1621 }
1640 else 1622 else
@@ -1675,7 +1657,7 @@ entry_skip_formatter:
1675 { /* user aborted */ 1657 { /* user aborted */
1676 tagcache_search_finish(&tcs); 1658 tagcache_search_finish(&tcs);
1677 tree_unlock_cache(c); 1659 tree_unlock_cache(c);
1678 tagtree_unlock(); 1660 core_unpin(tagtree_handle);
1679 return current_entry_count; 1661 return current_entry_count;
1680 } 1662 }
1681 } 1663 }
@@ -1694,7 +1676,7 @@ entry_skip_formatter:
1694 { 1676 {
1695 tagcache_search_finish(&tcs); 1677 tagcache_search_finish(&tcs);
1696 tree_unlock_cache(c); 1678 tree_unlock_cache(c);
1697 tagtree_unlock(); 1679 core_unpin(tagtree_handle);
1698 return current_entry_count; 1680 return current_entry_count;
1699 } 1681 }
1700 1682
@@ -1710,7 +1692,7 @@ entry_skip_formatter:
1710 1692
1711 tagcache_search_finish(&tcs); 1693 tagcache_search_finish(&tcs);
1712 tree_unlock_cache(c); 1694 tree_unlock_cache(c);
1713 tagtree_unlock(); 1695 core_unpin(tagtree_handle);
1714 1696
1715 if (!sort && (sort_inverse || sort_limit)) 1697 if (!sort && (sort_inverse || sort_limit))
1716 { 1698 {
@@ -1870,7 +1852,7 @@ int tagtree_enter(struct tree_context* c)
1870 1852
1871 /* lock buflib for possible I/O to protect dptr */ 1853 /* lock buflib for possible I/O to protect dptr */
1872 tree_lock_cache(c); 1854 tree_lock_cache(c);
1873 tagtree_lock(); 1855 core_pin(tagtree_handle);
1874 1856
1875 bool reset_selection = true; 1857 bool reset_selection = true;
1876 1858
@@ -1940,7 +1922,7 @@ int tagtree_enter(struct tree_context* c)
1940 { 1922 {
1941 tagtree_exit(c); 1923 tagtree_exit(c);
1942 tree_unlock_cache(c); 1924 tree_unlock_cache(c);
1943 tagtree_unlock(); 1925 core_unpin(tagtree_handle);
1944 return 0; 1926 return 0;
1945 } 1927 }
1946 if (csi->clause[i][j]->numeric) 1928 if (csi->clause[i][j]->numeric)
@@ -1999,7 +1981,7 @@ int tagtree_enter(struct tree_context* c)
1999 } 1981 }
2000 1982
2001 tree_unlock_cache(c); 1983 tree_unlock_cache(c);
2002 tagtree_unlock(); 1984 core_unpin(tagtree_handle);
2003 1985
2004 return rc; 1986 return rc;
2005} 1987}
diff --git a/apps/tree.c b/apps/tree.c
index a034fd0545..6622e1c4c2 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -314,6 +314,18 @@ struct tree_context* tree_get_context(void)
314 return &tc; 314 return &tc;
315} 315}
316 316
317void tree_lock_cache(struct tree_context *t)
318{
319 core_pin(t->cache.name_buffer_handle);
320 core_pin(t->cache.entries_handle);
321}
322
323void tree_unlock_cache(struct tree_context *t)
324{
325 core_unpin(t->cache.name_buffer_handle);
326 core_unpin(t->cache.entries_handle);
327}
328
317/* 329/*
318 * Returns the position of a given file in the current directory 330 * Returns the position of a given file in the current directory
319 * returns -1 if not found 331 * returns -1 if not found
@@ -1020,9 +1032,6 @@ int rockbox_browse(struct browse_context *browse)
1020static int move_callback(int handle, void* current, void* new) 1032static int move_callback(int handle, void* current, void* new)
1021{ 1033{
1022 struct tree_cache* cache = &tc.cache; 1034 struct tree_cache* cache = &tc.cache;
1023 if (cache->lock_count > 0)
1024 return BUFLIB_CB_CANNOT_MOVE;
1025
1026 ptrdiff_t diff = new - current; 1035 ptrdiff_t diff = new - current;
1027 /* FIX_PTR makes sure to not accidentally update static allocations */ 1036 /* FIX_PTR makes sure to not accidentally update static allocations */
1028#define FIX_PTR(x) \ 1037#define FIX_PTR(x) \
diff --git a/apps/tree.h b/apps/tree.h
index c70ae8dac1..a75e8d2260 100644
--- a/apps/tree.h
+++ b/apps/tree.h
@@ -52,7 +52,6 @@ struct tree_cache {
52 int name_buffer_handle; /* handle to the name cache */ 52 int name_buffer_handle; /* handle to the name cache */
53 int max_entries; /* Max entries in the cache */ 53 int max_entries; /* Max entries in the cache */
54 int name_buffer_size; /* in bytes */ 54 int name_buffer_size; /* in bytes */
55 volatile int lock_count; /* non-0 if buffers may not move */
56}; 55};
57 56
58struct browse_context { 57struct browse_context {
@@ -120,14 +119,10 @@ void browse_context_init(struct browse_context *browse,
120int rockbox_browse(struct browse_context *browse); 119int rockbox_browse(struct browse_context *browse);
121int create_playlist(void); 120int create_playlist(void);
122void resume_directory(const char *dir); 121void resume_directory(const char *dir);
123static inline void tree_lock_cache(struct tree_context *t) 122
124{ 123void tree_lock_cache(struct tree_context *t);
125 t->cache.lock_count++; 124void tree_unlock_cache(struct tree_context *t);
126} 125
127static inline void tree_unlock_cache(struct tree_context *t)
128{
129 t->cache.lock_count--;
130}
131#ifdef WIN32 126#ifdef WIN32
132/* it takes an int on windows */ 127/* it takes an int on windows */
133#define getcwd_size_t int 128#define getcwd_size_t int