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 /firmware/buflib.c | |
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
Diffstat (limited to 'firmware/buflib.c')
-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) 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; } |