aemu
aemu copied to clipboard
Unsafe locking of critical sections
the following code sequence is not safe:
while (context->event_stack_lock) sceKernelDelayThread(1000);
context->event_stack_lock = 1;
...do something...
context->event_stack_lock = 0;
A thread reschedule could happen between the test in the "while" and setting
the lock to "1". The 2 threads could both think the lock is free and both enter
the critical section at the same time.
Better would be to use a Mutex:
context->event_stack_mutex = sceKernelCreateMutex("Event Stack", PSP_MUTEX_ATTR_ALLOW_RECURSIVE, 0, NULL);
sceKernelLockMutex(context->event_stack_mutex, 1, NULL);
...do something...
sceKernelUnlockMutex(context->event_stack_mutex, 1);
The attribute PSP_MUTEX_ATTR_ALLOW_RECURSIVE allows a thread to lock again a
mutex when it has already been locked by himself. This could be useful to also
protect the sequence below, see Issue 2 (_spawnLocalEvent will again lock the
mutex):
sceKernelLockMutex(context->event_stack_mutex, 1, NULL);
_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_ESTABLISHED, sendermac, 0, NULL);
_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_ACCEPT, sendermac, optlen, opt);
sceKernelUnlockMutex(context->event_stack_mutex, 1);
Original issue reported on code.google.com by [email protected]
on 12 Jul 2012 at 7:20