diff options
author | Thomas Martitz <kugel@rockbox.org> | 2011-10-09 12:27:35 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2011-10-09 12:27:35 +0000 |
commit | aed39dbbafc2f1cacfdce4382f22b06ab0224aae (patch) | |
tree | 2ff8db79199cb71486fbade6ddf837ea014b8e0d | |
parent | 227c7af9b3746a9ea4133df73bcac1ca08249aa3 (diff) | |
download | rockbox-aed39dbbafc2f1cacfdce4382f22b06ab0224aae.tar.gz rockbox-aed39dbbafc2f1cacfdce4382f22b06ab0224aae.zip |
Protect the move operation of buflib against IRQs.
This makes accessing the buffers with core_get_data() from
interrupt context safe, other buflib functions aren't really safe (yet).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30736 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/buflib.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/firmware/buflib.c b/firmware/buflib.c index 3b4f522dcf..d82acd77d3 100644 --- a/firmware/buflib.c +++ b/firmware/buflib.c | |||
@@ -206,16 +206,26 @@ move_block(struct buflib_context* ctx, union buflib_data* block, int shift) | |||
206 | handle, shift, shift*sizeof(union buflib_data)); | 206 | handle, shift, shift*sizeof(union buflib_data)); |
207 | new_block = block + shift; | 207 | new_block = block + shift; |
208 | new_start = tmp->alloc + shift*sizeof(union buflib_data); | 208 | new_start = tmp->alloc + shift*sizeof(union buflib_data); |
209 | |||
210 | /* disable IRQs to make accessing the buffer from interrupt context safe. */ | ||
211 | /* protect the move callback, as a cached global pointer might be updated | ||
212 | * in it. and protect "tmp->alloc = new_start" for buflib_get_data() */ | ||
213 | disable_irq(); | ||
209 | /* call the callback before moving */ | 214 | /* call the callback before moving */ |
210 | if (ops) | 215 | if (ops) |
211 | { | 216 | { |
212 | if (ops->move_callback(handle, tmp->alloc, new_start) | 217 | if (ops->move_callback(handle, tmp->alloc, new_start) |
213 | == BUFLIB_CB_CANNOT_MOVE) | 218 | == BUFLIB_CB_CANNOT_MOVE) |
219 | { | ||
220 | enable_irq(); | ||
214 | return false; | 221 | return false; |
222 | } | ||
215 | } | 223 | } |
224 | |||
216 | tmp->alloc = new_start; /* update handle table */ | 225 | tmp->alloc = new_start; /* update handle table */ |
217 | memmove(new_block, block, block->val * sizeof(union buflib_data)); | 226 | memmove(new_block, block, block->val * sizeof(union buflib_data)); |
218 | 227 | ||
228 | enable_irq(); | ||
219 | return true; | 229 | return true; |
220 | } | 230 | } |
221 | 231 | ||