public boolean closeProject(
      @NotNull final Project project,
      final boolean save,
      final boolean dispose,
      boolean checkCanClose) {
    if (isLight(project)) {
      throw new AssertionError("must not close light project");
    }
    if (!isProjectOpened(project)) return true;
    if (checkCanClose && !canClose(project)) return false;
    final ShutDownTracker shutDownTracker = ShutDownTracker.getInstance();
    shutDownTracker.registerStopperThread(Thread.currentThread());
    try {
      if (save) {
        FileDocumentManager.getInstance().saveAllDocuments();
        project.save();
      }

      if (checkCanClose && !ensureCouldCloseIfUnableToSave(project)) {
        return false;
      }

      fireProjectClosing(project); // somebody can start progress here, do not wrap in write action

      ApplicationManager.getApplication()
          .runWriteAction(
              new Runnable() {
                @Override
                public void run() {
                  synchronized (myOpenProjects) {
                    myOpenProjects.remove(project);
                    cacheOpenProjects();
                    myTestProjects.remove(project);
                  }

                  myChangedProjectFiles.remove(project);

                  fireProjectClosed(project);

                  if (dispose) {
                    Disposer.dispose(project);
                  }
                }
              });
    } finally {
      shutDownTracker.unregisterStopperThread(Thread.currentThread());
    }

    return true;
  }
 public boolean isReadAccessAllowed() {
   Thread currentThread = Thread.currentThread();
   return ourDispatchThread == currentThread
       || isExceptionalThreadWithReadAccess()
       || myActionsLock.isReadLockAcquired()
       || myActionsLock.isWriteLockAcquired()
       || isDispatchThread();
 }
  private static void assertIsDispatchThread(String message) {
    if (ShutDownTracker.isShutdownHookRunning()) return;
    final Thread currentThread = Thread.currentThread();
    if (ourDispatchThread == currentThread) return;

    if (EventQueue.isDispatchThread()) {
      ourDispatchThread = currentThread;
    }
    if (ourDispatchThread == currentThread) return;

    Integer safeCounter = ourEdtSafe.get();
    if (safeCounter != null && safeCounter > 0) return;

    LOG.error(
        message,
        "Current thread: " + describe(Thread.currentThread()),
        "Our dispatch thread:" + describe(ourDispatchThread),
        "SystemEventQueueThread: " + describe(getEventQueueThread()));
  }
 public void assertReadAccessAllowed() {
   if (myHeadlessMode) return;
   if (!isReadAccessAllowed()) {
     LOG.error(
         "Read access is allowed from event dispatch thread or inside read-action only (see com.intellij.openapi.application.Application.runReadAction())",
         "Current thread: " + describe(Thread.currentThread()),
         "Our dispatch thread:" + describe(ourDispatchThread),
         "SystemEventQueueThread: " + describe(getEventQueueThread()));
   }
 }
  public void runWriteAction(@NotNull final Runnable action) {
    assertCanRunWriteAction();

    ActivityTracker.getInstance().inc();
    fireBeforeWriteActionStart(action);
    final AtomicBoolean stopped = new AtomicBoolean(false);

    if (ourDumpThreadsOnLongWriteActionWaiting > 0) {
      executeOnPooledThread(
          new Runnable() {
            @Override
            public void run() {
              while (!stopped.get()) {
                try {
                  Thread.sleep(ourDumpThreadsOnLongWriteActionWaiting);
                  if (!stopped.get()) {
                    PerformanceWatcher.getInstance().dumpThreads(true);
                  }
                } catch (InterruptedException ignored) {
                }
              }
            }
          });
    }

    LOG.assertTrue(
        myActionsLock.isWriteLockAcquired(Thread.currentThread())
            || !Thread.holdsLock(PsiLock.LOCK),
        "Thread must not hold PsiLock while performing writeAction");
    try {
      myActionsLock.writeLock().acquire();
    } catch (InterruptedException e) {
      throw new RuntimeInterruptedException(e);
    }
    stopped.set(true);

    try {
      myWriteActionsStack.push(action);

      fireWriteActionStarted(action);

      action.run();
    } finally {
      try {
        fireWriteActionFinished(action);

        myWriteActionsStack.pop();
      } finally {
        myActionsLock.writeLock().release();
      }
    }
  }
  public void assertIsDispatchThread(@Nullable final JComponent component) {
    if (component == null) return;

    Thread curThread = Thread.currentThread();
    if (ourDispatchThread == curThread) {
      return;
    }

    if (Boolean.TRUE.equals(component.getClientProperty(WAS_EVER_SHOWN))) {
      assertIsDispatchThread();
    } else {
      final JRootPane root = component.getRootPane();
      if (root != null) {
        component.putClientProperty(WAS_EVER_SHOWN, Boolean.TRUE);
        assertIsDispatchThread();
      }
    }
  }
 public boolean isWriteAccessAllowed() {
   return myActionsLock.isWriteLockAcquired(Thread.currentThread());
 }