Community
Participate
Working Groups
Build Identifier: 20100218-1602 The SVNKitConnector has a thread which monitors all progress monitors for cancellation. While querying the IProgressMonitor.isCanceled() it superflously holds the lock on its list of monitors. Therefore, when the progress monitor needs a lock (such as the display thread) inside its isCanceled() implementation there is potential for deadlocks when the thread holding that resource is simultaneously trying to remove a monitor from the locked list. The SVNKitConnector thread does not need to hold the lock. It can copy the list of monitors and release the lock before iterating the list. I provide a patch which does exactly this. By the way, I could not find the repository of org.polarion.team.svn.connector.svnkit.SVNConnector.java Is it not publically availiable for reading? Below is a stack trace which shows the deadlock scenario. Thread [SVN-QLAF4] (Suspended) SVNKitConnector$ProgressMonitorThread.remove(SVNKitConnector$ProgressMonitorWrapper) line: 1578 SVNKitConnector$ProgressMonitorWrapper.interrupt() line: 1652 SVNKitConnector.checkout(SVNEntryRevisionReference, String, int, long, ISVNProgressMonitor) line: 204 ThreadNameModifier.checkout(SVNEntryRevisionReference, String, int, long, ISVNProgressMonitor) line: 78 CheckoutAsOperation.doCheckout(IProgressMonitor, IPath) line: 169 CheckoutAsOperation$1.run(IProgressMonitor) line: 127 ProgressMonitorUtility.doSubTask(IActionOperation, IUnprotectedOperation, IProgressMonitor, int, int) line: 118 CheckoutAsOperation.runImpl(IProgressMonitor) line: 125 CheckoutAsOperation(AbstractActionOperation).run(IProgressMonitor) line: 81 ProgressMonitorUtility.doTask(IActionOperation, IProgressMonitor, int, int) line: 104 CompositeOperation.runImpl(IProgressMonitor) line: 95 CompositeOperation(AbstractActionOperation).run(IProgressMonitor) line: 81 UILoggedOperation(LoggedOperation).run(IProgressMonitor) line: 39 ProgressMonitorUtility.doTask(IActionOperation, IProgressMonitor, int, int) line: 104 ProgressMonitorUtility.doTaskExternal(IActionOperation, IProgressMonitor, ILoggedOperationFactory) line: 90 ProgressMonitorUtility.doTaskExternal(IActionOperation, IProgressMonitor) line: 81 SVNTeamProjectSetCapability.addToWorkspace(String[], ProjectSetSerializationContext, IProgressMonitor) line: 98 ProjectSetImporter.importProjectSet(TypeSafeUIProjectSetSerializationContext, XMLMemento, IProgressMonitor) line: 73 ProjectSetImporter.importProjectSet(String, InputStream, Shell, IProgressMonitor) line: 31 Installer$1.resultRun() line: 36 Installer$1.resultRun() line: 1 Installer$1(ResultRunnable<T>).run() line: 31 UISynchronizer(Synchronizer).syncExec(Runnable) line: 179 UISynchronizer.syncExec(Runnable) line: 150 Display.syncExec(Runnable) line: 4113 Installer.installTeamSet(IGenericApplicationInfo, IProgressMonitor) line: 45 Installer.install(IGenericApplicationInfo, IProgressMonitor) line: 23 ImportGenericAppWizard.runFinish(IProgressMonitor) line: 129 GeneratedWizard$1.run(IProgressMonitor) line: 71 ModalContext.runInCurrentThread(IRunnableWithProgress, IProgressMonitor) line: 464 ModalContext.run(IRunnableWithProgress, boolean, IProgressMonitor, Display) line: 372 WizardDialog.run(boolean, boolean, IRunnableWithProgress) line: 944 GeneratedWizard.performOperation(IWizardContainer, IRunnableWithProgress, boolean) line: 95 ImportGenericAppWizard(GeneratedWizard).runFinish() line: 78 ImportGenericAppWizard.performFinish() line: 106 WizardDialog.finishPressed() line: 752 WizardDialog.buttonPressed(int) line: 373 Dialog$2.widgetSelected(SelectionEvent) line: 624 TypedListener.handleEvent(Event) line: 228 EventTable.sendEvent(Event) line: 84 Button(Widget).sendEvent(Event) line: 1176 Display.runDeferredEvents() line: 3493 Display.readAndDispatch() line: 3112 WizardDialog(Window).runEventLoop(Shell) line: 825 WizardDialog(Window).open() line: 801 WizardHandler$Import.executeHandler(ExecutionEvent) line: 146 WizardHandler$Import(WizardHandler).execute(ExecutionEvent) line: 273 HandlerProxy.execute(ExecutionEvent) line: 294 Command.executeWithChecks(ExecutionEvent) line: 476 ParameterizedCommand.executeWithChecks(Object, Object) line: 508 HandlerService.executeCommand(ParameterizedCommand, Event) line: 169 SlaveHandlerService.executeCommand(ParameterizedCommand, Event) line: 241 ActionFactory$WorkbenchCommandAction(CommandAction).runWithEvent(Event) line: 157 ActionFactory$WorkbenchCommandAction(CommandAction).run() line: 171 ImportResourcesAction.run() line: 97 ImportResourcesAction(BaseSelectionListenerAction).runWithEvent(Event) line: 168 ActionContributionItem.handleWidgetSelection(Event, boolean) line: 584 ActionContributionItem.access$2(ActionContributionItem, Event, boolean) line: 501 ActionContributionItem$5.handleEvent(Event) line: 411 EventTable.sendEvent(Event) line: 84 MenuItem(Widget).sendEvent(Event) line: 1176 Display.runDeferredEvents() line: 3493 Display.readAndDispatch() line: 3112 Workbench.runEventLoop(Window$IExceptionHandler, Display) line: 2405 Workbench.runUI() line: 2369 Workbench.access$4(Workbench) line: 2221 Workbench$5.run() line: 500 Realm.runWithDefault(Realm, Runnable) line: 332 Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 493 PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149 IDEApplication.start(IApplicationContext) line: 113 EclipseAppHandle.run(Object) line: 194 EclipseAppLauncher.runApplication(Object) line: 110 EclipseAppLauncher.start(Object) line: 79 EclipseStarter.run(Object) line: 368 EclipseStarter.run(String[], Runnable) line: 179 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39 DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25 Method.invoke(Object, Object...) line: 597 Main.invokeFramework(String[], URL[]) line: 559 Main.basicRun(String[]) line: 514 Main.run(String[]) line: 1311 Main.main(String[]) line: 1287 Thread [SVN Kit 1.2 Connector] (Suspended) Object.wait(long) line: not available [native method] [local variables unavailable] RunnableLock(Object).wait() line: 485 UISynchronizer(Synchronizer).syncExec(Runnable) line: 186 UISynchronizer.syncExec(Runnable) line: 150 Display.syncExec(Runnable) line: 4113 UIProgressMonitor.displayExec(ResultRunnable<T>, T) line: 21 UIProgressMonitor.isCanceled() line: 72 SubProgressMonitorWithInfo(ProgressMonitorWrapper).isCanceled() line: 106 SubProgressMonitorWithInfo(ProgressMonitorWrapper).isCanceled() line: 106 SubProgressMonitorWithInfo(ProgressMonitorWrapper).isCanceled() line: 106 SVNProgressMonitor.isActivityCancelled() line: 84 SVNKitConnector$ProgressMonitorThread.checkForActivityCancelled() line: 1604 SVNKitConnector$ProgressMonitorThread.run() line: 1585 Reproducible: Sometimes Steps to Reproduce: See details
Created attachment 172514 [details] patch as promised in description
Thank you very much for your efforts and I'm sorry it took so long to just check the issue report. I fixed the issue for all of the existing connectors.