diff options
-rw-r--r-- | apps/gui/icon.c | 8 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_backdrops.c | 14 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 16 | ||||
-rw-r--r-- | apps/tagcache.c | 13 | ||||
-rw-r--r-- | apps/tagtree.c | 66 | ||||
-rw-r--r-- | apps/tree.c | 15 | ||||
-rw-r--r-- | apps/tree.h | 13 | ||||
-rw-r--r-- | firmware/common/dircache.c | 60 | ||||
-rw-r--r-- | firmware/common/unicode.c | 29 | ||||
-rw-r--r-- | firmware/font.c | 16 |
10 files changed, 93 insertions, 157 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 |
44 | static int handle_being_loaded; | ||
45 | static int current_lcd_backdrop[NB_SCREENS]; | 44 | static int current_lcd_backdrop[NB_SCREENS]; |
46 | 45 | ||
47 | bool skin_backdrop_get_debug(int index, char **path, int *ref_count, size_t *size) | 46 | bool 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 | ||
66 | static int buflib_move_callback(int handle, void* current, void* new) | 65 | static 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__ |
1873 | static int currently_loading_handle = -1; | ||
1874 | static int buflib_move_callback(int handle, void* current, void* new) | 1873 | static 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 | } |
1892 | static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL}; | 1890 | static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL}; |
1893 | static void lock_handle(int handle) | ||
1894 | { | ||
1895 | currently_loading_handle = handle; | ||
1896 | } | ||
1897 | static void unlock_handle(void) | ||
1898 | { | ||
1899 | currently_loading_handle = -1; | ||
1900 | } | ||
1901 | #endif | 1891 | #endif |
1902 | 1892 | ||
1903 | static int load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir) | 1893 | static 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 | ||
283 | static inline void tcrc_buffer_lock(void) | 282 | static inline void tcrc_buffer_lock(void) |
284 | { | 283 | { |
285 | tcramcache.move_lock++; | 284 | core_pin(tcramcache.handle); |
286 | } | 285 | } |
287 | 286 | ||
288 | static inline void tcrc_buffer_unlock(void) | 287 | static 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) | |||
4005 | static int move_cb(int handle, void* current, void* new) | 4003 | static 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; | |||
192 | static struct tree_context *tc; | 192 | static struct tree_context *tc; |
193 | 193 | ||
194 | /* a few memory alloc helper */ | 194 | /* a few memory alloc helper */ |
195 | static int tagtree_handle, lock_count; | 195 | static int tagtree_handle; |
196 | static size_t tagtree_bufsize, tagtree_buf_used; | 196 | static 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 | ||
254 | static inline void tagtree_lock(void) | ||
255 | { | ||
256 | lock_count++; | ||
257 | } | ||
258 | |||
259 | static inline void tagtree_unlock(void) | ||
260 | { | ||
261 | lock_count--; | ||
262 | } | ||
263 | |||
264 | static struct buflib_callbacks ops = { | 251 | static 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 | ||
1213 | static void tagtree_unload(struct tree_context *c) | 1200 | static 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 | ||
1261 | void tagtree_init(void) | 1245 | void 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 | ||
317 | void 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 | |||
323 | void 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) | |||
1020 | static int move_callback(int handle, void* current, void* new) | 1032 | static 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 | ||
58 | struct browse_context { | 57 | struct browse_context { |
@@ -120,14 +119,10 @@ void browse_context_init(struct browse_context *browse, | |||
120 | int rockbox_browse(struct browse_context *browse); | 119 | int rockbox_browse(struct browse_context *browse); |
121 | int create_playlist(void); | 120 | int create_playlist(void); |
122 | void resume_directory(const char *dir); | 121 | void resume_directory(const char *dir); |
123 | static inline void tree_lock_cache(struct tree_context *t) | 122 | |
124 | { | 123 | void tree_lock_cache(struct tree_context *t); |
125 | t->cache.lock_count++; | 124 | void tree_unlock_cache(struct tree_context *t); |
126 | } | 125 | |
127 | static 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 |
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 8917b3348e..1d6371a6b5 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c | |||
@@ -249,7 +249,6 @@ static struct dircache_runinfo | |||
249 | /* cache buffer info */ | 249 | /* cache buffer info */ |
250 | int handle; /* buflib buffer handle */ | 250 | int handle; /* buflib buffer handle */ |
251 | size_t bufsize; /* size of buflib allocation - 1 */ | 251 | size_t bufsize; /* size of buflib allocation - 1 */ |
252 | int buflocked; /* don't move due to other allocs */ | ||
253 | union { | 252 | union { |
254 | void *p; /* address of buffer - ENTRYSIZE */ | 253 | void *p; /* address of buffer - ENTRYSIZE */ |
255 | struct dircache_entry *pentry; /* alias of .p to assist entry resolution */ | 254 | struct dircache_entry *pentry; /* alias of .p to assist entry resolution */ |
@@ -329,29 +328,9 @@ static inline void dumpster_clean_buffer(void *p, size_t size) | |||
329 | */ | 328 | */ |
330 | static int move_callback(int handle, void *current, void *new) | 329 | static int move_callback(int handle, void *current, void *new) |
331 | { | 330 | { |
332 | if (dircache_runinfo.buflocked) | 331 | (void)handle; (void)current; |
333 | return BUFLIB_CB_CANNOT_MOVE; | ||
334 | |||
335 | dircache_runinfo.p = new - ENTRYSIZE; | 332 | dircache_runinfo.p = new - ENTRYSIZE; |
336 | |||
337 | return BUFLIB_CB_OK; | 333 | return BUFLIB_CB_OK; |
338 | (void)handle; (void)current; | ||
339 | } | ||
340 | |||
341 | /** | ||
342 | * add a "don't move" lock count | ||
343 | */ | ||
344 | static inline void buffer_lock(void) | ||
345 | { | ||
346 | dircache_runinfo.buflocked++; | ||
347 | } | ||
348 | |||
349 | /** | ||
350 | * remove a "don't move" lock count | ||
351 | */ | ||
352 | static inline void buffer_unlock(void) | ||
353 | { | ||
354 | dircache_runinfo.buflocked--; | ||
355 | } | 334 | } |
356 | 335 | ||
357 | 336 | ||
@@ -530,14 +509,14 @@ static void set_buffer(int handle, size_t size) | |||
530 | 509 | ||
531 | /** | 510 | /** |
532 | * remove the allocation from dircache control and return the handle | 511 | * remove the allocation from dircache control and return the handle |
512 | * Note that dircache must not be using the buffer! | ||
533 | */ | 513 | */ |
534 | static int reset_buffer(void) | 514 | static int reset_buffer(void) |
535 | { | 515 | { |
536 | int handle = dircache_runinfo.handle; | 516 | int handle = dircache_runinfo.handle; |
537 | if (handle > 0) | 517 | if (handle > 0) |
538 | { | 518 | { |
539 | /* don't mind .p; it might get changed by the callback even after | 519 | /* don't mind .p; buffer presence is determined by the following: */ |
540 | this call; buffer presence is determined by the following: */ | ||
541 | dircache_runinfo.handle = 0; | 520 | dircache_runinfo.handle = 0; |
542 | dircache_runinfo.bufsize = 0; | 521 | dircache_runinfo.bufsize = 0; |
543 | } | 522 | } |
@@ -1857,7 +1836,7 @@ static void reset_cache(void) | |||
1857 | */ | 1836 | */ |
1858 | static void build_volumes(void) | 1837 | static void build_volumes(void) |
1859 | { | 1838 | { |
1860 | buffer_lock(); | 1839 | core_pin(dircache_runinfo.handle); |
1861 | 1840 | ||
1862 | for (int i = 0; i < NUM_VOLUMES; i++) | 1841 | for (int i = 0; i < NUM_VOLUMES; i++) |
1863 | { | 1842 | { |
@@ -1903,12 +1882,14 @@ static void build_volumes(void) | |||
1903 | 1882 | ||
1904 | logf("Done, %ld KiB used", dircache.size / 1024); | 1883 | logf("Done, %ld KiB used", dircache.size / 1024); |
1905 | 1884 | ||
1906 | buffer_unlock(); | 1885 | core_unpin(dircache_runinfo.handle); |
1907 | } | 1886 | } |
1908 | 1887 | ||
1909 | /** | 1888 | /** |
1910 | * allocate buffer and return whether or not a synchronous build should take | 1889 | * allocate buffer and return whether or not a synchronous build should take |
1911 | * place; if 'realloced' is NULL, it's just a query about what will happen | 1890 | * place; if 'realloced' is NULL, it's just a query about what will happen |
1891 | * | ||
1892 | * Note this must be called with the dircache_lock() active. | ||
1912 | */ | 1893 | */ |
1913 | static int prepare_build(bool *realloced) | 1894 | static int prepare_build(bool *realloced) |
1914 | { | 1895 | { |
@@ -1958,16 +1939,14 @@ static int prepare_build(bool *realloced) | |||
1958 | *realloced = true; | 1939 | *realloced = true; |
1959 | reset_cache(); | 1940 | reset_cache(); |
1960 | 1941 | ||
1961 | buffer_lock(); | ||
1962 | |||
1963 | int handle = reset_buffer(); | 1942 | int handle = reset_buffer(); |
1964 | dircache_unlock(); | 1943 | dircache_unlock(); /* release lock held by caller */ |
1965 | 1944 | ||
1966 | core_free(handle); | 1945 | core_free(handle); |
1967 | 1946 | ||
1968 | handle = alloc_cache(size); | 1947 | handle = alloc_cache(size); |
1969 | 1948 | ||
1970 | dircache_lock(); | 1949 | dircache_lock(); /* reacquire lock */ |
1971 | 1950 | ||
1972 | if (dircache_runinfo.suspended && handle > 0) | 1951 | if (dircache_runinfo.suspended && handle > 0) |
1973 | { | 1952 | { |
@@ -1979,13 +1958,9 @@ static int prepare_build(bool *realloced) | |||
1979 | } | 1958 | } |
1980 | 1959 | ||
1981 | if (handle <= 0) | 1960 | if (handle <= 0) |
1982 | { | ||
1983 | buffer_unlock(); | ||
1984 | return -1; | 1961 | return -1; |
1985 | } | ||
1986 | 1962 | ||
1987 | set_buffer(handle, size); | 1963 | set_buffer(handle, size); |
1988 | buffer_unlock(); | ||
1989 | 1964 | ||
1990 | return syncbuild; | 1965 | return syncbuild; |
1991 | } | 1966 | } |
@@ -2384,9 +2359,9 @@ void dircache_fileop_create(struct file_base_info *dirinfop, | |||
2384 | if ((dinp->attr & ATTR_DIRECTORY) && !is_dotdir_name(basename)) | 2359 | if ((dinp->attr & ATTR_DIRECTORY) && !is_dotdir_name(basename)) |
2385 | { | 2360 | { |
2386 | /* scan-in the contents of the new directory at this level only */ | 2361 | /* scan-in the contents of the new directory at this level only */ |
2387 | buffer_lock(); | 2362 | core_pin(dircache_runinfo.handle); |
2388 | sab_process_dir(infop, false); | 2363 | sab_process_dir(infop, false); |
2389 | buffer_unlock(); | 2364 | core_unpin(dircache_runinfo.handle); |
2390 | } | 2365 | } |
2391 | } | 2366 | } |
2392 | 2367 | ||
@@ -2915,7 +2890,7 @@ void dircache_dump(void) | |||
2915 | 2890 | ||
2916 | if (dircache_runinfo.handle) | 2891 | if (dircache_runinfo.handle) |
2917 | { | 2892 | { |
2918 | buffer_lock(); | 2893 | core_pin(dircache_runinfo.handle); |
2919 | 2894 | ||
2920 | /* bin */ | 2895 | /* bin */ |
2921 | write(fdbin, dircache_runinfo.p + ENTRYSIZE, | 2896 | write(fdbin, dircache_runinfo.p + ENTRYSIZE, |
@@ -2985,7 +2960,7 @@ void dircache_dump(void) | |||
2985 | tm.tm_hour, tm.tm_min, tm.tm_sec); | 2960 | tm.tm_hour, tm.tm_min, tm.tm_sec); |
2986 | } | 2961 | } |
2987 | 2962 | ||
2988 | buffer_unlock(); | 2963 | core_unpin(dircache_runinfo.handle); |
2989 | } | 2964 | } |
2990 | 2965 | ||
2991 | dircache_unlock(); | 2966 | dircache_unlock(); |
@@ -3104,7 +3079,6 @@ int dircache_load(void) | |||
3104 | } | 3079 | } |
3105 | 3080 | ||
3106 | dircache_lock(); | 3081 | dircache_lock(); |
3107 | buffer_lock(); | ||
3108 | 3082 | ||
3109 | if (!dircache_is_clean(false)) | 3083 | if (!dircache_is_clean(false)) |
3110 | goto error; | 3084 | goto error; |
@@ -3113,6 +3087,7 @@ int dircache_load(void) | |||
3113 | dircache = maindata.dircache; | 3087 | dircache = maindata.dircache; |
3114 | 3088 | ||
3115 | set_buffer(handle, bufsize); | 3089 | set_buffer(handle, bufsize); |
3090 | core_pin(handle); | ||
3116 | hasbuffer = true; | 3091 | hasbuffer = true; |
3117 | 3092 | ||
3118 | /* convert back to in-RAM representation */ | 3093 | /* convert back to in-RAM representation */ |
@@ -3167,13 +3142,13 @@ int dircache_load(void) | |||
3167 | dircache_enable_internal(false); | 3142 | dircache_enable_internal(false); |
3168 | 3143 | ||
3169 | /* cache successfully loaded */ | 3144 | /* cache successfully loaded */ |
3145 | core_unpin(handle); | ||
3170 | logf("Done, %ld KiB used", dircache.size / 1024); | 3146 | logf("Done, %ld KiB used", dircache.size / 1024); |
3171 | rc = 0; | 3147 | rc = 0; |
3172 | error: | 3148 | error: |
3173 | if (rc < 0 && hasbuffer) | 3149 | if (rc < 0 && hasbuffer) |
3174 | reset_buffer(); | 3150 | reset_buffer(); |
3175 | 3151 | ||
3176 | buffer_unlock(); | ||
3177 | dircache_unlock(); | 3152 | dircache_unlock(); |
3178 | 3153 | ||
3179 | error_nolock: | 3154 | error_nolock: |
@@ -3199,8 +3174,9 @@ int dircache_save(void) | |||
3199 | if (fd < 0) | 3174 | if (fd < 0) |
3200 | return -1; | 3175 | return -1; |
3201 | 3176 | ||
3177 | /* it seems the handle *must* exist if this function is called */ | ||
3202 | dircache_lock(); | 3178 | dircache_lock(); |
3203 | buffer_lock(); | 3179 | core_pin(dircache_runinfo.handle); |
3204 | 3180 | ||
3205 | int rc = -1; | 3181 | int rc = -1; |
3206 | 3182 | ||
@@ -3269,7 +3245,7 @@ int dircache_save(void) | |||
3269 | that makes what was saved completely invalid */ | 3245 | that makes what was saved completely invalid */ |
3270 | rc = 0; | 3246 | rc = 0; |
3271 | error: | 3247 | error: |
3272 | buffer_unlock(); | 3248 | core_unpin(dircache_runinfo.handle); |
3273 | dircache_unlock(); | 3249 | dircache_unlock(); |
3274 | 3250 | ||
3275 | if (rc < 0) | 3251 | if (rc < 0) |
diff --git a/firmware/common/unicode.c b/firmware/common/unicode.c index f0f663f712..e53ad6bcb0 100644 --- a/firmware/common/unicode.c +++ b/firmware/common/unicode.c | |||
@@ -168,6 +168,10 @@ static unsigned short default_cp_table_buf[MAX_CP_TABLE_SIZE+1]; | |||
168 | do {} while (0) | 168 | do {} while (0) |
169 | #define cp_table_alloc(filename, size, opsp) \ | 169 | #define cp_table_alloc(filename, size, opsp) \ |
170 | ({ (void)(opsp); 1; }) | 170 | ({ (void)(opsp); 1; }) |
171 | #define cp_table_pin(handle) \ | ||
172 | do { (void)handle; } while(0) | ||
173 | #define cp_table_unpin(handle) \ | ||
174 | do { (void)handle; } while(0) | ||
171 | #else | 175 | #else |
172 | #define cp_table_alloc(filename, size, opsp) \ | 176 | #define cp_table_alloc(filename, size, opsp) \ |
173 | core_alloc_ex((filename), (size), (opsp)) | 177 | core_alloc_ex((filename), (size), (opsp)) |
@@ -175,6 +179,10 @@ static unsigned short default_cp_table_buf[MAX_CP_TABLE_SIZE+1]; | |||
175 | core_free(handle) | 179 | core_free(handle) |
176 | #define cp_table_get_data(handle) \ | 180 | #define cp_table_get_data(handle) \ |
177 | core_get_data(handle) | 181 | core_get_data(handle) |
182 | #define cp_table_pin(handle) \ | ||
183 | core_pin(handle) | ||
184 | #define cp_table_unpin(handle) \ | ||
185 | core_unpin(handle) | ||
178 | #endif | 186 | #endif |
179 | 187 | ||
180 | static const unsigned char utf8comp[6] = | 188 | static const unsigned char utf8comp[6] = |
@@ -191,21 +199,8 @@ static inline void cptable_tohw16(uint16_t *buf, unsigned int count) | |||
191 | (void)buf; (void)count; | 199 | (void)buf; (void)count; |
192 | } | 200 | } |
193 | 201 | ||
194 | static int move_callback(int handle, void *current, void *new) | ||
195 | { | ||
196 | /* we don't keep a pointer but we have to stop it if this applies to a | ||
197 | buffer not yet swapped-in since it will likely be in use in an I/O | ||
198 | call */ | ||
199 | return (handle != default_cp_handle || default_cp_table_ref != 0) ? | ||
200 | BUFLIB_CB_CANNOT_MOVE : BUFLIB_CB_OK; | ||
201 | (void)current; (void)new; | ||
202 | } | ||
203 | |||
204 | static int alloc_and_load_cp_table(int cp, void *buf) | 202 | static int alloc_and_load_cp_table(int cp, void *buf) |
205 | { | 203 | { |
206 | static struct buflib_callbacks ops = | ||
207 | { .move_callback = move_callback }; | ||
208 | |||
209 | /* alloc and read only if there is an associated file */ | 204 | /* alloc and read only if there is an associated file */ |
210 | const char *filename = cp_info[cp].filename; | 205 | const char *filename = cp_info[cp].filename; |
211 | if (!filename) | 206 | if (!filename) |
@@ -228,13 +223,17 @@ static int alloc_and_load_cp_table(int cp, void *buf) | |||
228 | !(size % (off_t)sizeof (uint16_t))) { | 223 | !(size % (off_t)sizeof (uint16_t))) { |
229 | 224 | ||
230 | /* if the buffer is provided, use that but don't alloc */ | 225 | /* if the buffer is provided, use that but don't alloc */ |
231 | int handle = buf ? 0 : cp_table_alloc(filename, size, &ops); | 226 | int handle = buf ? 0 : cp_table_alloc(filename, size, NULL); |
232 | if (handle > 0) | 227 | if (handle > 0) { |
228 | cp_table_pin(handle); | ||
233 | buf = cp_table_get_data(handle); | 229 | buf = cp_table_get_data(handle); |
230 | } | ||
234 | 231 | ||
235 | if (buf && read(fd, buf, size) == size) { | 232 | if (buf && read(fd, buf, size) == size) { |
236 | close(fd); | 233 | close(fd); |
237 | cptable_tohw16(buf, size / sizeof (uint16_t)); | 234 | cptable_tohw16(buf, size / sizeof (uint16_t)); |
235 | if (handle > 0) | ||
236 | cp_table_unpin(handle); | ||
238 | return handle; | 237 | return handle; |
239 | } | 238 | } |
240 | 239 | ||
diff --git a/firmware/font.c b/firmware/font.c index 724cb84d57..7ce64ed47d 100644 --- a/firmware/font.c +++ b/firmware/font.c | |||
@@ -90,7 +90,6 @@ extern struct font sysfont; | |||
90 | 90 | ||
91 | struct buflib_alloc_data { | 91 | struct buflib_alloc_data { |
92 | struct font font; /* must be the first member! */ | 92 | struct font font; /* must be the first member! */ |
93 | int handle_locks; /* is the buflib handle currently locked? */ | ||
94 | int refcount; /* how many times has this font been loaded? */ | 93 | int refcount; /* how many times has this font been loaded? */ |
95 | unsigned char buffer[]; | 94 | unsigned char buffer[]; |
96 | }; | 95 | }; |
@@ -107,9 +106,6 @@ static int buflibmove_callback(int handle, void* current, void* new) | |||
107 | struct buflib_alloc_data *alloc = (struct buflib_alloc_data*)current; | 106 | struct buflib_alloc_data *alloc = (struct buflib_alloc_data*)current; |
108 | ptrdiff_t diff = new - current; | 107 | ptrdiff_t diff = new - current; |
109 | 108 | ||
110 | if (alloc->handle_locks > 0) | ||
111 | return BUFLIB_CB_CANNOT_MOVE; | ||
112 | |||
113 | #define UPDATE(x) if (x) { x = PTR_ADD(x, diff); } | 109 | #define UPDATE(x) if (x) { x = PTR_ADD(x, diff); } |
114 | 110 | ||
115 | UPDATE(alloc->font.bits); | 111 | UPDATE(alloc->font.bits); |
@@ -129,18 +125,18 @@ static void lock_font_handle(int handle, bool lock) | |||
129 | { | 125 | { |
130 | if ( handle < 0 ) | 126 | if ( handle < 0 ) |
131 | return; | 127 | return; |
132 | struct buflib_alloc_data *alloc = core_get_data(handle); | 128 | |
133 | if ( lock ) | 129 | if (lock) |
134 | alloc->handle_locks++; | 130 | core_pin(handle); |
135 | else | 131 | else |
136 | alloc->handle_locks--; | 132 | core_unpin(handle); |
137 | } | 133 | } |
138 | 134 | ||
139 | void font_lock(int font_id, bool lock) | 135 | void font_lock(int font_id, bool lock) |
140 | { | 136 | { |
141 | if( font_id < 0 || font_id >= MAXFONTS ) | 137 | if( font_id < 0 || font_id >= MAXFONTS ) |
142 | return; | 138 | return; |
143 | if( buflib_allocations[font_id] >= 0 ) | 139 | if( buflib_allocations[font_id] > 0 ) |
144 | lock_font_handle(buflib_allocations[font_id], lock); | 140 | lock_font_handle(buflib_allocations[font_id], lock); |
145 | } | 141 | } |
146 | 142 | ||
@@ -522,8 +518,8 @@ int font_load_ex( const char *path, size_t buf_size, int glyphs ) | |||
522 | return -1; | 518 | return -1; |
523 | } | 519 | } |
524 | struct buflib_alloc_data *pdata; | 520 | struct buflib_alloc_data *pdata; |
521 | core_pin(handle); | ||
525 | pdata = core_get_data(handle); | 522 | pdata = core_get_data(handle); |
526 | pdata->handle_locks = 1; | ||
527 | pdata->refcount = 1; | 523 | pdata->refcount = 1; |
528 | 524 | ||
529 | /* load and init */ | 525 | /* load and init */ |