public boolean waitUntilLocked(Object[] keys) {
    final boolean isDebugEnabled = logger.isDebugEnabled();

    final String title = "BucketRegion.waitUntilLocked:";
    while (true) {
      LockObject foundLock = searchAndLock(keys);

      if (foundLock != null) {
        synchronized (foundLock) {
          try {
            while (!foundLock.isRemoved()) {
              partitionedRegion.checkReadiness();
              foundLock.wait(1000);
              // primary could be changed by prRebalancing while waiting here
              checkForPrimary();
            }
          } catch (InterruptedException e) {
            // TODO this isn't a localizable string and it's being logged at info level
            if (isDebugEnabled) {
              logger.debug("{} interrupted while waiting for {}", title, foundLock);
            }
          }
          if (isDebugEnabled) {
            long waitTime = System.currentTimeMillis() - foundLock.lockedTimeStamp;
            logger.debug("{} waited {} ms to lock {}", title, waitTime, foundLock);
          }
        }
      } else {
        // now the keys have been locked by this thread
        return true;
      } // to lock and process
    } // while
  }
Keep checking if CM has contained any key in keys. If yes, wait for notify, then retry again.
This method will block current thread for long time. It only exits when current thread
successfully save its keys into CM.
geode-core/src/main/java/org/apache/geode/internal/cache/BucketRegion.java