summaryrefslogtreecommitdiff
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
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
-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)
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