blob: 8f002a6a8fd123e91b4f0888f7aadde5eb118151 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 Tasktop Technologies and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.internal.commons.repositories.ui;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.equinox.security.storage.ISecurePreferences;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.operation.ModalContext;
import org.eclipse.mylyn.internal.commons.repositories.core.SecureCredentialsStore;
import org.eclipse.swt.widgets.Display;
/**
* When this class is accessed on the UI thread, access to the secure store will occur on a background thread and the
* event loop will continue to run. This prevents a deadlock that can occur when accessing the secure store on the UI
* thread.
* <p>
* Clients should be extremely careful when accessing this class on the UI thread while holding onto a lock (such as
* from within synchronized methods). It is possible that the event loop will process an event that spawns another job
* (such as when the user opens a dialog which runs a background operation). If that job also tries to acquire the lock,
* there will be a deadlock. For this reason, clients should never hold a lock while accessing this class on the UI
* thread, unless they can be certain that nothing can cause the UI thread to wait for another job that attempts to
* acquire the lock.
*
* @author Sam Davis
*/
public class UiSecureCredentialsStore extends SecureCredentialsStore {
public UiSecureCredentialsStore(String id) {
super(id);
}
@Override
protected ISecurePreferences getSecurePreferences() {
if (Display.getCurrent() != null) {
// ensure we don't open the secure preferences on the UI thread as this can cause deadlock
final ISecurePreferences securePreferences[] = new ISecurePreferences[1];
try {
ModalContext.run(new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
securePreferences[0] = UiSecureCredentialsStore.super.getSecurePreferences();
}
}, true, new NullProgressMonitor(), Display.getCurrent());
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return securePreferences[0];
}
return super.getSecurePreferences();
}
@Override
protected ISecurePreferences openSecurePreferences() {
Assert.isTrue(Display.getCurrent() == null);
return super.openSecurePreferences();
}
}