void (@Nullable ProgressIndicator indicator) { FormattingTask task = myTask; if (task != null && myStateRef.compareAndSet(FormattingRequestState.NOT_STARTED, FormattingRequestState.RUNNING)) { try { myTaskSemaphore.acquire(); task.run(); long waitTime = 0; while (waitTime < getTimeout().getSeconds() * 1000L) { if (myTaskSemaphore.tryAcquire(RETRY_PERIOD, TimeUnit.MILLISECONDS)) { myTaskSemaphore.release(); break; } if (indicator != null) indicator.checkCanceled(); waitTime += RETRY_PERIOD; } if (myStateRef.compareAndSet(FormattingRequestState.RUNNING, FormattingRequestState.EXPIRED)) { FormattingNotificationService.getInstance(myContext.getProject()).reportError( getNotificationGroupId(), getName(), CodeStyleBundle.message("async.formatting.service.timeout", getName(), Long.toString(getTimeout().getSeconds())), getTimeoutActions(myContext)); } else if (myResult != null) { if (ApplicationManager.getApplication().isWriteAccessAllowed()) { updateDocument(myResult); } else { ApplicationManager.getApplication().invokeLater(() -> { CommandProcessor.getInstance().runUndoTransparentAction(() -> { try { WriteAction.run((ThrowableRunnable<Throwable>)() -> { updateDocument(myResult); }); } catch (Throwable throwable) { LOG.error(throwable); } }); }); } } } catch (InterruptedException ie) { LOG.warn("Interrupted formatting thread."); } } }