3

I encounter some problems when I try to update Eclipse plug-ins at the start up of Eclipse. My program pops up the dialog at Help -> Check for Updates at the start up of Eclipse. But, when the user proceeds with the update quickly, Eclipse throws an exception saying that the p2 profile is in use. I believe this is because other Eclipse jobs are using the p2 profile at the start up and thus my program fails to use the p2 profile to update the plug-ins. How can I safely use the p2 profile? How can I use the p2 profile in isolation?

I've uploaded the minimal piece of code that is needed to reproduce the problem on github. And, I've described the problem and the steps to reproduce it in details in an issue on the github repository.

reprogrammer
  • 14,298
  • 16
  • 57
  • 93

2 Answers2

0

You can get the ProvisioningJob from your UpdateOperation, let it belongs to the family of running profile change job. See org.eclipse.core.runtime.jobs.Job.belongsTo(Object).

Besides I have two ideas to do it via using internal API,

  1. try to test lock the profile to see whether it's being changed. org.eclipse.equinox.internal.p2.engine.SimpleProfileRegistry.lockProfile(Profile)
  2. run your like before, but catch IlegalStateException, then register a ProvisioningListener on the IProvisioningEventBus to be notified when the running profilechangeoperation is finished.
Kane
  • 8,035
  • 7
  • 46
  • 75
  • @Kane: It seems straightforward to lock and unlock a profile explicitly. But, it requires the use of internal API, which is discouraged. You suggested to get the ProvisioningJob from the UpdateOperation and make sure that it belongs to the family of running profile change job. But, how can I find the family of the running profile change job? – reprogrammer Jun 17 '11 at 05:42
  • I think you can add breakpoint in the method of SimpleProfileRegistry.lockProfile to see which job is locking the profile. – Kane Jun 17 '11 at 05:49
  • The only `ProvisioningJob` that implements `Job.belongsTo` is `LoadMetadataRepositoryJob`. So, we cannot use the job family to enforce exclusive access to the profile. – reprogrammer Jun 18 '11 at 00:16
  • It's not easy to add breakpoints because to test my plug-in, I have to create a new update site and install it twice. I can modify Eclipse plug-ins and create feature patches. But, I'd rather not go through the trouble of creating feature patches just to debug my plug-in. – reprogrammer Jun 18 '11 at 00:19
  • Listening to `IProvisioningEventBus` to get notified when some running jobs finish doesn't guarantee mutual exclusion because another job could immediately begin right after all existing jobs finish. This leads to a TOCTTOU (http://en.wikipedia.org/wiki/Time-of-check-to-time-of-use) bug. – reprogrammer Jun 18 '11 at 00:22
  • Another problem with `SimpleProfileRegistry.lockProfile` is that it doesn't block until it acquires the lock on the profile. Instead, it simply throws an exception saying that the profile is in use. – reprogrammer Jun 18 '11 at 00:24
  • It isn't clear to me how Eclipse ensures the mutual exclusive access to a profile. – reprogrammer Jun 18 '11 at 00:36
0

My commit opens the "Check for Updates" dialog by invoking the command "org.eclipse.equinox.p2.ui.sdk.update" instead of invoking the following method.

org.eclipse.equinox.p2.ui.ProvisioningUI.openUpdateWizard(boolean, UpdateOperation, LoadMetadataRepositoryJob)

Surprisingly, this change seems to fix the issue with the race condition in accessing the p2 profile. Does anyone have an explanation for how my commit removes the race condition?

reprogrammer
  • 14,298
  • 16
  • 57
  • 93