[FIXED HUDSON-6819] Here is the race condition that induces this problem.
- Task X becomes buildable - Thread E1 enters the pop() method, assigns X to an executor E2. Note that at this point X is not removed from the buildables list yet - Thread E1 goes to offer.event.block and blocks, losing the lock - Thread E3 enters the pop() method, assigns X to anogher executor E4. This is possible because X is still in the buildables list. - Thread E3 goes to offer.event.block and blocks, losing the lock. - Thread E2 wakes up, obtains the lock and execute the rest of the pop() method. It decides that it's assigned X, it removes X from the buildables list. - Thread E2 leaves the pop() method, loses the lock, and starts building X - Thread E4 wakes up, obtains the lock, and executes the rest of the pop() method. It decides that it's assigned X. It tries to remove X from the buildables list. This remove operation becomes no-op, but we don't check that. - Thread E4 leaves the pop(), and start building X. Thus we end up building X twice. To avoid this problem, I've introduced the 4th state "pending", and moves BuildableItem from buildables to pendings as soon as we assigned it to the executor. New BuildableItem cannot be created while its another copy is either in the buildables or pendings state. git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@32258 71c3de6d-444a-0410-be80-ed276b4c234a
Showing
想要评论请 注册 或 登录