public boolean isReadAccessAllowed() {
   Thread currentThread = Thread.currentThread();
   return ourDispatchThread == currentThread
       || isExceptionalThreadWithReadAccess()
       || myActionsLock.isReadLockAcquired()
       || myActionsLock.isWriteLockAcquired()
       || isDispatchThread();
 }
  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 boolean isWriteAccessAllowed() {
   return myActionsLock.isWriteLockAcquired(Thread.currentThread());
 }