summaryrefslogtreecommitdiffstats
path: root/firmware/buflib.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2011-10-09 12:27:35 +0000
committerThomas Martitz <kugel@rockbox.org>2011-10-09 12:27:35 +0000
commitaed39dbbafc2f1cacfdce4382f22b06ab0224aae (patch)
tree2ff8db79199cb71486fbade6ddf837ea014b8e0d /firmware/buflib.c
parent227c7af9b3746a9ea4133df73bcac1ca08249aa3 (diff)
downloadrockbox-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
Diffstat (limited to 'firmware/buflib.c')
-rw-r--r--firmware/buflib.c10
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)
handle, shift, shift*sizeof(union buflib_data));
new_block = block + shift;
new_start = tmp->alloc + shift*sizeof(union buflib_data);
+
+ /* disable IRQs to make accessing the buffer from interrupt context safe. */
+ /* protect the move callback, as a cached global pointer might be updated
+ * in it. and protect "tmp->alloc = new_start" for buflib_get_data() */
+ disable_irq();
/* call the callback before moving */
if (ops)
{
if (ops->move_callback(handle, tmp->alloc, new_start)
== BUFLIB_CB_CANNOT_MOVE)
+ {
+ enable_irq();
return false;
+ }
}
+
tmp->alloc = new_start; /* update handle table */
memmove(new_block, block, block->val * sizeof(union buflib_data));
+ enable_irq();
return true;
}