Community
Participate
Working Groups
Build: I20041207 When ModalContext executes a runnable, control effectively transfers from the calling thread (typically the UI thread), to a ModalContextThread, and then back to the original calling thread. If the runnable needs to make use of thread-local state, a mechanism is needed to allow it to find out the execution thread before execution begins, and then may need an opportunity to pass thread-local back to the calling thread upon completion. Examples of state that needs to be able to do this "thread hopping" include ThreadLocal values, a thread's context class loader, and ISchedulingRules owned by a given thread. Here is an example from JDT refactoring. A refactoring needs to be able to "own" a scheduling rule for the entire duration of the operation to prevent concurrent access by other threads. This entire operation typically includes: 1) Acquiring operation input from the user (in UI thread) 2) Pre-condition checking (in a ModalContext thread) 3) Presentation of pre-condition results (in UI thread) 4) Execution of refactoring (another ModalContext) 5) Displaying results or errors (in UI thread) Since a scheduling rule (or any other locking mechanism) can only be owned by a single thread at a time, this operation requires the lock to be released and reacquired several times during the operation lifecycle. After one thread releases the rule and before the next thread acquires it, there is a timing hole where another thread can get the rule and perform an operation. If the operation that slips in invalidates the results of the precondition checks, the refactoring will likely fail in unpredicable ways. Platform core has added an atomic "rule transfer" API that allows an operation such as refactoring to pass off a rule to another thrad without the possibility of timing holes. The single remaining problem is that the ModalContextThread used in steps 2) and 4) above is not known in advance, so there is no opportunity to pass the rule from the UI thread to the ModalContextThread before it begins. After a few iterations, Dirk and I have come up with a simple "thread listener" interface that will solve this problem. If an IRunnableWithProgress implements the thread listener interface, it will be notified before any thread changes in the control flow take place. This is where scheduling rules can be transferred. This can also be used to pass a context class loader or other thread-specific state to the modal context thread before it executes.
Created attachment 16503 [details] Patch to org.eclipse.jface project Proposed implementation. New IThreadListener interface and hooks in ModalContext to call the listener.
Created attachment 16504 [details] Patch to org.eclipse.ui.tests This patch renames the "deadlock" test package to "concurrency" to make it a bit more general (it only contained a single test before). Also added is a test class that exercises scheduling rule transfer in conjunction with the proposed thread listener API on ModalContext.
Dirk, can you test out the patch to make sure it suits the needs of refactoring? I assume this is not something that you need for M4 so I will mark as M5 to give us time to test it. See also bug 79698 for additional back-story.
John, the patch works for me. M5 is fine for me as well.
May as well move this to you John as you are a commiter now.
Released latest revision of the IThreadListener patch. Tests added in new class TransferRuleTest in the new concurrency tests package.
No behaviour to verify for this.