public TDeleteTableDeviceResp deleteDevices(
      final TDeleteTableDeviceReq req, final boolean isGeneratedByPipe) {
    long procedureId;
    DeleteDevicesProcedure procedure = null;
    final TSStatus status;
    synchronized (this) {
      final Pair<Long, Boolean> procedureIdDuplicatePair =
          checkDuplicateTableTask(
              req.database,
              null,
              req.tableName,
              req.queryId,
              ProcedureType.DELETE_DEVICES_PROCEDURE);
      procedureId = procedureIdDuplicatePair.getLeft();

      if (procedureId == -1) {
        if (Boolean.TRUE.equals(procedureIdDuplicatePair.getRight())) {
          return new TDeleteTableDeviceResp(
              RpcUtils.getStatus(
                  TSStatusCode.OVERLAP_WITH_EXISTING_TASK,
                  "Some other task is operating table with same name."));
        }
        procedure =
            new DeleteDevicesProcedure(
                req.database,
                req.tableName,
                req.queryId,
                req.getPatternInfo(),
                req.getFilterInfo(),
                req.getModInfo(),
                isGeneratedByPipe);
        this.executor.submitProcedure(procedure);
        status = waitingProcedureFinished(procedure);
      } else {
        status = waitingProcedureFinished(procedureId);
      }
    }
    if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
      return new TDeleteTableDeviceResp(StatusUtils.OK)
          .setDeletedNum(
              Optional.ofNullable(procedure)
                  .map(DeleteDevicesProcedure::getDeletedDevicesNum)
                  .orElse(-1L));
    } else {
      return new TDeleteTableDeviceResp(status);
    }
  }
Waiting until the specific procedure finished.

@param procedure The specific procedure
@return TSStatus the running result of this procedure
iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java