private static void writeEntryToDisk(DiskEntry entry, InternalRegion region, VersionTag tag,
        boolean asyncQueueWasFull) {
      if (region.isThisRegionBeingClosedOrDestroyed()) {
        return;
      }
      DiskRegion dr = region.getDiskRegion();
      if (!asyncQueueWasFull) {
        dr.setClearCountReference();
      }
      synchronized (entry) { // fixes 40116
        // If I don't sync the entry and this method ends up doing an eviction
        // thus setting value to null
        // some other thread is free to fetch the value while the entry is synced
        // and think it has removed it or replaced it. This results in updateSizeOn*
        // being called twice for the same value (once when it is evicted and once
        // when it is removed/updated).
        try {
          dr.acquireReadLock();
          try {
            DiskId did = entry.getDiskId();
            synchronized (did) {
              if (did.isPendingAsync()) {
                did.setPendingAsync(false);
                final Token entryVal = entry.getValueAsToken();
                final int entryValSize = region.calculateRegionEntryValueSize(entry);
                try {
                  if (Token.isRemovedFromDisk(entryVal)) {
                    if (region.isThisRegionBeingClosedOrDestroyed()) {
                      return;
                    }
                    dr.remove(region, entry, true, false);
                    if (dr.isBackup()) {
                      did.setKeyId(DiskRegion.INVALID_ID); // fix for bug 41340
                    }
                  } else if ((Token.isInvalid(entryVal) || entryVal == Token.TOMBSTONE)
                      && !dr.isBackup()) {
                    // no need to write invalid or tombstones to disk if overflow only
                  } else if (entryVal != null) {
                    writeToDisk(entry, region, true);
                    assert !dr.isSync();
                    // Only setValue to null if this was an evict.
                    // We could just be a backup that is writing async.
                    if (!Token.isInvalid(entryVal) && (entryVal != Token.TOMBSTONE)
                        && entry instanceof EvictableEntry
                        && ((EvictableEntry) entry).isEvicted()) {
                      // Moved this here to fix bug 40116.
                      region.updateSizeOnEvict(entry.getKey(), entryValSize);
                      updateStats(dr, region, -1/* InVM */, 1/* OnDisk */, did.getValueLength());
                      entry.handleValueOverflow(region);
                      entry.setValueWithContext(region, null);
                    }
                  } else {
                    // if we have a version tag we need to record the operation
                    // to update the RVV
                    if (tag != null) {
                      DiskEntry.Helper.doAsyncFlush(tag, region);
                    }
                    return;
                  }
                } catch (RegionClearedException ignore) {
                  // no need to do the op since it was clobbered by a region clear
                }

                // See if we the entry we wrote to disk has the same tag
                // as this entry. If not, write the tag as a conflicting operation.
                // to update the RVV.
                VersionStamp stamp = entry.getVersionStamp();
                if (tag != null && stamp != null && (stamp.getMemberID() != tag.getMemberID()
                    || stamp.getRegionVersion() != tag.getRegionVersion())) {
                  DiskEntry.Helper.doAsyncFlush(tag, region);
                }
              } else {
                // if we have a version tag we need to record the operation
                // to update the RVV
                if (tag != null) {
                  DiskEntry.Helper.doAsyncFlush(tag, region);
                }
              }
            }
          } finally {
            dr.releaseReadLock();
          }
        } finally {
          if (!asyncQueueWasFull) {
            dr.removeClearCountReference();
          }
        }
      } // sync entry
    }
Does a synchronous write to disk for a region that uses async. This method is used by both
doAsyncFlush and handleFullAsyncQueue to fix GEODE-1700.

@param asyncQueueWasFull true if caller wanted to put this entry in the queue but could not
       do so because it was full
geode-core/src/main/java/org/apache/geode/internal/cache/entries/DiskEntry.java