- Loading...
...
This last helper function exists for making life easier for list walker code. List walker code calls get_list_head_locked() to get the locked list head and then walks the list applying its particular logic to elements in the list. In order to safely walk to the 'next' ObjectMonitor in a list, the list walker code must lock the 'next' ObjectMonitor before unlocking the 'current' ObjectMonitor that it has locked. If a list walker unlocks 'current' before locking 'next', then there is race where 'current' could be modified to refer to something other than the 'next' value that was in place when 'current' was locked. By locking 'next' first and then unlocking 'current', the list walker can safely advance to 'next'.
L01: static ObjectMonitor* lock_next_for_traversal(ObjectMonitor* cur) {
L02: assert(is_locked(cur), "cur=" INTPTR_FORMAT " must be locked", p2i(cur));
L03: ObjectMonitor* next = unmarked_next(cur);
L04: if (next == NULL) { // Reached the end of the list.
L05: om_unlock(cur);
L06: return NULL;
L07: }
L08: om_lock(next); // Lock next before unlocking current to keep
L09: om_unlock(cur); // from being by-passed by another thread.
L10: return next;
L11: }
This function is pretty straight forward so there are no detailed notes for it.
...