protected boolean doRegionDestroy(CacheEvent event) throws EntryNotFoundException {
      appliedOperation = true;
      RegionEventImpl ev = (RegionEventImpl) event;
      final DistributedRegion rgn = (DistributedRegion) ev.region;

      if (getOperation().isLocal()) {
        Assert.assertTrue(serialNum != DistributionAdvisor.ILLEGAL_SERIAL);
        disableRegionDepartureNotification();
        try {
          rgn.handleRemoteLocalRegionDestroyOrClose(getSender(), serialNum, subregionSerialNumbers,
              !getOperation().isClose());
        } finally {
          enableRegionDepartureNotification();
        }
        return true;
      }

      try {
        String fullPath = null;
        if (logger.isDebugEnabled()) {
          fullPath = rgn.getFullPath();
          StringBuilder subregionNames = new StringBuilder();
          for (final Object o : rgn.debugGetSubregionNames()) {
            subregionNames.append(o);
            subregionNames.append(", ");
          }
          logger.debug(
              "Processing DestroyRegionOperation, about to destroy {}, has immediate subregions: {}",
              fullPath, subregionNames);
        }
        if (getOperation() == Operation.REGION_LOAD_SNAPSHOT) {
          if (logger.isDebugEnabled()) {
            logger.debug("Processing DestroyRegionOperation, calling reinitialize_destroy: {}",
                fullPath);
          }

          // do just the destroy here, then spawn a thread to do the
          // the re-create. This allows the ack to be send for the
          // destroy message before we re-create the region.
          // Don't release the destroy lock until after we re-create
          rgn.reinitialize_destroy(ev);

          final LocalRegion loc_lockRoot = lockRoot;
          lockRoot = null; // spawned thread will release lock, not
                           // basicProcess

          rgn.getDistributionManager().getExecutors().getWaitingThreadPool()
              .execute(() -> {
                try {
                  rgn.reinitializeFromImageTarget(getSender());
                } catch (TimeoutException e) {
                  // dlock timed out, log message
                  logger.warn(String.format(
                      "Got timeout when trying to recreate region during re-initialization: %s",
                      rgn.getFullPath()),
                      e);
                } catch (IOException e) {
                  // only if loading snapshot, not here
                  InternalGemFireError assErr = new InternalGemFireError(
                      "unexpected exception", e);
                  throw assErr;
                } catch (ClassNotFoundException e) {
                  // only if loading snapshot, not here
                  InternalGemFireError assErr = new InternalGemFireError(
                      "unexpected exception", e);
                  throw assErr;
                } finally {
                  if (loc_lockRoot != null) {
                    loc_lockRoot.releaseDestroyLock();
                  }
                }
              });
        } else {
          if (logger.isDebugEnabled()) {
            logger.debug("Processing DestroyRegionOperation, calling basicDestroyRegion: {}",
                fullPath);
          }
          rgn.basicDestroyRegion(ev, false /* cacheWrite */, false /* lock */,
              true/* cacheCallbacks */);
        }
      } catch (CacheWriterException ignore) {
        throw new Error(
            "CacheWriter should not have been called");
      } catch (TimeoutException ignore) {
        throw new Error(
            "DistributedLock should not have been acquired");
      } catch (RejectedExecutionException ignore) {
        // rejected while trying to execute recreate thread
        // must be shutting down, so what we were trying to do must not be
        // important anymore, so just quit
      }
      return true;
    }
Return true if a reply should be sent
geode-core/src/main/java/org/apache/geode/internal/cache/DestroyRegionOperation.java